def test_parse_ints_with_kwargs(self): for param_string, defaults, names, exp_params in ( ('1,baz=3', (2, 4, 6), ('foo', 'bar', 'baz', 'qux'), [1, 2, 3, 6]), ('g=0,h=', (1, 2, 3), ('f', 'g', 'h'), [1, 0, 3]), ): params = parse_ints(param_string, defaults=defaults, names=names)[1:] self.assertEqual(exp_params, params) # First parameter optional and omitted end, p, q, r = parse_ints(',r=2', defaults=(0, 5, 10), names=('p', 'q', 'r')) self.assertEqual((0, 5, 2), (p, q, r)) self.assertEqual(end, 4) # Arithmetic expressions with brackets text = '(foo=1+(3-2)*4,baz=(1^255)+1)' names = ('foo', 'bar', 'baz') defaults = (2, 3) self.assertEqual([len(text), 5, 2, 255], parse_ints(text, defaults=defaults, names=names)) # Arithmetic expressions with spaces text = '(foo = 12 / 3, bar = 34 & 15, baz = 7 | 8)' names = ('foo', 'bar', 'baz') self.assertEqual([len(text), 4, 2, 15], parse_ints(text, names=names))
def test_parse_ints_with_required_parameter_left_blank(self): for text, num, defaults, pos in ((',1,2', 3, (), 1), (',1,', 3, (2, ), 1), ('0,,2', 3, (), 2), ('0,,', 3, (2, ), 2), ('0,1,', 3, (), 3), ('0,1,', 3, (), 3)): error_msg = "Missing required parameter in position {}/{}: '{}'".format( pos, num - len(defaults), text) for param_string in (text, '({})'.format(text)): with self.assertRaisesRegex(MacroParsingError, error_msg): parse_ints(param_string, num=num, defaults=defaults)
def test_parse_ints_with_required_parameter_left_blank(self): for text, num, defaults, pos in ( (',1,2', 3, (), 1), (',1,', 3, (2,), 1), ('0,,2', 3, (), 2), ('0,,', 3, (2,), 2), ('0,1,', 3, (), 3), ('0,1,', 3, (), 3) ): error_msg = "Missing required parameter in position {}/{}: '{}'".format(pos, num - len(defaults), text) for param_string in (text, '({})'.format(text)): with self.assertRaisesRegex(MacroParsingError, error_msg): parse_ints(param_string, num=num, defaults=defaults)
def test_parse_ints_with_kwargs(self): for param_string, defaults, names, exp_params in ( ('1,baz=3', (2, 4, 6), ('foo', 'bar', 'baz', 'qux'), [1, 2, 3, 6]), ('g=0,h=', (1, 2, 3), ('f', 'g', 'h'), [1, 0, 3]), ): params = parse_ints(param_string, defaults=defaults, names=names)[1:] self.assertEqual(exp_params, params)
def expand_route(self, text, index, cwd=None): " Expand a directive of the form #ROUTE(address) " end, address = parse_ints(text, index, 1) s = "[ " while self.snapshot[address] != 0xFF: byte = self.snapshot[address] other = (byte & 0x7F) if other < 40: reversed = (byte >= 128) # it's a door r = " reversed" if reversed else "" s += "door(%d%s), " % (other, r) else: # it's a location index s += "location(%d), " % (other - 40) address += 1 s += "(end) ]" return end, s
def expand_route(self, text, index, cwd=None): " Expand a directive of the form #ROUTE(address) " end, address = parse_ints(text, index, 1) s = "[ " while self.snapshot[address] != 0xFF: byte = self.snapshot[address] reversed = (byte >= 128) other = (byte & 0x7F) if other < 40: # it's a door if reversed: r = " reversed" else: r = "" s += "door(%d%s), " % (other, r) else: # it's a location index s += "location(%d), " % (other - 40) address += 1 s += "(end) ]" return end, s
def test_parse_ints_without_kwargs(self): # Test with the exact number of parameters text = '1,$2,3' end, p1, p2, p3 = parse_ints(text, 0, 3) self.assertEqual((p1, p2, p3), (1, 2, 3)) self.assertEqual(end, len(text)) # Test with default parameter values text = '$1,2,3' end, p1, p2, p3, p4, p5 = parse_ints(text, 0, 5, (4, 5)) self.assertEqual((p1, p2, p3, p4, p5), (1, 2, 3, 4, 5)) self.assertEqual(end, len(text)) # Test with more than enough parameters text = '1,2,3' end, p1, p2 = parse_ints(text, 0, 2) self.assertEqual((p1, p2), (1, 2)) self.assertEqual(end, 3) # Test with blank parameters text = '1,,$a,' end, p1, p2, p3, p4 = parse_ints(text, 0, 4) self.assertEqual((p1, p2, p3, p4), (1, None, 10, None)) self.assertEqual(end, len(text)) # Test with an empty parameter string end, p1 = parse_ints('', 0, 1, (1,)) self.assertEqual(p1, 1) self.assertEqual(end, 0) # Test with adjacent non-numeric characters junk = 'xyz' text = '1,2{0}'.format(junk) end, p1, p2 = parse_ints(text, 0, 2) self.assertEqual((p1, p2), (1, 2)) self.assertEqual(end, len(text) - len(junk))
def parse_as(text, index): end, state = parse_ints(text, index, 1, (None,)) end, link_text = parse_brackets(text, end, '#N({},,,1)(0x)'.format(state)) return end, state, link_text
def parse_gbuf(text, index): # #GBUFfrom[,to] return parse_ints(text, index, 2, (None,))
def test_parse_ints_unknown_kwarg(self): with self.assertRaisesRegex(MacroParsingError, "Unknown keyword argument: 'qux=2'"): parse_ints('foo=1,qux=2', names=('foo', 'bar'))
def test_parse_ints_non_kwarg_after_kwarg(self): with self.assertRaisesRegex( MacroParsingError, "Non-keyword argument after keyword argument: '3'"): parse_ints('1,bar=2,3', names=('foo', 'bar', 'baz'))
def test_parse_ints_with_kwargs_not_enough_parameters(self): with self.assertRaisesRegex( MacroParsingError, "Missing required argument 'a': 'b=4,c=5'$"): parse_ints('b=4,c=5', defaults=(2, 3), names=('a', 'b', 'c'))
def test_parse_ints_without_kwargs(self): # No parameters expected self.assertEqual([0], parse_ints('', 0)) self.assertEqual([0], parse_ints('{not a param}', 0)) self.assertEqual([0], parse_ints('xxx', 0)) # Exact number of parameters text = '1,$2,3' end, p1, p2, p3 = parse_ints(text, 0, 3) self.assertEqual((1, 2, 3), (p1, p2, p3)) self.assertEqual(end, len(text)) # Default parameter values text = '$1,2,3' end, p1, p2, p3, p4, p5 = parse_ints(text, 0, 5, (4, 5)) self.assertEqual((1, 2, 3, 4, 5), (p1, p2, p3, p4, p5)) self.assertEqual(end, len(text)) # More than enough parameters text = '1,2,3' end, p1, p2 = parse_ints(text, 0, 2) self.assertEqual((1, 2), (p1, p2)) self.assertEqual(end, 3) # Blank parameters text = '1,,$a,' end, p1, p2, p3, p4 = parse_ints(text, 0, 4, (0, 0, 0)) self.assertEqual((1, 0, 10, 0), (p1, p2, p3, p4)) self.assertEqual(end, len(text)) # First parameter optional and omitted end, p1, p2, p3 = parse_ints(',1,2', 0, 3, (0, 5, 10)) self.assertEqual((0, 1, 2), (p1, p2, p3)) self.assertEqual(end, 4) # Empty parameter string end, p1 = parse_ints('', 0, 1, (1,)) self.assertEqual(p1, 1) self.assertEqual(end, 0) # Empty parameter string in brackets end, p1 = parse_ints('()', 0, 1, (1,)) self.assertEqual(p1, 1) self.assertEqual(end, 2) # Adjacent non-numeric characters junk = 'xyz' text = '1,2{0}'.format(junk) end, p1, p2 = parse_ints(text, 0, 2) self.assertEqual((1, 2), (p1, p2)) self.assertEqual(end, len(text) - len(junk)) # Arithmetic expressions: +, -, *, /, ** text = '(-1,1+1,5-2,10-3*2,2+7/2,3**2)' self.assertEqual([len(text), -1, 2, 3, 4, 5, 9], parse_ints(text, 0, 6)) # Arithmetic expressions: &, |, ^, % text = '(6&3,8|4,7^2,10%3)' self.assertEqual([len(text), 2, 12, 5, 1], parse_ints(text, 0, 4)) # Arithmetic expressions: <<, >> text = '(1<<5,96>>3)' self.assertEqual([len(text), 32, 12], parse_ints(text, 0, 2)) # Arithmetic expressions: ==, !=, >, <, >=, <= text = '(1==1,1!=1,5>4,5<4,6>=3,6<=3)' self.assertEqual([len(text), 1, 0, 1, 0, 1, 0], parse_ints(text, 0, 6)) # Arithmetic expressions: (, ) text = '(1+(1+1)/2,(2+2)*3-1)' self.assertEqual([len(text), 2, 11], parse_ints(text, 0, 2)) # Arithmetic expressions: spaces text = '(1 - (1 + 1) / 2, (2 + 2) * 3 + 1)' self.assertEqual([len(text), 0, 13], parse_ints(text, 0, 2))
def test_parse_ints_with_kwargs_not_enough_parameters(self): with self.assertRaisesRegexp(MacroParsingError, "Missing required argument 'a'"): parse_ints('b=4,c=5', defaults=(2, 3), names=('a', 'b', 'c'))
def test_parse_ints_without_kwargs(self): # No parameters expected self.assertEqual([0], parse_ints('', 0)) self.assertEqual([0], parse_ints('{not a param}', 0)) self.assertEqual([0], parse_ints('xxx', 0)) # Exact number of parameters text = '1,$2,3' end, p1, p2, p3 = parse_ints(text, 0, 3) self.assertEqual((1, 2, 3), (p1, p2, p3)) self.assertEqual(end, len(text)) # Default parameter values text = '$1,2,3' end, p1, p2, p3, p4, p5 = parse_ints(text, 0, 5, (4, 5)) self.assertEqual((1, 2, 3, 4, 5), (p1, p2, p3, p4, p5)) self.assertEqual(end, len(text)) # More than enough parameters text = '1,2,3' end, p1, p2 = parse_ints(text, 0, 2) self.assertEqual((1, 2), (p1, p2)) self.assertEqual(end, 3) # Blank parameters text = '1,,$a,' end, p1, p2, p3, p4 = parse_ints(text, 0, 4, (0, 0, 0)) self.assertEqual((1, 0, 10, 0), (p1, p2, p3, p4)) self.assertEqual(end, len(text)) # First parameter optional and omitted end, p1, p2, p3 = parse_ints(',1,2', 0, 3, (0, 5, 10)) self.assertEqual((0, 1, 2), (p1, p2, p3)) self.assertEqual(end, 4) # Empty parameter string end, p1 = parse_ints('', 0, 1, (1, )) self.assertEqual(p1, 1) self.assertEqual(end, 0) # Empty parameter string in brackets end, p1 = parse_ints('()', 0, 1, (1, )) self.assertEqual(p1, 1) self.assertEqual(end, 2) # Adjacent non-numeric characters junk = 'xyz' text = '1,2{0}'.format(junk) end, p1, p2 = parse_ints(text, 0, 2) self.assertEqual((1, 2), (p1, p2)) self.assertEqual(end, len(text) - len(junk)) # Arithmetic expressions: +, -, *, /, ** text = '(-1,1+1,5-2,10-3*2,2+7/2,3**2)' self.assertEqual([len(text), -1, 2, 3, 4, 5, 9], parse_ints(text, 0, 6)) # Arithmetic expressions: &, |, ^, % text = '(6&3,8|4,7^2,10%3)' self.assertEqual([len(text), 2, 12, 5, 1], parse_ints(text, 0, 4)) # Arithmetic expressions: <<, >> text = '(1<<5,96>>3)' self.assertEqual([len(text), 32, 12], parse_ints(text, 0, 2)) # Arithmetic expressions: ==, !=, >, <, >=, <= text = '(1==1,1!=1,5>4,5<4,6>=3,6<=3)' self.assertEqual([len(text), 1, 0, 1, 0, 1, 0], parse_ints(text, 0, 6)) # Arithmetic expressions: (, ) text = '(1+(1+1)/2,(2+2)*3-1)' self.assertEqual([len(text), 2, 11], parse_ints(text, 0, 2)) # Arithmetic expressions: spaces text = '(1 - (1 + 1) / 2, (2 + 2) * 3 + 1)' self.assertEqual([len(text), 0, 13], parse_ints(text, 0, 2))
def parse_gbuf(text, index): # #GBUFfrom[,to] return parse_ints(text, index, 2, (None, ))
def test_parse_ints_non_kwarg_after_kwarg(self): with self.assertRaisesRegexp(MacroParsingError, "Non-keyword argument after keyword argument: '3'"): parse_ints('1,bar=2,3', names=('foo', 'bar', 'baz'))
def test_parse_ints_invalid_kwarg_integer(self): with self.assertRaisesRegexp(MacroParsingError, "Cannot parse integer '3x' in parameter string: '1,baz=3x'"): parse_ints('1,baz=3x', defaults=(2, 3), names=('foo', 'bar', 'baz'))
def test_parse_ints_invalid_integer(self): with self.assertRaisesRegexp(MacroParsingError, re.escape("Cannot parse integer '3$0' in parameter string: '1,3$0'")): parse_ints('1,3$0', num=2)
def parse_lesson(text, index): end, lesson = parse_ints(text, index, 1) end, link_text = parse_brackets(text, end, '#N({},,,1)(0x)'.format(lesson)) return end, lesson, link_text
def test_parse_ints_not_enough_parameters(self): with self.assertRaisesRegex( MacroParsingError, re.escape("Not enough parameters (expected 4): '1,2,$3'")): parse_ints('1,2,$3', num=4)
def test_parse_ints_unknown_kwarg(self): with self.assertRaisesRegexp(MacroParsingError, "Unknown keyword argument: 'qux=2'"): parse_ints('foo=1,qux=2', names=('foo', 'bar'))
def test_parse_ints_not_enough_parameters(self): with self.assertRaisesRegexp(MacroParsingError, re.escape("Not enough parameters (expected 4): '1,2,$3'")): parse_ints('1,2,$3', num=4)