mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add tests for CFI round-tripping
This commit is contained in:
parent
8648e3ff2f
commit
7c9cafc63f
@ -136,7 +136,9 @@ def encode(doc, node, offset, tail): # {{{
|
||||
# Handle the offset, if any
|
||||
if node.nodeType is Node.ELEMENT_NODE:
|
||||
if jstype(offset) is 'number':
|
||||
node = node.childNodes.item(offset)
|
||||
q = node.childNodes.item(offset)
|
||||
if q and q.nodeType is Node.ELEMENT_NODE:
|
||||
node = q
|
||||
elif Node.TEXT_NODE <= node.nodeType <= Node.ENTITY_NODE:
|
||||
offset = offset or 0
|
||||
while True:
|
||||
@ -212,7 +214,7 @@ def decode(cfi, doc): # {{{
|
||||
cfi = cfi.substr(r[0].length)
|
||||
break
|
||||
index |= 1 # Increment index by 1 if it is even
|
||||
if child.nodeType is 1:
|
||||
if child.nodeType is Node.ELEMENT_NODE:
|
||||
index += 1
|
||||
if index is target:
|
||||
cfi = cfi.substr(r[0].length)
|
||||
@ -276,8 +278,6 @@ def decode(cfi, doc): # {{{
|
||||
# TODO: Handle text assertion
|
||||
|
||||
# Find the text node that contains the offset
|
||||
if node and node.parentNode:
|
||||
node.parentNode.normalize()
|
||||
if offset is not None:
|
||||
while True:
|
||||
l = node.nodeValue.length
|
||||
|
@ -2,11 +2,46 @@
|
||||
# License: GPL v3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
from __python__ import bound_methods, hash_literals
|
||||
|
||||
from read_book.cfi import escape_for_cfi, unescape_from_cfi
|
||||
from testing import test, assert_equal
|
||||
from elementmaker import E
|
||||
|
||||
from read_book.cfi import encode, decode, escape_for_cfi, unescape_from_cfi
|
||||
from testing import assert_equal, test
|
||||
|
||||
|
||||
@test
|
||||
def cfi_escaping():
|
||||
t = 'a^!,1'
|
||||
assert_equal(t, unescape_from_cfi(escape_for_cfi(t)))
|
||||
|
||||
|
||||
@test
|
||||
def cfi_roundtripping():
|
||||
idc = 0
|
||||
def nid():
|
||||
nonlocal idc
|
||||
idc += 1
|
||||
return idc + ''
|
||||
|
||||
document.body.appendChild(E.p('abc'))
|
||||
p = document.body.firstChild
|
||||
path_to_p = '/2/4/2'
|
||||
assert_equal(encode(document, p), path_to_p)
|
||||
assert_equal(decode(path_to_p), {'node': p})
|
||||
|
||||
assert_equal(encode(document, p.firstChild), f'{path_to_p}/1:0')
|
||||
assert_equal(decode(f'{path_to_p}/1:0'), {'node': p.firstChild, 'offset': 0})
|
||||
|
||||
assert_equal(encode(document, p.firstChild, 1), f'{path_to_p}/1:1')
|
||||
assert_equal(decode(f'{path_to_p}/1:1'), {'node': p.firstChild, 'offset': 1})
|
||||
|
||||
p.appendChild(document.createTextNode('def'))
|
||||
assert_equal(encode(document, p.firstChild, 5), f'{path_to_p}/1:5')
|
||||
assert_equal(p.childNodes.length, 2)
|
||||
assert_equal(encode(document, p.lastChild, 1), f'{path_to_p}/1:4')
|
||||
assert_equal(decode(f'{path_to_p}/1:5'), {'node': p.lastChild, 'offset': 2})
|
||||
assert_equal(decode(f'{path_to_p}/1:1'), {'node': p.firstChild, 'offset': 1})
|
||||
|
||||
p.appendChild(E.span('123', id=nid()))
|
||||
p.appendChild(document.createTextNode('456'))
|
||||
assert_equal(encode(document, p.lastChild, 1), f'{path_to_p}/1:7')
|
||||
assert_equal(decode(f'{path_to_p}/1:7'), {'node': p.lastChild, 'offset': 1})
|
||||
|
@ -25,8 +25,8 @@ def get_traceback(lines):
|
||||
lines = traceback.format_exception()
|
||||
last_line = lines[-1]
|
||||
final_lines = v'[]'
|
||||
pat = /at assert_\w+ \(/
|
||||
for line in lines:
|
||||
pat = /at assert_[0-9a-zA-Z_]+ \(/
|
||||
for line in lines[:-1]:
|
||||
if pat.test(line):
|
||||
break
|
||||
final_lines.push(line)
|
||||
|
@ -14,10 +14,21 @@ def raise_fail(preamble, msg, call_site):
|
||||
raise AssertionError(preamble + msg)
|
||||
|
||||
|
||||
def repr_of(a):
|
||||
if not a:
|
||||
return a
|
||||
q = a.outerHTML
|
||||
if q:
|
||||
return q.split('>')[0] + '>'
|
||||
return a
|
||||
|
||||
|
||||
def assert_equal(a, b, msg, call_site=None):
|
||||
|
||||
def fail():
|
||||
p = f'{a} != {b}'
|
||||
ra = repr_of(a)
|
||||
rb = repr_of(b)
|
||||
p = f'{ra} != {rb}'
|
||||
raise_fail(p, msg, call_site)
|
||||
|
||||
atype = jstype(a)
|
||||
@ -31,10 +42,18 @@ def assert_equal(a, b, msg, call_site=None):
|
||||
if not a.__eq__(b):
|
||||
fail()
|
||||
return
|
||||
if a.isSameNode:
|
||||
if not a.isSameNode(b):
|
||||
fail()
|
||||
return
|
||||
if b.__eq__:
|
||||
if not b.__eq__(a):
|
||||
fail()
|
||||
return
|
||||
if b.isSameNode:
|
||||
if not b.isSameNode(a):
|
||||
fail()
|
||||
return
|
||||
if a.length? or b.length?:
|
||||
if a.length is not b.length:
|
||||
fail()
|
||||
@ -48,7 +67,7 @@ def assert_equal(a, b, msg, call_site=None):
|
||||
for key in Object.keys(b):
|
||||
assert_equal(a[key], b[key])
|
||||
|
||||
if a is not b:
|
||||
if atype is not 'object' and btype is not 'object':
|
||||
fail()
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user