10d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin#!/usr/bin/python2.4 20d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin# 30d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin# Copyright 2008 The RE2 Authors. All Rights Reserved. 40d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin# Use of this source code is governed by a BSD-style 50d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin# license that can be found in the LICENSE file. 60d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 70d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin"""Unittest for the util/regexp/re2/unicode.py module.""" 80d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 90d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkinimport os 100d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkinimport StringIO 110d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkinfrom google3.pyglib import flags 120d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkinfrom google3.testing.pybase import googletest 130d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkinfrom google3.util.regexp.re2 import unicode 140d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 150d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin_UNICODE_DIR = os.path.join(flags.FLAGS.test_srcdir, "google3", "third_party", 160d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin "unicode", "ucd-5.1.0") 170d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 180d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 190d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkinclass ConvertTest(googletest.TestCase): 200d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin """Test the conversion functions.""" 210d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 220d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin def testUInt(self): 230d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals(0x0000, unicode._UInt("0000")) 240d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals(0x263A, unicode._UInt("263A")) 250d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals(0x10FFFF, unicode._UInt("10FFFF")) 260d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertRaises(unicode.InputError, unicode._UInt, "263") 270d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertRaises(unicode.InputError, unicode._UInt, "263AAAA") 280d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertRaises(unicode.InputError, unicode._UInt, "110000") 290d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 300d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin def testURange(self): 310d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals([1, 2, 3], unicode._URange("0001..0003")) 320d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals([1], unicode._URange("0001")) 330d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertRaises(unicode.InputError, unicode._URange, "0001..0003..0005") 340d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertRaises(unicode.InputError, unicode._URange, "0003..0001") 350d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertRaises(unicode.InputError, unicode._URange, "0001..0001") 360d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 370d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin def testUStr(self): 380d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("0x263A", unicode._UStr(0x263a)) 390d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("0x10FFFF", unicode._UStr(0x10FFFF)) 400d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertRaises(unicode.InputError, unicode._UStr, 0x110000) 410d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertRaises(unicode.InputError, unicode._UStr, -1) 420d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 430d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 440d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin_UNICODE_TABLE = """# Commented line, should be ignored. 450d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin# The next line is blank and should be ignored. 460d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 470d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin0041;Capital A;Line 1 480d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin0061..007A;Lowercase;Line 2 490d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin1F00;<Greek, First>;Ignored 500d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin1FFE;<Greek, Last>;Line 3 510d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin10FFFF;Runemax;Line 4 520d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin0000;Zero;Line 5 530d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin""" 540d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 550d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin_BAD_TABLE1 = """ 560d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin111111;Not a code point; 570d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin""" 580d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 590d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin_BAD_TABLE2 = """ 600d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin0000;<Zero, First>;Missing <Zero, Last> 610d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin""" 620d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 630d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin_BAD_TABLE3 = """ 640d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin0010..0001;Bad range; 650d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin""" 660d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 670d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 680d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkinclass AbortError(Exception): 690d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin """Function should not have been called.""" 700d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 710d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 720d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkindef Abort(): 730d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin raise AbortError("Abort") 740d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 750d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 760d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkindef StringTable(s, n, f): 770d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin unicode.ReadUnicodeTable(StringIO.StringIO(s), n, f) 780d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 790d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 800d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkinclass ReadUnicodeTableTest(googletest.TestCase): 810d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin """Test the ReadUnicodeTable function.""" 820d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 830d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin def testSimpleTable(self): 840d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 850d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin ncall = [0] # can't assign to ordinary int in DoLine 860d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 870d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin def DoLine(codes, fields): 880d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals(3, len(fields)) 890d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin ncall[0] += 1 900d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("Line %d" % (ncall[0],), fields[2]) 910d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin if ncall[0] == 1: 920d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals([0x0041], codes) 930d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("0041", fields[0]) 940d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("Capital A", fields[1]) 950d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin elif ncall[0] == 2: 960d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals(range(0x0061, 0x007A + 1), codes) 970d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("0061..007A", fields[0]) 980d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("Lowercase", fields[1]) 990d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin elif ncall[0] == 3: 1000d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals(range(0x1F00, 0x1FFE + 1), codes) 1010d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("1F00..1FFE", fields[0]) 1020d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("Greek", fields[1]) 1030d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin elif ncall[0] == 4: 1040d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals([0x10FFFF], codes) 1050d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("10FFFF", fields[0]) 1060d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("Runemax", fields[1]) 1070d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin elif ncall[0] == 5: 1080d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals([0x0000], codes) 1090d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("0000", fields[0]) 1100d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("Zero", fields[1]) 1110d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 1120d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin StringTable(_UNICODE_TABLE, 3, DoLine) 1130d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals(5, ncall[0]) 1140d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 1150d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin def testErrorTables(self): 1160d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertRaises(unicode.InputError, StringTable, _UNICODE_TABLE, 4, Abort) 1170d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertRaises(unicode.InputError, StringTable, _UNICODE_TABLE, 2, Abort) 1180d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertRaises(unicode.InputError, StringTable, _BAD_TABLE1, 3, Abort) 1190d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertRaises(unicode.InputError, StringTable, _BAD_TABLE2, 3, Abort) 1200d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertRaises(unicode.InputError, StringTable, _BAD_TABLE3, 3, Abort) 1210d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 1220d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 1230d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkinclass ParseContinueTest(googletest.TestCase): 1240d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin """Test the ParseContinue function.""" 1250d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 1260d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin def testParseContinue(self): 1270d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals(("Private Use", "First"), 1280d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin unicode._ParseContinue("<Private Use, First>")) 1290d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals(("Private Use", "Last"), 1300d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin unicode._ParseContinue("<Private Use, Last>")) 1310d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals(("<Private Use, Blah>", None), 1320d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin unicode._ParseContinue("<Private Use, Blah>")) 1330d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 1340d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 1350d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkinclass CaseGroupsTest(googletest.TestCase): 1360d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin """Test the CaseGroups function (and the CaseFoldingReader).""" 1370d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 1380d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin def FindGroup(self, c): 1390d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin if type(c) == str: 1400d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin c = ord(c) 1410d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin for g in self.groups: 1420d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin if c in g: 1430d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin return g 1440d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin return None 1450d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 1460d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin def testCaseGroups(self): 1470d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.groups = unicode.CaseGroups(unicode_dir=_UNICODE_DIR) 1480d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals([ord("A"), ord("a")], self.FindGroup("a")) 1490d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals(None, self.FindGroup("0")) 1500d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 1510d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 1520d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkinclass ScriptsTest(googletest.TestCase): 1530d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin """Test the Scripts function (and the ScriptsReader).""" 1540d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 1550d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin def FindScript(self, c): 1560d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin if type(c) == str: 1570d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin c = ord(c) 1580d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin for script, codes in self.scripts.items(): 1590d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin for code in codes: 1600d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin if c == code: 1610d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin return script 1620d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin return None 1630d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 1640d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin def testScripts(self): 1650d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.scripts = unicode.Scripts(unicode_dir=_UNICODE_DIR) 1660d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("Latin", self.FindScript("a")) 1670d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("Common", self.FindScript("0")) 1680d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals(None, self.FindScript(0xFFFE)) 1690d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 1700d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 1710d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkinclass CategoriesTest(googletest.TestCase): 1720d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin """Test the Categories function (and the UnicodeDataReader).""" 1730d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 1740d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin def FindCategory(self, c): 1750d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin if type(c) == str: 1760d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin c = ord(c) 1770d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin short = None 1780d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin for category, codes in self.categories.items(): 1790d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin for code in codes: 1800d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin if code == c: 1810d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin # prefer category Nd over N 1820d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin if len(category) > 1: 1830d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin return category 1840d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin if short == None: 1850d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin short = category 1860d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin return short 1870d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 1880d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin def testCategories(self): 1890d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.categories = unicode.Categories(unicode_dir=_UNICODE_DIR) 1900d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("Ll", self.FindCategory("a")) 1910d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("Nd", self.FindCategory("0")) 1920d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("Lo", self.FindCategory(0xAD00)) # in First, Last range 1930d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals(None, self.FindCategory(0xFFFE)) 1940d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("Lo", self.FindCategory(0x8B5A)) 1950d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("Lo", self.FindCategory(0x6C38)) 1960d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertEquals("Lo", self.FindCategory(0x92D2)) 1970d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertTrue(ord("a") in self.categories["L"]) 1980d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertTrue(ord("0") in self.categories["N"]) 1990d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertTrue(0x8B5A in self.categories["L"]) 2000d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertTrue(0x6C38 in self.categories["L"]) 2010d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin self.assertTrue(0x92D2 in self.categories["L"]) 2020d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 2030d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkindef main(): 2040d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin googletest.main() 2050d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 2060d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkinif __name__ == "__main__": 2070d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin main() 208