def test_group(self): """ Does the group method add parentheses? """ sample = Randomizer.letters() exp = Group.group(sample) self.assertEqual("(" + sample + ")",exp) matched = re.search(exp,sample+Randomizer.letters()).groups()[0] self.assertEqual(matched, sample) return
def test_string_end(self): """ Does it return the end of string metacharacter? """ metacharacter = Boundaries.string_end word = Randomizer.letters() expression = word + metacharacter text = Randomizer.letters() + word self.assertIsNotNone(re.search(expression, text)) self.assertIsNone(re.search(expression, text + Randomizer.letters())) return
def test_zero_or_one(self): """ Does it return the zero-or-one quantifier? """ substring = Randomizer.letters() text = Randomizer.letters() expression = text + Quantifier.zero_or_one("(" + substring + ")") text_1 = text + substring * random.randint(1,100) text_2 = text + substring * random.randint(1,100) self.assertIsNotNone(re.search(expression, text_1)) self.assertEqual(re.search(expression, text_2).groups()[0], substring) return
def test_zero_or_more(self): """ Does it return the kleene star? """ substring = Randomizer.letters() text = Randomizer.letters() complement = text + Randomizer.letters_complement(substring) expression = text + Quantifier.zero_or_more('(' + substring + ')') text_1 = text + substring * random.randint(0, 10) + Randomizer.letters() self.assertIsNotNone(re.search(expression, complement)) self.assertIsNotNone(re.search(expression, text_1)) return
def test_one_or_more(self): """ Does it return the one-or-more metacharachter? """ character = random.choice(string.letters) complement = Randomizer.letters_complement(character) text = Randomizer.letters() + character * random.randint(1,100) + Randomizer.letters() expression = character + '+' self.assertIsNone(re.search(expression, complement)) self.assertIsNotNone(re.search(expression, text)) return
def test_preceded_by(self): "Does it match a substring with a prefix?" name = 'preceded' body = Randomizer.letters() sub_string = Randomizer.letters() prefix = Randomizer.letters() expression = Group.named(name, Group.preceded_by(prefix) + sub_string) text = body + prefix + sub_string match = re.search(expression, text) self.assertEqual(match.group(name), sub_string)
def test_word_boundary(self): """ Does it add word-boundaries to the expression """ word = Randomizer.letters() expected = r'\b' + word + r'\b' expression = Boundaries.word(word) bad_word = word + Randomizer.letters() text = ' '.join([Randomizer.letters(),word,Randomizer.letters()]) self.assertIsNone(re.search(expression, bad_word)) self.assertIsNotNone(re.search(expression, text)) return
def test_named(self): """ Does the named method create a named group? """ name = Randomizer.letters() sample = Randomizer.letters() text = Randomizer.letters() + sample + Randomizer.letters() exp = Group.named(name=name, expression=sample) expected = '(?P<' + name + '>' + sample + ")" self.assertEqual(expected, exp) matched = re.search(exp, text).groupdict()[name] self.assertEqual(sample, matched) return
def test_string_start(self): """ Does it have return a string start metacharacter? """ metacharacter = Boundaries.string_start expected = '^' self.assertEqual(expected, metacharacter) word = Randomizer.letters() expression = Boundaries.string_start + word text = word + Randomizer.letters() self.assertIsNotNone(re.search(expression, text)) self.assertIsNone(re.search(expression, " " + text)) return
def test_digits(self): "Does it match one or more digits?" expression = Group.named(name='digits', expression=Numbers.digits) first = "{0}".format(random.randint(0,9)) rest = str(random.randint(0,1000)) test = first + rest self.assertIsNotNone(re.search(expression, test)) match = re.search(expression, test) self.assertEqual(match.group('digits'), test) mangled = Randomizer.letters() + test + Randomizer.letters() match = re.search(expression, mangled) self.assertEqual(match.group('digits'), test) return
def test_followed_by(self): """ Does it match strings followed by a pattern? """ body = Randomizer.letters() sub_string = Randomizer.letters() suffix = Randomizer.letters() text = body + sub_string + suffix name = 'followed' expression = Group.named(name, sub_string + Group.followed_by(suffix)) match = re.search(expression, text) self.assertEqual(match.group(name), sub_string)
def test_not_preceded_by(self): ''' Does it create a negative look-behind expression? ''' prefix = Randomizer.letters() expr = Group.not_preceded_by(prefix) self.assertEqual(L_PERL_GROUP + "<!" + prefix + R_GROUP, expr) text = Randomizer.letters(minimum=5) is_preceded_by = prefix + text self.assertIsNone(re.search(expr + text, is_preceded_by)) self.assertIsNotNone(re.search(expr + text, text)) return
def test_exactly(self): """ Does it return the repetition suffix? """ repetitions = Randomizer.integer(minimum=1, maximum=5) repeater = Randomizer.letters() expected = "{" + "{0}".format(repetitions) + "}" quantifier = Quantifier.exactly(repetitions) self.assertEqual(expected, quantifier) expression = "(" + repeater + ")" + quantifier text = Randomizer.letters() + repeater * (repetitions + Randomizer.integer(minimum=0)) self.assertIsNotNone(re.search(expression, text)) self.assertEqual(re.search(expression, text).groups(), (repeater,)) return
def test_not_followed_by(self): """ Does not_followed_by create a negative lookahead assertion? """ prefix = Randomizer.letters(maximum=5) suffix = Randomizer.letters_complement(prefix) expr = Group.not_followed_by(suffix) text = Randomizer.letters() self.assertEqual(L_PERL_GROUP + '!' + suffix + R_GROUP, expr) self.assertIsNone(re.search(text + expr, text + suffix)) self.assertIsNotNone(re.search(text + expr, text)) return
def test_digit(self): """ Does it return the digit character class? """ metacharacter = CharacterClass.digit test = Randomizer.integer(maximum=9) self.assertIsNotNone(re.search(metacharacter, str(test))) self.assertIsNone(re.search(metacharacter, Randomizer.letters())) return
def test_decimal_point(self): """ Does it return a decimal point literal? """ metacharacter = Numbers.decimal_point test = random.uniform(0,100) self.assertIsNotNone(re.search(metacharacter, str(test))) self.assertIsNone(re.search(metacharacter, Randomizer.letters())) return
def test_m_to_n(self): """ Does it return the expression to match m-to-n repetitions """ m = Randomizer.integer(minimum=5) n = Randomizer.integer(minimum=m+1) substring = Randomizer.letters() quantifier = Quantifier.m_to_n(m,n) expression = '(' + substring + ')' + quantifier self.assertEqual("{" + str(m) + ',' + str(n) + '}',quantifier) text = Randomizer.letters() + substring * Randomizer.integer(m, n) complement = (Randomizer.letters_complement(substring) + substring * Randomizer.integer(0,m-1)) too_many = substring * Randomizer.integer(n+1, n*2) self.assertIsNotNone(re.search(expression, text)) self.assertIsNone(re.search(expression, complement)) self.assertEqual(re.search(expression, too_many).groups(), (substring,)) return
def test_empty_string(self): "Does it match only an empty string?" name = 'empty' expression = Group.named(name, FormalDefinition.empty_string) empty = '' not_empty = Randomizer.letters() match = re.search(expression, empty) self.assertEqual(empty, match.group(name)) self.assertIsNone(re.search(expression, not_empty)) return
def test_string_boundary(self): """ Does it add boundaries to match a whole line? """ substring = Randomizer.letters() expression = Boundaries.string(substring) expected = "^" + substring + "$" self.assertEqual(expected, expression) self.assertIsNotNone(re.search(expression, substring)) self.assertIsNone(re.search(expression, ' ' + substring)) return
def test_class(self): ''' Does it convert the string to a character class? ''' sample = Randomizer.letters() expression = CharacterClass.character_class(sample) self.assertEqual(LEFT_BRACKET + sample + RIGHT_BRACKET, expression) sub_string = random.choice(sample) complement = Randomizer.letters_complement(sample) self.assertIsNotNone(re.search(expression, sub_string)) self.assertIsNone(re.search(expression, complement)) return
def test_not(self): ''' Does it convert the string to a non-matching class? ''' sample = Randomizer.letters(maximum=10) complement = Randomizer.letters_complement(sample) expression = CharacterClass.not_in(sample) self.assertEqual(LEFT_BRACKET + '^' + sample + RIGHT_BRACKET, expression) self.assertIsNone(re.search(expression, sample)) self.assertIsNotNone(re.search(expression, complement)) return
def test_alternation(self): """ Does it match alternatives? """ name = 'or' # this might fail if one of the terms is a sub-string of another # and the longer term is chosen as the search term terms = [Randomizer.letters() for term in range(random.randint(10, 100))] expression = Group.named(name, FormalDefinition.alternative.join(terms)) test = terms[random.randrange(len(terms))] match = re.search(expression, test) self.assertEqual(test, match.group(name)) return
def test_one_hundreds(self): """ Does it match values from 100-199? """ number = "{0}".format(random.randint(100,199)) low_number = str(random.randint(-99,99)) high_number = str(random.randint(200,500)) float_number = str(random.uniform(100,199)) text = Randomizer.letters() + str(random.randint(100,199)) name = 'onehundred' expression = re.compile(Group.named(name, Numbers.one_hundreds)) self.assertIsNotNone(re.search(Numbers.one_hundreds, number)) self.assertIsNone(re.search(Numbers.one_hundreds, low_number)) self.assertIsNone(re.search(Numbers.one_hundreds, high_number)) # it only checks word boundaries and the decimal point is a boundary self.assertIsNotNone(re.search(Numbers.one_hundreds, float_number)) # it needs a word boundary so letters smashed against it will fail self.assertIsNone(re.search(Numbers.one_hundreds, text)) return