Skip to content

Commit

Permalink
Add tests for all exported modules
Browse files Browse the repository at this point in the history
  • Loading branch information
lionel-rowe committed Sep 18, 2024
1 parent 87cefe1 commit 42b47c1
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Diff-Match-Patch Unicode [![JSR](https://jsr.io/badges/@clearlylocal/diff-match-patch-unicode)](https://jsr.io/@clearlylocal/diff-match-patch-unicode)

Modern JS/TS and Unicode-friendly version of [Neil Fraser](https://github.com/NeilFraser)’s [`diff-match-patch`](https://github.com/google/diff-match-patch).
Modern JS/TS and Unicode-friendly version of [Neil Fraser](https://github.com/NeilFraser)’s [`diff-match-patch`](https://github.com/google/diff-match-patch). Currently only supports diffing; matching and patching may be added in the future, depending on need.

## Usage

Expand Down
55 changes: 55 additions & 0 deletions src/Diff.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { assert, assertEquals } from '@std/assert'
import { Diff, DiffOperation } from './Diff.ts'

Deno.test(Diff.name, async (t) => {
await t.step('TypeScript validates inputs', () => {
;(() => {
new Diff(0, 'a')
new Diff(1, 'a')
new Diff(-1, 'a')

// @ts-expect-error wrong order
new Diff('a', 1)
// @ts-expect-error 2 is not a valid op
new Diff(2, 'a')
// @ts-expect-error -2 is not a valid op
new Diff(-2, 'a')
})()
})

await t.step('diff.op', () => {
assertEquals(new Diff(DiffOperation.Delete, 'a').op, -1)
assertEquals(new Diff(DiffOperation.Equal, 'a').op, 0)
assertEquals(new Diff(DiffOperation.Insert, 'a').op, 1)
})

await t.step('other getters', () => {
const diff = new Diff(DiffOperation.Equal, 'a')
assertEquals(diff.text, 'a')
assertEquals(diff.length, 2)
})

await t.step('JSON.stringify', () => {
const diff = new Diff(DiffOperation.Equal, 'a')
assertEquals(JSON.stringify(diff), '[0,"a"]')
})

await t.step('iterate', () => {
const diff = new Diff(DiffOperation.Equal, 'a')
assertEquals([...diff], [0, 'a'])
})

await t.step('inspect', () => {
const diff = new Diff(DiffOperation.Equal, 'a')
assertEquals(Deno.inspect(diff, { colors: false }), 'Diff #[ 0, "a" ]')
assertEquals(Deno.inspect(diff, { colors: true }), 'Diff #[ \x1b[33m0\x1b[39m, \x1b[32m"a"\x1b[39m ]')
})

await t.step('clone', () => {
const diff = new Diff(DiffOperation.Equal, 'a')
// value-equal
assertEquals(diff, diff.clone())
// not reference-equal
assert(diff !== diff.clone())
})
})
10 changes: 5 additions & 5 deletions src/Differ.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,14 @@ export class Differ {
* ```
*/
diff(before: string, after: string, options?: Partial<DiffOptions>): Diff[] {
if (before === after) {
// no need to go any further if both strings are the same
return before ? [new Diff(DiffOperation.Equal, before)] : []
}

const opts = { ...defaultDiffOptions, ...options, maxBefore: MAX_SEGMENTS_2_3, maxAfter: MAX_SEGMENTS }
const { join } = opts

if (before === after && join) {
// no need to go any further if both strings are the same (unless `join` is false)
return before ? [new Diff(DiffOperation.Equal, before)] : []
}

const { encodedDiffs, decode } = this.#diffInternal(before, after, opts)

if (!join) {
Expand Down
4 changes: 2 additions & 2 deletions src/_DiffMatchPatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export class DiffMatchPatch {
if (this.Diff_Timeout <= 0) {
opt_deadline = Number.MAX_VALUE
} else {
opt_deadline = (new Date()).getTime() + this.Diff_Timeout * 1000
opt_deadline = Date.now() + this.Diff_Timeout * 1000
}
}
const deadline = opt_deadline
Expand Down Expand Up @@ -279,7 +279,7 @@ export class DiffMatchPatch {
let k2end = 0
for (let d = 0; d < max_d; d++) {
// Bail out if deadline is reached.
if ((new Date()).getTime() > deadline) {
if (Date.now() > deadline) {
break
}

Expand Down
27 changes: 27 additions & 0 deletions src/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { assert, assertInstanceOf, assertThrows } from '@std/assert'
import { makeDiff } from './utils.ts'
import { Diff } from './Diff.ts'

Deno.test(makeDiff.name, async (t) => {
await t.step('instanceof', () => {
assertInstanceOf(makeDiff([0, 'a']), Diff)
})

await t.step('returns `Diff` input unchanged', () => {
const diff = makeDiff([0, 'a'])
// reference-equal
assert(diff === diff)
})

await t.step('validates inputs at runtime', () => {
makeDiff([0, 'a'])
makeDiff([1, 'a'])
makeDiff([-1, 'a'])

assertThrows(() => makeDiff([1, 1]), Error, 'Invalid text')
assertThrows(() => makeDiff(['a', '1']), Error, 'Invalid op')
assertThrows(() => makeDiff(['a', 1]), Error, 'Invalid text')
assertThrows(() => makeDiff([2, 'a']), Error, 'Invalid op')
assertThrows(() => makeDiff([-2, 'a']), Error, 'Invalid op')
})
})
6 changes: 3 additions & 3 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Diff, DiffOperation } from './Diff.ts'
import { Diff } from './Diff.ts'
import { assert } from '@std/assert/assert'

/**
Expand All @@ -19,7 +19,7 @@ export function makeDiffs(arr: readonly DiffLike[]): Diff[] {
export function makeDiff(d: DiffLike): Diff {
if (d instanceof Diff) return d
const [op, text] = d
assert(typeof text === 'string')
assert(op === DiffOperation.Delete || op === DiffOperation.Insert || op === DiffOperation.Equal)
assert(typeof text === 'string', `Invalid text: type is ${typeof text}; expected string`)
assert(op === -1 || op === 0 || op === 1, `Invalid op: ${op}; expected -1, 0, or 1`)
return new Diff(op, text)
}

0 comments on commit 42b47c1

Please sign in to comment.