def generate(amt: int) -> None : rs = Rstr(SystemRandom()) codes = dict() if os.path.exists(codes_path) : with open(codes_path, 'r') as fp : codes = json.load(fp)['codes'] count = 0 new_codes = [] while count < amt : cd = rs.xeger(pattern) if cd not in codes : new_codes.append(cd) codes[cd] = True count += 1 # separate JSON of most recently generated codes with open(os.path.join(path, 'obj/new-codes.json'), 'w') as fp : json.dump({'codes' : {cd : True for cd in new_codes}}, fp, indent=INDENT) else : codes = {rs.xeger(pattern) : True for _ in range(amt)} with open(codes_path, 'w') as fp : json.dump({'codes' : codes}, fp, indent=INDENT)
class TestNondigits(unittest.TestCase): def setUp(self) -> None: self.rs = Rstr() def test_nondigits(self) -> None: assert_matches(r'^\D{1,10}$', self.rs.nondigits()) def test_nondigits_include(self) -> None: assert_matches(r'^\D*@\D*$', self.rs.nondigits(include='@')) def test_nondigits_exclude(self) -> None: for _ in range(0, 100): assert 'A' not in self.rs.nondigits(exclude='A')
class TestLetters(unittest.TestCase): def setUp(self) -> None: self.rs = Rstr() def test_letters(self) -> None: assert_matches(r'^[a-zA-Z]{1,10}$', self.rs.letters()) def test_letters_include(self) -> None: assert_matches(r'^[a-zA-Z]*@[a-zA-Z]*$', self.rs.letters(include='@')) def test_letters_exclude(self) -> None: for _ in range(0, 100): assert 'A' not in self.rs.letters(exclude='A')
class TestDigits(unittest.TestCase): def setUp(self) -> None: self.rs = Rstr() def test_all_digits(self) -> None: assert_matches(r'^\d{1,10}$', self.rs.digits()) def test_digits_include(self) -> None: assert_matches(r'^\d*@\d*$', self.rs.digits(include='@')) def test_digits_exclude(self) -> None: for _ in range(0, 100): assert '5' not in self.rs.digits(exclude='5')
class TestUnambiguous(unittest.TestCase): def setUp(self) -> None: self.rs = Rstr() def test_unambiguous(self) -> None: assert_matches('^[a-km-zA-HJ-NP-Z2-9]{1,10}$', self.rs.unambiguous()) def test_unambiguous_include(self) -> None: assert_matches('^[a-km-zA-HJ-NP-Z2-9@]{1,10}$', self.rs.unambiguous(include='@')) def test_unambiguous_exclude(self) -> None: for _ in range(0, 100): assert 'A' not in self.rs.unambiguous(exclude='A')
class Regex(Generator): def __init__(self, regex, seed=None): self.gen = Rstr(Random(seed)) self.regex = regex def get_single(self): return self.gen.xeger(self.regex)
from contextlib import contextmanager import errno import os import re from random import SystemRandom import tempfile from rstr import Rstr from ._compat import which rstr = Rstr(SystemRandom()) import_module = __import__ def genpass(pattern=r'[\w]{32}'): """generates a password with random chararcters """ try: return rstr.xeger(pattern) except re.error as e: raise ValueError(str(e)) @contextmanager def mkdir_open(path, mode="r"): try: dir_path = os.path.dirname(path) os.makedirs(dir_path)
def __init__(self, regex, seed=None): self.gen = Rstr(Random(seed)) self.regex = regex
def text_from_regex(draw, regexp): random = draw(st.randoms()) return Rstr(random).xeger(regexp)
def setUp(self) -> None: self.rs = Rstr()
class TestXeger(unittest.TestCase): def setUp(self) -> None: self.rs = Rstr() def test_literals(self) -> None: pattern = r'foo' assert re.match(pattern, self.rs.xeger(pattern)) def test_dot(self) -> None: ''' Verify that the dot character doesn't produce newlines. See: https://bitbucket.org/leapfrogdevelopment/rstr/issue/1/ ''' pattern = r'.+' for i in range(100): assert re.match(pattern, self.rs.xeger(pattern)) def test_digit(self) -> None: pattern = r'\d' assert re.match(pattern, self.rs.xeger(pattern)) def test_nondigits(self) -> None: pattern = r'\D' assert re.match(pattern, self.rs.xeger(pattern)) def test_literal_with_repeat(self) -> None: pattern = r'A{3}' assert re.match(pattern, self.rs.xeger(pattern)) def test_literal_with_range_repeat(self) -> None: pattern = r'A{2, 5}' assert re.match(pattern, self.rs.xeger(pattern)) def test_word(self) -> None: pattern = r'\w' assert re.match(pattern, self.rs.xeger(pattern)) def test_nonword(self) -> None: pattern = r'\W' assert re.match(pattern, self.rs.xeger(pattern)) def test_or(self) -> None: pattern = r'foo|bar' assert re.match(pattern, self.rs.xeger(pattern)) def test_or_with_subpattern(self) -> None: pattern = r'(foo|bar)' assert re.match(pattern, self.rs.xeger(pattern)) def test_range(self) -> None: pattern = r'[A-F]' assert re.match(pattern, self.rs.xeger(pattern)) def test_character_group(self) -> None: pattern = r'[ABC]' assert re.match(pattern, self.rs.xeger(pattern)) def test_carot(self) -> None: pattern = r'^foo' assert re.match(pattern, self.rs.xeger(pattern)) def test_dollarsign(self) -> None: pattern = r'foo$' assert re.match(pattern, self.rs.xeger(pattern)) def test_not_literal(self) -> None: pattern = r'[^a]' assert re.match(pattern, self.rs.xeger(pattern)) def test_negation_group(self) -> None: pattern = r'[^AEIOU]' assert re.match(pattern, self.rs.xeger(pattern)) def test_lookahead(self) -> None: pattern = r'foo(?=bar)' assert re.match(pattern, self.rs.xeger(pattern)) def test_lookbehind(self) -> None: pattern = r'(?<=foo)bar' assert re.search(pattern, self.rs.xeger(pattern)) def test_backreference(self) -> None: pattern = r'(foo|bar)baz\1' assert re.match(pattern, self.rs.xeger(pattern)) def test_zero_or_more_greedy(self) -> None: pattern = r'a*' assert re.match(pattern, self.rs.xeger(pattern)) def test_zero_or_more_non_greedy(self) -> None: pattern = r'a*?' assert re.match(pattern, self.rs.xeger(pattern))
def gen_access_key(self): rs = Rstr(SystemRandom()) self.access_key = rs.xeger(r'[A-Z]\d[A-Z]-\d[A-Z]\d') return self.access_key
def setUp(self) -> None: self.rs = Rstr(random.SystemRandom())
def test_add_alphabet(self) -> None: rs = Rstr() rs.add_alphabet('evens', '02468') assert_matches('^[02468]{1,10}$', rs.evens())
def test_alphabet_at_instantiation(self) -> None: rs = Rstr(vowels='AEIOU') assert_matches('^[AEIOU]{1,10}$', rs.vowels())
class TestRstr(unittest.TestCase): def setUp(self) -> None: self.rs = Rstr() def test_specific_length(self) -> None: assert_matches('^A{5}$', self.rs.rstr('A', 5)) def test_length_range(self) -> None: assert_matches('^A{11,20}$', self.rs.rstr('A', 11, 20)) def test_end_range_no_start_range(self) -> None: assert_matches('^A{1,20}$', self.rs.rstr('A', end_range=20)) def test_custom_alphabet(self) -> None: assert_matches('^A{1,10}$', self.rs.rstr('AA')) def test_alphabet_as_list(self) -> None: assert_matches('^A{1,10}$', self.rs.rstr(['A', 'A'])) def test_include(self) -> None: assert_matches('^[ABC]*@[ABC]*$', self.rs.rstr('ABC', include='@')) def test_include_specific_length(self) -> None: ''' Verify including characters doesn't make the string longer than intended. ''' assert_matches('^[ABC@]{5}$', self.rs.rstr('ABC', 5, include='@')) def test_exclude(self) -> None: for _ in range(0, 100): assert 'C' not in self.rs.rstr('ABC', exclude='C') def test_include_as_list(self) -> None: assert_matches('^[ABC]*@[ABC]*$', self.rs.rstr('ABC', include=['@'])) def test_exclude_as_list(self) -> None: for _ in range(0, 100): assert 'C' not in self.rs.rstr('ABC', exclude=['C']) def test_raise_exception_if_include_and_exclude_parameters_contain_same_character( self) -> None: with self.assertRaisesRegex( SameCharacterError, r"include and exclude parameters contain same character \(B\)" ): self.rs.rstr('A', include='B', exclude='B') self.rs.rstr('A', include=['B'], exclude=['B']) with self.assertRaisesRegex( SameCharacterError, r"include and exclude parameters contain same characters \(., .\)" ): self.rs.rstr('A', include='BC', exclude='BC')