comparison tests/test.py @ 542:f71d34dda19f

Add an optional C-implementation for configmix.config.unquote and configmix.config.pathstr2path. This is currently for Python 3.5+. It is tested with Python 3.7 and Python3.8 (FreeBSD 12.2 amd64, LLVM 10.0.1). A build for the stable API ("abi3") fails because PyUnicode_New() is currently not in the stable API. Also includes are extended tests for unquote() and pathstr2path().
author Franz Glasner <fzglas.hg@dom66.de>
date Fri, 31 Dec 2021 21:24:16 +0100
parents be6ef72c55d5
children 491413368c7c
comparison
equal deleted inserted replaced
541:25b61f0a1958 542:f71d34dda19f
15 import configmix.ini 15 import configmix.ini
16 import configmix.yaml 16 import configmix.yaml
17 import configmix.json 17 import configmix.json
18 import configmix.py 18 import configmix.py
19 import configmix.toml 19 import configmix.toml
20 import configmix.config
20 from configmix.compat import u, PY2 21 from configmix.compat import u, PY2
21 22
22 23
23 TESTDATADIR = os.path.join( 24 TESTDATADIR = os.path.join(
24 os.path.abspath(os.path.dirname(__file__)), 25 os.path.abspath(os.path.dirname(__file__)),
1213 def test_reference2(self): 1214 def test_reference2(self):
1214 self.assertEqual( 1215 self.assertEqual(
1215 "value", 1216 "value",
1216 self._cfg.getvar_s("events.qc-2021%x2e1-5G-summit.xref.%x23")) 1217 self._cfg.getvar_s("events.qc-2021%x2e1-5G-summit.xref.%x23"))
1217 1218
1218 def test_quoting_and_unquoting_are_inverse(self):
1219 for c in """%.:#|"'{}[]""":
1220 qc = configmix.quote(c)
1221 self.assertTrue(qc.startswith("%x") and len(qc) == 4)
1222 self.assertEqual(c, configmix.unquote(qc))
1223
1224 def test_quoting_and_unquoting_are_identical(self):
1225 # other characters
1226 for c in """abc09/""":
1227 qc = configmix.quote(c)
1228 self.assertEqual(c, qc)
1229 self.assertEqual(c, configmix.unquote(qc))
1230
1231 def test_namespace_quoting(self): 1219 def test_namespace_quoting(self):
1232 v1 = self._cfg.getvar("PY:version") 1220 v1 = self._cfg.getvar("PY:version")
1233 v2 = self._cfg.getvar("P%x59:version") 1221 v2 = self._cfg.getvar("P%x59:version")
1234 v3 = self._cfg.getvar("%U00000050Y:version") 1222 v3 = self._cfg.getvar("%U00000050Y:version")
1235 v4 = self._cfg.getvar("%x50%u0059:version") 1223 v4 = self._cfg.getvar("%x50%u0059:version")
1782 self.assertEqual(u"val1", jcfg[0]) 1770 self.assertEqual(u"val1", jcfg[0])
1783 self.assertEqual(u"val2", jcfg[1]) 1771 self.assertEqual(u"val2", jcfg[1])
1784 self.assertEqual(u"in the root namespace", jcfg[2]) 1772 self.assertEqual(u"in the root namespace", jcfg[2])
1785 1773
1786 1774
1775 class _TParserMixin:
1776 def test_quote_and_unquote_empty(self):
1777 e = configmix.quote(u"")
1778 self.assertEqual(u"", e)
1779 self.assertEqual(u"", self.unquote(e))
1780
1781 def test_quoting_and_unquoting_are_inverse(self):
1782 for c in u"""%.:#|"'{}[]""":
1783 qc = configmix.quote(c)
1784 self.assertTrue(qc.startswith(u"%x") and len(qc) == 4)
1785 self.assertEqual(c, self.unquote(qc))
1786
1787 def test_quoting_and_unquoting_are_identical(self):
1788 # other characters
1789 for c in configmix.config._QUOTE_SAFE:
1790 qc = configmix.quote(c)
1791 self.assertEqual(c, qc)
1792 self.assertEqual(c, self.unquote(qc))
1793
1794 def test_unquote_unimax(self):
1795 self.assertEqual(u"\U00019001", self.unquote(u"%U00019001"))
1796 self.assertEqual(u"X\U00019AF1Z", self.unquote(u"X%U00019aF1Z"))
1797
1798 def test_unquote_base_plane(self):
1799 self.assertEqual(u"\uFFFF", self.unquote(u"%uffff"))
1800 self.assertEqual(u"X\uFFFFZ", self.unquote(u"X%uffffZ"))
1801
1802 def test_unquote_latin(self):
1803 self.assertEqual(u"\xFF", self.unquote(u"%xff"))
1804 self.assertEqual(u"X\xFFZ", self.unquote(u"X%xffZ"))
1805
1806 def test_unquote_zero(self):
1807 self.assertEqual(u"\x00", self.unquote(u"%x00"))
1808 self.assertEqual(u"X\x00Z", self.unquote(u"X%x00Z"))
1809
1810 def test_unquote_adjacent_x(self):
1811 self.assertEqual(u"\x00\x01\xA0\xB0\xFF",
1812 self.unquote(u"%x00%x01%xA0%xB0%xFF"))
1813
1814 def test_unquote_adjacent_u(self):
1815 self.assertEqual(u"\u0000\u0001\u00A0\uABCD\uFEFE",
1816 self.unquote(u"%u0000%u0001%u00A0%uabCD%ufeFE"))
1817
1818 def test_unquote_adjacent_U(self):
1819 self.assertEqual(
1820 u"\U00000000\U00000001\U000000A0\U0001ABCD\U0001FEFE",
1821 self.unquote(u"%U00000000%U00000001%U000000A0%U0001abCD%U0001feFE"))
1822
1823 def test_invalid_hex_digits(self):
1824 self.assertRaises(
1825 ValueError,
1826 self.unquote,
1827 u"%xgG")
1828 self.assertRaises(
1829 ValueError,
1830 self.unquote,
1831 u"%ugGGG")
1832 self.assertRaises(
1833 ValueError,
1834 self.unquote,
1835 u"%UgGGGgGGG")
1836
1837 def test_invalid_too_short(self):
1838 self.assertRaises(
1839 ValueError,
1840 self.unquote,
1841 u"%x0")
1842 self.assertRaises(
1843 ValueError,
1844 self.unquote,
1845 u"%u000")
1846 self.assertRaises(
1847 ValueError,
1848 self.unquote,
1849 u"%U0000000")
1850
1851 def test_invalid_too_short_no_sigil(self):
1852 self.assertRaises(
1853 ValueError,
1854 self.unquote,
1855 u"%")
1856
1857 def test_empty_pathstr(self):
1858 # an empty path string returns an empty path tuple
1859 self.assertEqual(tuple(), self.pathstr2path(u""))
1860
1861 def test_split(self):
1862 p = self.pathstr2path(u"abc.def.hik.jkl")
1863 self.assertEqual((u"abc", u"def", u"hik", u"jkl"), p)
1864
1865 def test_split_all_empty_parts(self):
1866 p = self.pathstr2path(u"....")
1867 self.assertEqual((u"", u"", u"", u"", u""), p)
1868
1869 def test_split_all_empty_tail(self):
1870 p = self.pathstr2path(u"1.2.")
1871 self.assertEqual((u"1", u"2", u""), p)
1872
1873 def test_split_unquote(self):
1874 p = self.pathstr2path(u"a%x2Eb.c%u002Ed.e%U0000002Ef")
1875 self.assertEqual((u"a.b", u"c.d", u"e.f"), p)
1876
1877
1878 class T09Parser(_TParserMixin, unittest.TestCase):
1879
1880 def setUp(self):
1881 self.unquote = configmix.config.py_unquote
1882 self.pathstr2path = configmix.config.py_pathstr2path
1883
1884
1885 if configmix.config.fast_unquote is not None:
1886 class T10FastParser(_TParserMixin, unittest.TestCase):
1887
1888 def setUp(self):
1889 self.unquote = configmix.config.fast_unquote
1890 self.pathstr2path = configmix.config.fast_pathstr2path
1891
1892
1787 if __name__ == "__main__": 1893 if __name__ == "__main__":
1788 unittest.main() 1894 unittest.main()