mirror of
https://github.com/biojppm/rapidyaml.git
synced 2026-01-18 13:31:19 +01:00
550 lines
18 KiB
Python
550 lines
18 KiB
Python
import ryml
|
|
from ryml.ryml import _same_ptr, _same_mem
|
|
import unittest
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# -----------------------------------------------------------------------------
|
|
# -----------------------------------------------------------------------------
|
|
class TestSubstrInterop(unittest.TestCase):
|
|
|
|
# ------------------------------------------------
|
|
# str
|
|
|
|
# CAN create c4::csubstr from string object
|
|
def test11_str2csubstr(self):
|
|
s = "asdasd"
|
|
m = ryml.as_csubstr(s)
|
|
self.assertTrue(_same_ptr(s, m))
|
|
self.assertTrue(_same_mem(s, m))
|
|
self.assertEqual(s, ryml.u(m))
|
|
#
|
|
m = ryml.as_csubstr(m)
|
|
self.assertTrue(_same_ptr(s, m))
|
|
self.assertTrue(_same_mem(s, m))
|
|
self.assertEqual(s, ryml.u(m))
|
|
|
|
# CANNOT create c4::substr from string object
|
|
def test12_str2substr(self):
|
|
s = ""
|
|
with self.assertRaises(TypeError) as context:
|
|
_ = ryml.as_substr(s)
|
|
self.assertTrue(type(context.exception), TypeError)
|
|
|
|
# ------------------------------------------------
|
|
# bytes
|
|
|
|
# CAN create c4::csubstr from string object
|
|
def test21_bytes2csubstr(self):
|
|
s = b"foo21"
|
|
m = ryml.as_csubstr(s)
|
|
self.assertTrue(_same_ptr(s, m))
|
|
self.assertTrue(_same_mem(s, m))
|
|
self.assertEqual(s, m)
|
|
#
|
|
m = ryml.as_csubstr(m)
|
|
self.assertTrue(_same_ptr(s, m))
|
|
self.assertTrue(_same_mem(s, m))
|
|
self.assertEqual(s, m)
|
|
|
|
# CANNOT create c4::csubstr from string object
|
|
def test22_bytes2substr(self):
|
|
s = b"foo22"
|
|
with self.assertRaises(TypeError) as context:
|
|
_ = ryml.as_substr(s)
|
|
self.assertTrue(type(context.exception), TypeError)
|
|
|
|
# ------------------------------------------------
|
|
# bytearray
|
|
|
|
# CAN create c4::csubstr from string object
|
|
def test31_bytes2csubstr(self):
|
|
s = bytearray("foo31", "utf8")
|
|
m = ryml.as_csubstr(s)
|
|
self.assertTrue(_same_ptr(s, m))
|
|
self.assertTrue(_same_mem(s, m))
|
|
self.assertEqual(s, m)
|
|
#
|
|
m = ryml.as_csubstr(m)
|
|
self.assertTrue(_same_ptr(s, m))
|
|
self.assertTrue(_same_mem(s, m))
|
|
self.assertEqual(s, m)
|
|
|
|
# CANNOT create c4::csubstr from string object
|
|
def test32_bytes2substr(self):
|
|
s = bytearray("foo31", "utf8")
|
|
m = ryml.as_csubstr(s)
|
|
self.assertTrue(_same_ptr(s, m))
|
|
self.assertTrue(_same_mem(s, m))
|
|
self.assertEqual(s, m)
|
|
#
|
|
m = ryml.as_csubstr(m)
|
|
self.assertTrue(_same_ptr(s, m))
|
|
self.assertTrue(_same_mem(s, m))
|
|
self.assertEqual(s, m)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# -----------------------------------------------------------------------------
|
|
# -----------------------------------------------------------------------------
|
|
|
|
def _addmap(t, node, k=None):
|
|
m = t.append_child(node)
|
|
if k is None:
|
|
t.to_map(m)
|
|
else:
|
|
t.to_map(m, k)
|
|
return m
|
|
|
|
|
|
def _addseq(t, node, k=None):
|
|
m = t.append_child(node)
|
|
if k is None:
|
|
t.to_seq(m)
|
|
else:
|
|
t.to_seq(m, k)
|
|
return m
|
|
|
|
|
|
def _addleaf(t, node, k, v=None):
|
|
ch = t.append_child(node)
|
|
if v is None:
|
|
t.to_val(ch, k)
|
|
else:
|
|
t.to_keyval(ch, k, v)
|
|
return ch
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# -----------------------------------------------------------------------------
|
|
# -----------------------------------------------------------------------------
|
|
def check_tree_mod(ut, t):
|
|
# some convenient shorthands
|
|
eq = ut.assertEqual
|
|
def _leaf(node, k, v=None):
|
|
ch = _addleaf(t, node, k, v)
|
|
pos = t.child_pos(node, ch)
|
|
eq(t.child(node, pos), ch)
|
|
if v is not None:
|
|
eq(t.find_child(node, k), ch)
|
|
eq(t.child(node, pos), t.find_child(node, k))
|
|
return ch
|
|
def _seq(node, k):
|
|
ch = _addseq(t, node, k)
|
|
eq(t.find_child(node, k), ch)
|
|
return ch
|
|
def _map(node, k):
|
|
ch = _addmap(t, node, k)
|
|
eq(t.find_child(node, k), ch)
|
|
return ch
|
|
m = _map(t.root_id(), "check_tree_mod_map")
|
|
_leaf(m, "k1", "v1")
|
|
_leaf(m, "k2", "v2")
|
|
_leaf(m, "k3", "v3")
|
|
eq(t.num_children(m), 3)
|
|
eq(t.num_siblings(t.first_child(m)), 3)
|
|
s = _seq(t.root_id(), "check_tree_mod_seq")
|
|
_leaf(s, "v1")
|
|
_leaf(s, "v2")
|
|
_leaf(s, "v3")
|
|
eq(t.num_children(s), 3)
|
|
eq(t.num_siblings(t.first_child(m)), 3)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# -----------------------------------------------------------------------------
|
|
# -----------------------------------------------------------------------------
|
|
class SimpleHardcoded:
|
|
|
|
yaml = "{'HELLO': a, foo: \"b\", bar: c, baz: d, seq: [0, 1, 2, 3]}"
|
|
|
|
def check(self, ut, t, is_json=False):
|
|
# some convenient shorthands
|
|
eq = ut.assertEqual
|
|
ne = ut.assertNotEqual
|
|
fs = ut.assertFalse
|
|
tr = ut.assertTrue
|
|
#
|
|
eq(t.size(), 10)
|
|
tr(t.is_root(0))
|
|
eq(t.num_children(0), 5)
|
|
eq(t.find_child(0, b"HELLO"), 1)
|
|
eq(t.find_child(0, b"foo"), 2)
|
|
eq(t.find_child(0, b"bar"), 3)
|
|
eq(t.find_child(0, b"baz"), 4)
|
|
eq(t.find_child(0, b"seq"), 5)
|
|
eq(t.parent(0), ryml.NONE)
|
|
eq(t.parent(1), 0)
|
|
eq(t.parent(2), 0)
|
|
eq(t.parent(3), 0)
|
|
eq(t.parent(4), 0)
|
|
eq(t.parent(5), 0)
|
|
fs(t.is_root(1))
|
|
fs(t.is_root(2))
|
|
fs(t.is_root(3))
|
|
fs(t.is_root(4))
|
|
fs(t.is_root(5))
|
|
fs(t.has_child(0, b"foozzie"))
|
|
fs(t.has_child(0, b"bark"))
|
|
fs(t.has_child(0, b"bart"))
|
|
fs(t.has_child(0, b"bazk"))
|
|
eq(t.next_sibling(0), ryml.NONE)
|
|
eq(t.prev_sibling(0), ryml.NONE)
|
|
eq(t.prev_sibling(1), ryml.NONE)
|
|
eq(t.next_sibling(5), ryml.NONE)
|
|
tr(t.has_child(0, b"HELLO"))
|
|
tr(t.has_child(0, b"foo"))
|
|
tr(t.has_child(0, b"bar"))
|
|
tr(t.has_child(0, b"baz"))
|
|
eq(t.key(1), b"HELLO")
|
|
eq(t.key(2), b"foo")
|
|
eq(t.key(3), b"bar")
|
|
eq(t.key(4), b"baz")
|
|
eq(t.key(5), b"seq")
|
|
eq(t.val(1), b"a")
|
|
eq(t.val(2), b"b")
|
|
eq(t.val(3), b"c")
|
|
eq(t.val(4), b"d")
|
|
eq(t.val(6), b"0")
|
|
eq(t.val(7), b"1")
|
|
eq(t.val(8), b"2")
|
|
eq(t.val(9), b"3")
|
|
if not is_json:
|
|
tr(t.is_key_quoted(1))
|
|
fs(t.is_key_quoted(2))
|
|
fs(t.is_key_quoted(3))
|
|
fs(t.is_key_quoted(4))
|
|
fs(t.is_key_quoted(5))
|
|
else:
|
|
tr(t.is_key_quoted(1))
|
|
tr(t.is_key_quoted(2))
|
|
tr(t.is_key_quoted(3))
|
|
tr(t.is_key_quoted(4))
|
|
tr(t.is_key_quoted(5))
|
|
if not is_json:
|
|
fs(t.is_val_quoted(1))
|
|
tr(t.is_val_quoted(2))
|
|
fs(t.is_val_quoted(3))
|
|
fs(t.is_val_quoted(4))
|
|
fs(t.is_val_quoted(5))
|
|
fs(t.is_val_quoted(6))
|
|
fs(t.is_val_quoted(7))
|
|
fs(t.is_val_quoted(8))
|
|
fs(t.is_val_quoted(9))
|
|
else:
|
|
tr(t.is_val_quoted(1))
|
|
tr(t.is_val_quoted(2))
|
|
tr(t.is_val_quoted(3))
|
|
tr(t.is_val_quoted(4))
|
|
fs(t.is_val_quoted(5))
|
|
fs(t.is_val_quoted(6))
|
|
fs(t.is_val_quoted(7))
|
|
fs(t.is_val_quoted(8))
|
|
fs(t.is_val_quoted(9))
|
|
if not is_json:
|
|
tr(t.is_quoted(1))
|
|
tr(t.is_quoted(2))
|
|
fs(t.is_quoted(3))
|
|
fs(t.is_quoted(4))
|
|
fs(t.is_quoted(5))
|
|
fs(t.is_quoted(6))
|
|
fs(t.is_quoted(7))
|
|
fs(t.is_quoted(8))
|
|
fs(t.is_quoted(9))
|
|
else:
|
|
tr(t.is_quoted(1))
|
|
tr(t.is_quoted(2))
|
|
tr(t.is_quoted(3))
|
|
tr(t.is_quoted(4))
|
|
tr(t.is_quoted(5))
|
|
fs(t.is_quoted(6))
|
|
fs(t.is_quoted(7))
|
|
fs(t.is_quoted(8))
|
|
fs(t.is_quoted(9))
|
|
tr(t.has_sibling(1, b"bar"))
|
|
tr(t.has_sibling(1, b"baz"))
|
|
tr(t.has_sibling(2, b"foo"))
|
|
tr(t.has_sibling(2, b"baz"))
|
|
tr(t.has_sibling(3, b"foo"))
|
|
tr(t.has_sibling(3, b"bar"))
|
|
for i in (1, 2, 3, 4, 5):
|
|
eq(t.find_sibling(i, b"HELLO"), 1)
|
|
eq(t.find_sibling(i, b"foo"), 2)
|
|
eq(t.find_sibling(i, b"bar"), 3)
|
|
eq(t.find_sibling(i, b"baz"), 4)
|
|
eq(t.find_sibling(i, b"seq"), 5)
|
|
#
|
|
num = 0
|
|
for id in ryml.children(t):
|
|
num += 1
|
|
eq(id, num)
|
|
eq(num, t.num_children(t.root_id()))
|
|
eq(num, t.num_siblings(t.first_child(t.root_id())))
|
|
#
|
|
num = 0
|
|
for id in ryml.children(t, 1):
|
|
num += 1
|
|
eq(num, 0)
|
|
#
|
|
num = 0
|
|
for id in ryml.siblings(t, 1):
|
|
num += 1
|
|
eq(id, num)
|
|
eq(num, t.num_children(t.root_id()))
|
|
eq(num, t.num_siblings(t.first_child(t.root_id())))
|
|
#
|
|
num = 0
|
|
for id in ryml.siblings(t, 3):
|
|
num += 1
|
|
eq(id, num)
|
|
eq(num, 5)
|
|
eq(num, t.num_siblings(t.first_child(t.root_id())))
|
|
#
|
|
for i, ch in enumerate(ryml.children(t, 5)):
|
|
eq(t.val(ch), [b"0", b"1", b"2", b"3"][i])
|
|
sibs = [b"HELLO", b"foo", b"bar", b"baz", b"seq"]
|
|
sibs_s = ["HELLO", "foo", "bar", "baz", "seq"]
|
|
for i, sib in enumerate(ryml.siblings(t, 5)):
|
|
k = t.key(sib)
|
|
k_s = str(k, "utf8")
|
|
eq(k, sibs[i])
|
|
eq(k_s, sibs_s[i])
|
|
ne(k, sibs_s[i])
|
|
ne(k_s, sibs[i])
|
|
k_s = str(k)
|
|
ne(k_s, sibs_s[i])
|
|
ne(k_s, sibs[i])
|
|
num = 0
|
|
for id in ryml.siblings(t, 0):
|
|
num += 1
|
|
eq(num, 1)
|
|
#
|
|
num = 0
|
|
for id, level in ryml.walk(t):
|
|
num += 1
|
|
if t.is_root(id):
|
|
eq(id, 0)
|
|
eq(level, 0)
|
|
if t.is_map(id):
|
|
eq(id, 0)
|
|
eq(level, 0)
|
|
if t.is_seq(id):
|
|
eq(id, 5)
|
|
eq(level, 1)
|
|
if t.is_keyval(id):
|
|
tr(id > 0 and id < 5)
|
|
if t.is_val(id):
|
|
tr(id > 5)
|
|
eq(level, 2)
|
|
eq(num, t.size())
|
|
#
|
|
num = 0
|
|
for id in ryml.walk(t, 5):
|
|
num += 1
|
|
eq(num, 5)
|
|
#
|
|
num = 0
|
|
for id in ryml.walk(t, 9):
|
|
num += 1
|
|
eq(num, 1)
|
|
check_tree_mod(ut, t)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# -----------------------------------------------------------------------------
|
|
# -----------------------------------------------------------------------------
|
|
class _TestBase(unittest.TestCase):
|
|
|
|
def _setUp(self, case=None):
|
|
self.case = case
|
|
self.src_as_str = str(case.yaml)
|
|
self.src_as_bytes = bytes(case.yaml, "utf8")
|
|
self.src_as_bytearray = bytearray(case.yaml, "utf8")
|
|
|
|
# ----------------------------------------------------------
|
|
def _test11_str__ro(self): # cannot read string buffers (or can we?)
|
|
tree = ryml.parse_in_arena(self.src_as_str)
|
|
self.case.check(self, tree)
|
|
|
|
def _test12_str__ro__reuse_tree(self): # cannot read string buffers (or can we?)
|
|
t = ryml.Tree()
|
|
ryml.parse_in_arena(self.src_as_str, tree=t)
|
|
self.case.check(self, t)
|
|
|
|
def _test13_str__rw(self): # cannot mutate string buffers (or can we?)
|
|
with self.assertRaises(TypeError) as context:
|
|
ryml.parse_in_place(self.src_as_str)
|
|
self.assertTrue(type(context.exception), TypeError)
|
|
|
|
# ----------------------------------------------------------
|
|
def _test21_bytes__ro(self):
|
|
tree = ryml.parse_in_arena(self.src_as_bytes)
|
|
self.case.check(self, tree)
|
|
|
|
def _test22_bytes__ro__reuse_tree(self):
|
|
t = ryml.Tree()
|
|
r = ryml.parse_in_arena(self.src_as_bytes, tree=t)
|
|
self.assertTrue(r is t)
|
|
self.case.check(self, t)
|
|
|
|
def _test23_bytes__rw(self): # cannot mutate bytes buffers
|
|
with self.assertRaises(TypeError) as context:
|
|
ryml.parse_in_place(self.src_as_bytes)
|
|
self.assertTrue(type(context.exception), TypeError)
|
|
|
|
# ----------------------------------------------------------
|
|
def _test31_bytearray__ro(self):
|
|
tree = ryml.parse_in_arena(self.src_as_bytearray)
|
|
self.case.check(self, tree)
|
|
|
|
def _test32_bytearray__ro__reuse_tree(self):
|
|
t = ryml.Tree()
|
|
r = ryml.parse_in_arena(self.src_as_bytearray, tree=t)
|
|
self.assertTrue(r is t)
|
|
self.case.check(self, t)
|
|
|
|
def _test33_bytearray__rw(self): # bytearray buffers are mutable
|
|
tree = ryml.parse_in_place(self.src_as_bytearray)
|
|
self.case.check(self, tree)
|
|
|
|
def _test34_bytearray__rw__reuse_tree(self): # bytearray buffers are mutable
|
|
t = ryml.Tree()
|
|
r = ryml.parse_in_place(self.src_as_bytearray, tree=t)
|
|
self.assertTrue(r is t)
|
|
self.case.check(self, t)
|
|
|
|
# ----------------------------------------------------------
|
|
def _test41_emit_yaml(self):
|
|
tree = ryml.parse_in_arena(self.src_as_bytearray)
|
|
yaml = ryml.emit_yaml(tree)
|
|
output_tree = ryml.parse_in_arena(yaml)
|
|
self.case.check(self, output_tree)
|
|
|
|
def _test41_emit_json(self):
|
|
tree = ryml.parse_in_arena(self.src_as_bytearray)
|
|
json = ryml.emit_json(tree)
|
|
output_tree = ryml.parse_in_arena(json)
|
|
self.case.check(self, output_tree, is_json=True)
|
|
|
|
def _test42_compute_emit_yaml_length(self):
|
|
tree = ryml.parse_in_arena(self.src_as_bytearray)
|
|
yaml = ryml.emit_yaml(tree)
|
|
length = ryml.compute_emit_yaml_length(tree)
|
|
self.assertEqual(len(yaml), length)
|
|
|
|
def _test42_compute_emit_json_length(self):
|
|
tree = ryml.parse_in_arena(self.src_as_bytearray)
|
|
json = ryml.emit_json(tree)
|
|
length = ryml.compute_emit_json_length(tree)
|
|
self.assertEqual(len(json), length)
|
|
|
|
def _test43_emit_yaml_in_place(self):
|
|
tree = ryml.parse_in_arena(self.src_as_bytearray)
|
|
yaml = ryml.emit_yaml(tree)
|
|
length = ryml.compute_emit_yaml_length(tree)
|
|
self.assertEqual(len(yaml), length)
|
|
buf = bytearray(length)
|
|
s = ryml.emit_yaml_in_place(tree, buf)
|
|
self.assertEqual(len(s), length)
|
|
self.assertTrue(s.tobytes().decode('utf-8') == yaml)
|
|
self.assertTrue(buf.decode('utf-8') == yaml)
|
|
|
|
def _test43_emit_json_in_place(self):
|
|
tree = ryml.parse_in_arena(self.src_as_bytearray)
|
|
json = ryml.emit_json(tree)
|
|
length = ryml.compute_emit_json_length(tree)
|
|
self.assertEqual(len(json), length)
|
|
buf = bytearray(length)
|
|
s = ryml.emit_json_in_place(tree, buf)
|
|
self.assertEqual(len(s), length)
|
|
self.assertTrue(s.tobytes().decode('utf-8') == json)
|
|
self.assertTrue(buf.decode('utf-8') == json)
|
|
|
|
def _test44_emit_yaml_short_buf(self):
|
|
tree = ryml.parse_in_arena(self.src_as_bytearray)
|
|
length = ryml.compute_emit_yaml_length(tree)
|
|
buf = bytearray(length-1)
|
|
with self.assertRaises(IndexError):
|
|
ryml.emit_yaml_in_place(tree, buf)
|
|
|
|
def _test44_emit_json_short_buf(self):
|
|
tree = ryml.parse_in_arena(self.src_as_bytearray)
|
|
length = ryml.compute_emit_json_length(tree)
|
|
buf = bytearray(length-1)
|
|
with self.assertRaises(IndexError):
|
|
ryml.emit_json_in_place(tree, buf)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# -----------------------------------------------------------------------------
|
|
# -----------------------------------------------------------------------------
|
|
class TestSimpleHardCoded(_TestBase):
|
|
|
|
def setUp(self):
|
|
_TestBase._setUp(self, SimpleHardcoded())
|
|
|
|
# ----------------------------------------------------------
|
|
def test11_str__ro(self):
|
|
super()._test11_str__ro()
|
|
|
|
def test12_str__ro__reuse_tree(self):
|
|
self._test12_str__ro__reuse_tree()
|
|
|
|
def test13_str__rw(self):
|
|
self._test13_str__rw()
|
|
|
|
# ----------------------------------------------------------
|
|
def test21_bytes__ro(self):
|
|
self._test21_bytes__ro()
|
|
|
|
def test22_bytes__ro__reuse_tree(self):
|
|
self._test22_bytes__ro__reuse_tree()
|
|
|
|
def test23_bytes__rw(self):
|
|
self._test23_bytes__rw()
|
|
|
|
# ----------------------------------------------------------
|
|
def test31_bytearray__ro(self):
|
|
self._test31_bytearray__ro()
|
|
|
|
def test32_bytearray__ro__reuse_tree(self):
|
|
self._test32_bytearray__ro__reuse_tree()
|
|
|
|
def test33_bytearray__rw(self):
|
|
self._test33_bytearray__rw()
|
|
|
|
def test34_bytearray__rw__reuse_tree(self):
|
|
self._test34_bytearray__rw__reuse_tree()
|
|
|
|
# ----------------------------------------------------------
|
|
def test41_emit_yaml(self):
|
|
self._test41_emit_yaml()
|
|
|
|
def test41_emit_json(self):
|
|
self._test41_emit_json()
|
|
|
|
def test42_compute_emit_yaml_length(self):
|
|
self._test42_compute_emit_yaml_length()
|
|
|
|
def test42_compute_emit_json_length(self):
|
|
self._test42_compute_emit_json_length()
|
|
|
|
def test43_emit_yaml_in_place(self):
|
|
self._test43_emit_yaml_in_place()
|
|
|
|
def test43_emit_json_in_place(self):
|
|
self._test43_emit_json_in_place()
|
|
|
|
def test44_emit_yaml_short_buf(self):
|
|
self._test44_emit_yaml_short_buf()
|
|
|
|
def test44_emit_json_short_buf(self):
|
|
self._test44_emit_json_short_buf()
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# -----------------------------------------------------------------------------
|
|
# -----------------------------------------------------------------------------
|
|
if __name__ == "__main__":
|
|
unittest.main()
|