You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gristlabs_grist-core/sandbox/grist/test_gpath.py

160 lines
6.5 KiB

import unittest
import gpath
class TestGpath(unittest.TestCase):
def setUp(self):
self.obj = {
"foo": [{"bar": 1}, {"bar": 2}, {"baz": 3}],
"hello": "world"
}
def test_get(self):
self.assertEqual(gpath.get(self.obj, ["foo", 0, "bar"]), 1)
self.assertEqual(gpath.get(self.obj, ["foo", 2]), {"baz": 3})
self.assertEqual(gpath.get(self.obj, ["hello"]), "world")
self.assertEqual(gpath.get(self.obj, []), self.obj)
self.assertEqual(gpath.get(self.obj, ["foo", 0, "baz"]), None)
self.assertEqual(gpath.get(self.obj, ["foo", 4]), None)
self.assertEqual(gpath.get(self.obj, ["foo", 4, "baz"]), None)
self.assertEqual(gpath.get(self.obj, [0]), None)
def test_set(self):
gpath.place(self.obj, ["foo"], {"bar": 1, "baz": 2})
self.assertEqual(self.obj["foo"], {"bar": 1, "baz": 2})
gpath.place(self.obj, ["foo", "bar"], 17)
self.assertEqual(self.obj["foo"], {"bar": 17, "baz": 2})
gpath.place(self.obj, ["foo", "baz"], None)
self.assertEqual(self.obj["foo"], {"bar": 17})
self.assertEqual(self.obj["hello"], "world")
gpath.place(self.obj, ["hello"], None)
self.assertFalse("hello" in self.obj)
gpath.place(self.obj, ["hello"], None) # OK to remove a non-existent property.
self.assertFalse("hello" in self.obj)
gpath.place(self.obj, ["hello"], "blah")
self.assertEqual(self.obj["hello"], "blah")
def test_set_strict(self):
with self.assertRaisesRegex(Exception, r"non-existent"):
gpath.place(self.obj, ["bar", 4], 17)
with self.assertRaisesRegex(Exception, r"not a plain object"):
gpath.place(self.obj, ["foo", 0], 17)
def test_insert(self):
self.assertEqual(self.obj["foo"], [{"bar": 1}, {"bar": 2}, {"baz": 3}])
gpath.insert(self.obj, ["foo", 0], "asdf")
self.assertEqual(self.obj["foo"], ["asdf", {"bar": 1}, {"bar": 2}, {"baz": 3}])
gpath.insert(self.obj, ["foo", 3], "hello")
self.assertEqual(self.obj["foo"], ["asdf", {"bar": 1}, {"bar": 2}, "hello", {"baz": 3}])
gpath.insert(self.obj, ["foo", None], "world")
self.assertEqual(self.obj["foo"],
["asdf", {"bar": 1}, {"bar": 2}, "hello", {"baz": 3}, "world"])
def test_insert_strict(self):
with self.assertRaisesRegex(Exception, r'not an array'):
gpath.insert(self.obj, ["foo"], "asdf")
with self.assertRaisesRegex(Exception, r'invalid.*index'):
gpath.insert(self.obj, ["foo", -1], 17)
with self.assertRaisesRegex(Exception, r'invalid.*index'):
gpath.insert(self.obj, ["foo", "foo"], 17)
def test_update(self):
"""update should update array items"""
self.assertEqual(self.obj["foo"], [{"bar": 1}, {"bar": 2}, {"baz": 3}])
gpath.update(self.obj, ["foo", 0], "asdf")
self.assertEqual(self.obj["foo"], ["asdf", {"bar": 2}, {"baz": 3}])
gpath.update(self.obj, ["foo", 2], "hello")
self.assertEqual(self.obj["foo"], ["asdf", {"bar": 2}, "hello"])
gpath.update(self.obj, ["foo", 1], None)
self.assertEqual(self.obj["foo"], ["asdf", None, "hello"])
def test_update_strict(self):
"""update should be strict"""
with self.assertRaisesRegex(Exception, r'non-existent'):
gpath.update(self.obj, ["bar", 4], 17)
with self.assertRaisesRegex(Exception, r'not an array'):
gpath.update(self.obj, ["foo"], 17)
with self.assertRaisesRegex(Exception, r'invalid.*index'):
gpath.update(self.obj, ["foo", -1], 17)
with self.assertRaisesRegex(Exception, r'invalid.*index'):
gpath.update(self.obj, ["foo", None], 17)
def test_remove(self):
"""remove should remove indices"""
self.assertEqual(self.obj["foo"], [{"bar": 1}, {"bar": 2}, {"baz": 3}])
gpath.remove(self.obj, ["foo", 0])
self.assertEqual(self.obj["foo"], [{"bar": 2}, {"baz": 3}])
gpath.remove(self.obj, ["foo", 1])
self.assertEqual(self.obj["foo"], [{"bar": 2}])
gpath.remove(self.obj, ["foo", 0])
self.assertEqual(self.obj["foo"], [])
def test_remove_strict(self):
"""remove should be strict"""
with self.assertRaisesRegex(Exception, r'non-existent'):
gpath.remove(self.obj, ["bar", 4])
with self.assertRaisesRegex(Exception, r'not an array'):
gpath.remove(self.obj, ["foo"])
with self.assertRaisesRegex(Exception, r'invalid.*index'):
gpath.remove(self.obj, ["foo", -1])
with self.assertRaisesRegex(Exception, r'invalid.*index'):
gpath.remove(self.obj, ["foo", None])
def test_glob(self):
"""glob should scan arrays"""
self.assertEqual(self.obj["foo"], [{"bar": 1}, {"bar": 2}, {"baz": 3}])
self.assertEqual(gpath.place(self.obj, ["foo", "*", "bar"], 17), 3)
self.assertEqual(self.obj["foo"], [{"bar": 17}, {"bar": 17}, {"baz": 3, "bar": 17}])
with self.assertRaisesRegex(Exception, r'non-existent object at \/foo\/\*\/bad'):
gpath.place(self.obj, ["foo", "*", "bad", "test"], 10)
self.assertEqual(gpath.update(self.obj, ["foo", "*"], "hello"), 3)
self.assertEqual(self.obj["foo"], ["hello", "hello", "hello"])
def test_glob_strict_wildcard(self):
"""should only support tail wildcard for updates"""
with self.assertRaisesRegex(Exception, r'invalid array index'):
gpath.remove(self.obj, ["foo", "*"])
with self.assertRaisesRegex(Exception, r'invalid array index'):
gpath.insert(self.obj, ["foo", "*"], 1)
def test_glob_wildcard_keys(self):
"""should not scan object keys"""
self.assertEqual(self.obj["foo"], [{"bar": 1}, {"bar": 2}, {"baz": 3}])
self.assertEqual(gpath.place(self.obj, ["foo", 0, "*"], 17), 1)
self.assertEqual(self.obj["foo"], [{"bar": 1, '*': 17}, {"bar": 2}, {"baz": 3}])
with self.assertRaisesRegex(Exception, r'non-existent'):
gpath.place(self.obj, ["*", 0, "bar"], 17)
def test_glob_nested(self):
"""should scan nested arrays"""
self.obj = [{"a": [1,2,3]}, {"a": [4,5,6]}, {"a": [7,8,9]}]
self.assertEqual(gpath.update(self.obj, ["*", "a", "*"], 5), 9)
self.assertEqual(self.obj, [{"a": [5,5,5]}, {"a": [5,5,5]}, {"a": [5,5,5]}])
def test_dirname(self):
"""dirname should return path without last component"""
self.assertEqual(gpath.dirname(["foo", "bar", "baz"]), ["foo", "bar"])
self.assertEqual(gpath.dirname([1, 2]), [1])
self.assertEqual(gpath.dirname(["foo"]), [])
self.assertEqual(gpath.dirname([]), [])
def test_basename(self):
"""basename should return the last component of path"""
self.assertEqual(gpath.basename(["foo", "bar", "baz"]), "baz")
self.assertEqual(gpath.basename([1, 2]), 2)
self.assertEqual(gpath.basename(["foo"]), "foo")
self.assertEqual(gpath.basename([]), None)
if __name__ == "__main__":
unittest.main()