Files
agent-orchestrator-benchmark/calculators/builder-adversary/run-04/calc/test_lexer.py

104 lines
3.3 KiB
Python

import unittest
from calc.lexer import tokenize, Token, LexError
def kinds(src):
return [t.kind for t in tokenize(src)]
def kv(src):
return [(t.kind, t.value) for t in tokenize(src)]
class TestNumbers(unittest.TestCase):
def test_integer(self):
toks = tokenize("42")
self.assertEqual(toks, [Token('NUMBER', 42), Token('EOF', None)])
self.assertIsInstance(toks[0].value, int)
def test_float_standard(self):
toks = tokenize("3.14")
self.assertEqual(toks, [Token('NUMBER', 3.14), Token('EOF', None)])
self.assertIsInstance(toks[0].value, float)
def test_float_leading_dot(self):
toks = tokenize(".5")
self.assertAlmostEqual(toks[0].value, 0.5)
self.assertIsInstance(toks[0].value, float)
def test_float_trailing_dot(self):
toks = tokenize("10.")
self.assertAlmostEqual(toks[0].value, 10.0)
self.assertIsInstance(toks[0].value, float)
def test_zero(self):
toks = tokenize("0")
self.assertEqual(toks[0], Token('NUMBER', 0))
self.assertIsInstance(toks[0].value, int)
class TestOperatorsAndParens(unittest.TestCase):
def test_all_ops(self):
self.assertEqual(kinds("+-*/()"), ['PLUS','MINUS','STAR','SLASH','LPAREN','RPAREN','EOF'])
def test_expression(self):
self.assertEqual(kinds("1+2*3"), ['NUMBER','PLUS','NUMBER','STAR','NUMBER','EOF'])
def test_values_preserved(self):
self.assertEqual([t.value for t in tokenize("1+2*3")], [1, '+', 2, '*', 3, None])
def test_parens(self):
self.assertEqual(kinds("(1+2)"), ['LPAREN','NUMBER','PLUS','NUMBER','RPAREN','EOF'])
class TestWhitespaceAndErrors(unittest.TestCase):
def test_spaces_between(self):
self.assertEqual(kinds(" 12 + 3 "), ['NUMBER','PLUS','NUMBER','EOF'])
vals = [t.value for t in tokenize(" 12 + 3 ")]
self.assertEqual(vals, [12, '+', 3, None])
def test_complex_expr(self):
toks = tokenize("3.5*(1-2)")
expected_kinds = ['NUMBER','STAR','LPAREN','NUMBER','MINUS','NUMBER','RPAREN','EOF']
self.assertEqual([t.kind for t in toks], expected_kinds)
self.assertAlmostEqual(toks[0].value, 3.5)
def test_tabs(self):
self.assertEqual(kinds("1\t+\t2"), ['NUMBER','PLUS','NUMBER','EOF'])
def test_at_raises(self):
with self.assertRaises(LexError) as ctx:
tokenize("1 @ 2")
self.assertIn('@', str(ctx.exception))
def test_dollar_raises(self):
with self.assertRaises(LexError):
tokenize("$5")
def test_letter_raises(self):
with self.assertRaises(LexError) as ctx:
tokenize("1 x 2")
self.assertIn('x', str(ctx.exception))
def test_error_position_in_message(self):
try:
tokenize("1 @ 2")
except LexError as e:
self.assertIn('2', str(e)) # position 2
def test_malformed_float_raises_lex_error(self):
with self.assertRaises(LexError):
tokenize("..")
def test_malformed_float_multiple_dots_raises_lex_error(self):
with self.assertRaises(LexError):
tokenize("1.2.3")
def test_bare_dot_raises_lex_error(self):
with self.assertRaises(LexError):
tokenize(".")
if __name__ == '__main__':
unittest.main()