def parse_enums(code: str, trie: TrieRegEx) -> None: """ Finds enum values and adds them to the regex trie Args: code (str): Text to search through. trie (TrieRegEx): Trie to add results to. """ # scoop the innards from all enums, excluding enum structs for enum_innards_match in re.finditer( r'enum(?!\s+struct)(?:.|\n)*?{((?:.|\n)*?)}', code): Debug.log('-- Enum match: --\n{}\n-------'.format( enum_innards_match.group(0))) enum_innards: str = enum_innards_match.group(1) # try to get each enum variable for enum_def_match in re.finditer(r'(?:^|\n)\s*?(\w+)\b', enum_innards): def_text: str = enum_def_match.group(1) # if it's all uppercase, skip it if (re.match(r'\b[A-Z_\d]+\b', def_text)): continue # skip if already contains if (trie.has(def_text)): Debug.log('Skipping enum, already added: {}'.format(def_text)) continue trie.add(def_text) Debug.log('Enum added: {}'.format(def_text))
class TestHas(unittest.TestCase): """Tests for TrieRegEx.has()""" def setUp(self): self.words = ['heal', 'health', 'healthy', 'healthier', 'healthiest'] self.tre = TRE(*self.words) def test_existing_longest_word(self): self.assertTrue(self.tre.has('healthiest')) def test_existing_substring_word(self): self.assertTrue(self.tre.has('health')) self.assertTrue(self.tre.has('heal')) def test_nonexisting(self): self.assertFalse(self.tre.has('wound')) def test_nonword_substring_of_existing_word(self): self.assertFalse(self.tre.has('he')) def test_nonexisting_after_removed(self): """Also a test of the TrieRegEx.remove() function """ self.assertTrue(self.tre.has('healthy'), "'healthy' must first exist in trie") self.tre.remove('healthy') self.assertFalse(self.tre.has('healthy')) def test_existing_after_added(self): """Also a test of the TrieRegEx.add() function """ self.assertFalse(self.tre.has('settled'), "'settled' must first NOT exist in trie") self.tre.add('settled') self.assertTrue(self.tre.has('settled')) def test_empty_string(self): self.assertFalse(self.tre.has(''))
def parse_defines(code: str, trie: TrieRegEx) -> None: """ Finds defines and adds them to the regex trie Args: code (str): Text to search through. trie (TrieRegEx): Trie to add results to. """ # match all defines for define_match in re.finditer(r'^#define[ \t]*(\w+)\b[ \t]', code): define: str = define_match.group(1) # if all uppercase, ignore. Typically they should be uppercase but maybe there's an exception if (re.match(r'\b[A-Z_\d]+\b', define)): continue # skip if already contains if (trie.has(define)): Debug.log('Skipping define, already added: {}'.format(define)) continue trie.add(define) Debug.log('Define added: {}'.format(define))
def parse_publicconstants(code: str, trie: TrieRegEx) -> None: """ Finds public const variables and adds them to the regex trie Args: code (str): Text to search through. trie (TrieRegEx): Trie to add results to. """ # match public constants aka magic variables for constant_match in re.finditer( r'public[ \t]+const[ \t]+\w+[ \t]+(\w+)\b', code): constant: str = constant_match.group(1) # if all uppercase, ignore if (re.match(r'\b[A-Z_\d]+\b', constant)): continue # skip if already contains if (trie.has(constant)): Debug.log('Skipping const, already added: {}'.format(constant)) continue trie.add(constant) Debug.log('Const added: {}'.format(constant))
class TestTrieRegEx(unittest.TestCase): """Basic tests for each function in the trieregex.TrieRegEx class. More in-depth tests are located in files bearing their function names. """ def setUp(self): self.words = [ 'heart', 'healthy', 'pear', 'peach', 'lark', 'look', 'change' ] self.tre = TRE(*self.words) def test_add(self): self.assertEqual( self.tre._trie, { 'c': { 'h': { 'a': { 'n': { 'g': { 'e': { '**': {} } } } } } }, 'l': { 'a': { 'r': { 'k': { '**': {} } } }, 'o': { 'o': { 'k': { '**': {} } } } }, 'h': { 'e': { 'a': { 'l': { 't': { 'h': { 'y': { '**': {} } } } }, 'r': { 't': { '**': {} } } } } }, 'p': { 'e': { 'a': { 'c': { 'h': { '**': {} } }, 'r': { '**': {} } } } } }, "Words were not added to the trie (._trie) properly") def test_remove(self): self.tre = TRE(*self.words) self.tre.remove('healthy', 'change') self.assertEqual( self.tre._trie, { 'l': { 'a': { 'r': { 'k': { '**': {} } } }, 'o': { 'o': { 'k': { '**': {} } } } }, 'h': { 'e': { 'a': { 'r': { 't': { '**': {} } } } } }, 'p': { 'e': { 'a': { 'c': { 'h': { '**': {} } }, 'r': { '**': {} } } } } }, "'healthy' and 'change' were not properly removed from the trie") def test_has(self): for word in self.words: self.assertTrue(self.tre.has(word), f"'{word}' should be searchable in trie") non_existing = ['hear', 'ear', 'each', 'hang', 'ok', 'heal', 'pa'] for word in non_existing: self.assertFalse(self.tre.has(word), f"'{word}' should not be searchable in trie") def test_initials_variable(self): self.assertEqual( self.tre._initials, { 'c': 1, 'h': 2, 'l': 2, 'p': 2 }, ) def test_initials(self): self.assertEqual(self.tre.initials(), ['c', 'h', 'l', 'p']) def test_finals_variable(self): self.assertEqual(self.tre._finals, { 'e': 1, 'h': 1, 'k': 2, 'r': 1, 't': 1, 'y': 1 }) def test_finals(self): self.assertEqual(self.tre.finals(), ['e', 'h', 'k', 'r', 't', 'y']) def test_regex(self): self.assertEqual(self.tre.regex(), "(?:hea(?:lthy|rt)|l(?:ark|ook)|pea(?:ch|r)|change)")