From 3ac917c70697af1c44388880fdb81edce4b86455 Mon Sep 17 00:00:00 2001
From: John Factotum <50942278+johnfactotum@users.noreply.github.com>
Date: Wed, 19 Oct 2022 17:03:49 +0000
Subject: [PATCH] Add tests for EPUB CFI
---
README.md | 1 -
epubcfi.js | 3 +-
tests/epubcfi-tests.js | 202 +++++++++++++++++++++++++++++++++++++++++
tests/tests.html | 5 +
tests/tests.js | 1 +
5 files changed, 209 insertions(+), 3 deletions(-)
create mode 100644 tests/epubcfi-tests.js
create mode 100644 tests/tests.html
create mode 100644 tests/tests.js
diff --git a/README.md b/README.md
index 22bedce..ff3c376 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,6 @@ Features:
- Does not depend on or include any library for unzipping; bring your own Zip library
- Does not require loading whole file into memory
- Does not care about older browsers
-- No tests :(
- No continuous scrolling mode :(
## Demo
diff --git a/epubcfi.js b/epubcfi.js
index dac0771..ed45d4e 100644
--- a/epubcfi.js
+++ b/epubcfi.js
@@ -244,9 +244,8 @@ const partsToNode = (node, parts) => {
let sum = 0
for (const n of node) {
const { length } = n.nodeValue
- if (sum + length > offset) return { node: n, offset: offset - sum }
+ if (sum + length >= offset) return { node: n, offset: offset - sum }
sum += length
- if (n === node[node.length - 1]) return { node: n, offset: length - 1 }
}
}
diff --git a/tests/epubcfi-tests.js b/tests/epubcfi-tests.js
new file mode 100644
index 0000000..ec91e4b
--- /dev/null
+++ b/tests/epubcfi-tests.js
@@ -0,0 +1,202 @@
+import * as CFI from '../epubcfi.js'
+
+const parser = new DOMParser()
+const XML = str => parser.parseFromString(str, 'application/xml')
+const XHTML = str => parser.parseFromString(str, 'application/xhtml+xml')
+
+{
+ // example from EPUB CFI spec
+ const opf = XML(`
+
+
…
+…
+…
+…
+xxxyyy0123456789
+…
+…
+…
+…
+ +`) + + // the exact same page with some text nodes removed, CDATA sections added, + // and characters changed to entities + const page2 = XHTML(` + +…
…
…
…
+xxxyyy4589
+…
+…
+…
+…
+ +`) + + const a = opf.getElementById('chap01ref') + const b = CFI.toElement(opf, CFI.parse('/6/4[chap01ref]')[0]) + const c = CFI.toElement(opf, CFI.parse('/6/4')[0]) + console.assert(a === b) + console.assert(a === c) + + const test = page => { + for (const cfi of [ + '/4[body01]/10[para05]/3:10', + '/4[body01]/16[svgimg]', + '/4[body01]/10[para05]/1:0', + '/4[body01]/10[para05]/2/1:0', + '/4[body01]/10[para05]/2/1:3', + ]) { + const range = CFI.toRange(page, CFI.parse(cfi)) + const a = CFI.fromRange(range) + const b = `epubcfi(${cfi})` + console.assert(a === b, `expected ${b}, got ${a}`) + } + for (let i = 0; i < 10; i++) { + const cfi = `/4/10,/3:${i},/3:${i+1}` + const range = CFI.toRange(page, CFI.parse(cfi)) + const n = `${i}` + console.assert(range.toString() === n, `expted ${n}, got ${range}`) + } + } + test(page) + test(page2) +} + +{ + // special characters in ID assertions + const opf = XML(` +…
+…
+…
+…
+xxxyyy0123456789
+…
+…
+…
+…
+ +`) + + for (const cfi of [ + '/4[body0^]!/1^^]/10[para^]/0^,/5]/3:10', + '/4[body0^]!/1^^]/16[s^]^[vgimg]', + '/4[body0^]!/1^^]/10[para^]/0^,/5]/1:0', + '/4[body0^]!/1^^]/10[para^]/0^,/5]/2/1:0', + '/4[body0^]!/1^^]/10[para^]/0^,/5]/2/1:3', + ]) { + const range = CFI.toRange(page, CFI.parse(cfi)) + const a = CFI.fromRange(range) + const b = `epubcfi(${cfi})` + console.assert(a === b, `expected ${b}, got ${a}`) + } + for (let i = 0; i < 10; i++) { + const cfi = `/4[body0^]!/1^^]/10[para^]/0^,^/5],/3:${i},/3:${i+1}` + const range = CFI.toRange(page, CFI.parse(cfi)) + const n = `${i}` + console.assert(range.toString() === n, `expted ${n}, got ${range}`) + } +} + +{ + for (const [a, b, c] of [ + ['/6/4!/10', '/6/4!/10', 0], + ['/6/4!/2/3:0', '/6/4!/2', 1], + ['/6/4!/2/4/6/8/10/3:0', '/6/4!/4', -1], + [ + '/6/4[chap0^]!/1ref^^]!/4[body01^^]/10[para^]^,05^^]', + '/6/4!/4/10', + 0, + ], + [ + '/6/4[chap0^]!/1ref^^]!/4[body01^^],/10[para^]^,05^^],/15:10[foo^]]', + '/6/4!/4/12', + -1, + ], + ]) { + const x = CFI.compare(a, b) + console.assert(x === c, `compare ${a} and ${b}, expected ${c}, got ${x}`) + } +} diff --git a/tests/tests.html b/tests/tests.html new file mode 100644 index 0000000..2652dab --- /dev/null +++ b/tests/tests.html @@ -0,0 +1,5 @@ + + + + + diff --git a/tests/tests.js b/tests/tests.js new file mode 100644 index 0000000..c0227f1 --- /dev/null +++ b/tests/tests.js @@ -0,0 +1 @@ +import './epubcfi-tests.js'