def test_formattedReporting(self): """ Parse errors can be formatted into a nice human-readable view containing the erroneous input and possible fixes. """ g = self.compile( """ dig ::= '1' | '2' | '3' bits ::= <dig>+ """ ) input = "123x321" e = self.assertRaises(ParseError, g.bits, input) self.assertEqual( e.formatError(input), dedent( """ 123x321 ^ Parse error at line 1, column 3: expected one of '1', '3', or '2' """ ), ) input = "foo\nbaz\nboz\ncharlie\nbuz" e = ParseError(12, expected("token", "foo") + expected(None, "b")) self.assertEqual( e.formatError(input), dedent( """ charlie ^ Parse error at line 4, column 0: expected one of token 'foo', or 'b' """ ), ) input = "123x321" e = ParseError(3, expected("digit")) self.assertEqual( e.formatError(input), dedent( """ 123x321 ^ Parse error at line 1, column 3: expected a digit """ ), )
def test_orErrorTie(self): """ When branches of L{OMetaBase._or} produce errors that tie for rightmost position, they are merged. """ data = "foozle" o = OMetaBase(data) v, e = o._or([lambda: o.token("fog"), lambda: o.token("foz"), lambda: o.token("f")]) self.assertEqual(e[0], 2) self.assertEqual(e[1], [expected("token", "fog")[0], expected("token", "foz")[0]])
def test_digit(self): """ L{OMetaBase.rule_digit} matches digits. """ o = OMetaBase("1a") v, e = o.rule_digit() self.assertEqual((v, e), ("1", [0, None])) e = self.assertRaises(ParseError, o.rule_digit) self.assertEqual(e, ParseError(1, expected("digit")))
def test_tokenFailed(self): """ On failure, L{OMetaBase.rule_token} produces an error indicating the position where match failure occurred and the expected character. """ data = "foozle" o = OMetaBase(data) e = self.assertRaises(ParseError, o.rule_token, "fog") self.assertEqual(e[0], 2) self.assertEqual(e[1], expected("token", "fog"))
def test_many(self): """ L{OMetaBase.many} returns a list of parsed values and the error that caused the end of the loop. """ data = "ooops" o = OMetaBase(data) self.assertEqual(o.many(lambda: o.rule_exactly('o')), (['o'] * 3, _MaybeParseError(3, expected(None, 'o'))))
def test_letter(self): """ L{OMetaBase.rule_letter} matches letters. """ o = OMetaBase("a1") v, e = o.rule_letter() self.assertEqual((v, e), ("a", [0, None])) e = self.assertRaises(ParseError, o.rule_letter) self.assertEqual(e, ParseError(1, expected("letter")))
def test_letterOrDigit(self): """ L{OMetaBase.rule_letterOrDigit} matches alphanumerics. """ o = OMetaBase("a1@") v, e = o.rule_letterOrDigit() self.assertEqual((v, e), ("a", [0, None])) v, e = o.rule_letterOrDigit() self.assertEqual((v, e), ("1", [1, None])) e = self.assertRaises(ParseError, o.rule_letterOrDigit) self.assertEqual(e, ParseError(2, expected("letter or digit")))
def test_digit(self): """ L{OMetaBase.rule_digit} matches digits. """ o = OMetaBase("1a") v, e = o.rule_digit() self.assertEqual((v, e), ("1", [0, None])) try: o.rule_digit() except _MaybeParseError, e: self.assertEqual(e, _MaybeParseError(1, expected("digit")))
def test_exactlyFail(self): """ L{OMetaBase.rule_exactly} raises L{ParseError} when the requested item doesn't match the input. The error contains info on what was expected and the position. """ data = "foo" o = OMetaBase(data) e = self.assertRaises(ParseError, o.rule_exactly, "g") self.assertEquals(e[1], expected(None, "g")) self.assertEquals(e[0], 0)
def test_letter(self): """ L{OMetaBase.rule_letter} matches letters. """ o = OMetaBase("a1") v, e = o.rule_letter() self.assertEqual((v, e), ("a", [0, None])) try: o.rule_letter() except _MaybeParseError, e: self.assertEqual(e, _MaybeParseError(1, expected("letter")))
def test_formattedReporting(self): """ Parse errors can be formatted into a nice human-readable view containing the erroneous input and possible fixes. """ g = self.compile(""" dig ::= '1' | '2' | '3' bits ::= <dig>+ """) input = "123x321" e = self.assertRaises(ParseError, g.bits, input) self.assertEqual( e.formatError(input), dedent(""" 123x321 ^ Parse error at line 1, column 3: expected one of '1', '3', or '2' """)) input = "foo\nbaz\nboz\ncharlie\nbuz" e = ParseError(12, expected('token', 'foo') + expected(None, 'b')) self.assertEqual( e.formatError(input), dedent(""" charlie ^ Parse error at line 4, column 0: expected one of token 'foo', or 'b' """)) input = '123x321' e = ParseError(3, expected('digit')) self.assertEqual( e.formatError(input), dedent(""" 123x321 ^ Parse error at line 1, column 3: expected a digit """))
def test_letterOrDigit(self): """ L{OMetaBase.rule_letterOrDigit} matches alphanumerics. """ o = OMetaBase("a1@") v, e = o.rule_letterOrDigit() self.assertEqual((v, e), ("a", [0, None])) v, e = o.rule_letterOrDigit() self.assertEqual((v, e), ("1", [1, None])) try: o.rule_letterOrDigit() except _MaybeParseError, e: self.assertEqual(e, _MaybeParseError(2, expected("letter or digit")))
def test_digit(self): """ L{OMetaBase.rule_digit} matches digits. """ o = OMetaBase("1a") v, e = o.rule_digit() self.assertEqual((v, e), ("1", [0, None])) try: o.rule_digit() except _MaybeParseError as e: self.assertEqual(e, _MaybeParseError(1, expected("digit"))) else: self.fail('_MaybeParseError not raised')
def test_tokenFailed(self): """ On failure, L{OMetaBase.rule_token} produces an error indicating the position where match failure occurred and the expected character. """ data = "foozle" o = OMetaBase(data) try: o.rule_token('fog') except _MaybeParseError as e: self.assertEqual(e[0], 2) self.assertEqual(e[1], expected("token", "fog")) else: self.fail('_MaybeParseError not raised')
def test_letter(self): """ L{OMetaBase.rule_letter} matches letters. """ o = OMetaBase("a1") v, e = o.rule_letter() self.assertEqual((v, e), ("a", [0, None])) try: o.rule_letter() except _MaybeParseError as e: self.assertEqual(e, _MaybeParseError(1, expected("letter"))) else: self.fail('_MaybeParseError not raised')
def test_orFalseSuccess(self): """ When a failing branch of L{OMetaBase._or} gets further than a succeeding one, its error is returned instead of the success branch's. """ data = "foozle" o = OMetaBase(data) v, e = o._or([lambda: o.token("fog"), lambda: o.token("foozik"), lambda: o.token("f")]) self.assertEqual(e[0], 4) self.assertEqual(e[1], expected("token", "foozik"))
def TODO_test_keywordFailed(self): """ On failure, L{OMetaBase.rule_keyword} produces an error indicating the position where match failure occurred and the expected character. """ data = "foozle" o = OMetaBase(data) try: o.rule_keyword('foo') except _MaybeParseError, e: self.assertEqual(e[0], 4) self.assertEqual(e[1], expected("keyword", "foo")) self.assertEqual(o.input.position, 0) self.assertEqual(o.input.head()[0], 'f')
def test_orSimpleFailure(self): """ When none of the alternatives passed to L{OMetaBase._or} succeed, the one that got the furthest is returned. """ data = "foozle" o = OMetaBase(data) e = self.assertRaises(ParseError, o._or, [lambda: o.token("fog"), lambda: o.token("foozik"), lambda: o.token("woozle")]) self.assertEqual(e[0], 4) self.assertEqual(e[1], expected("token", "foozik"))
def test_letterOrDigit(self): """ L{OMetaBase.rule_letterOrDigit} matches alphanumerics. """ o = OMetaBase("a1@") v, e = o.rule_letterOrDigit() self.assertEqual((v, e), ("a", [0, None])) v, e = o.rule_letterOrDigit() self.assertEqual((v, e), ("1", [1, None])) try: o.rule_letterOrDigit() except _MaybeParseError as e: self.assertEqual(e, _MaybeParseError(2, expected("letter or digit"))) else: self.fail('_MaybeParseError not raised')
def test_orSimpleFailure(self): """ When none of the alternatives passed to L{OMetaBase._or} succeed, the one that got the furthest is returned. """ data = "foozle" o = OMetaBase(data) e = self.assertRaises(ParseError, o._or, [ lambda: o.token("fog"), lambda: o.token("foozik"), lambda: o.token("woozle") ]) self.assertEqual(e[0], 4) self.assertEqual(e[1], expected("token", "foozik"))
def applicationArgs(self): args = [] while True: try: (arg, endchar), err = self.pythonExpr(" >") if not arg: break args.append(self.builder.expr(arg)) if endchar == '>': break except ParseError: break if args: return args else: raise ParseError(self.input.position, expected("python expression"))
def test_exactlyFail(self): """ L{OMetaBase.rule_exactly} raises L{_MaybeParseError} when the requested item doesn't match the input. The error contains info on what was expected and the position. """ data = "foo" o = OMetaBase(data) try: o.rule_exactly("g") except _MaybeParseError as e: self.assertEquals(e[1], expected(None, "g")) self.assertEquals(e[0], 0) else: self.fail('_MaybeParseError not raised')
def test_exactlyFail(self): """ L{OMetaBase.rule_exactly} raises L{_MaybeParseError} when the requested item doesn't match the input. The error contains info on what was expected and the position. """ data = "foo" o = OMetaBase(data) try: o.rule_exactly("g") except _MaybeParseError as e: self.assertEqual(e[1], expected(None, "g")) self.assertEqual(e[0], 0) else: self.fail('_MaybeParseError not raised')
def test_orSimpleFailure(self): """ When none of the alternatives passed to L{OMetaBase._or} succeed, the one that got the furthest is returned. """ data = "foozle" o = OMetaBase(data) try: o._or([lambda: o.token("fog"), lambda: o.token("foozik"), lambda: o.token("woozle")]) except _MaybeParseError as e: self.assertEqual(e[0], 4) self.assertEqual(e[1], expected("token", "foozik")) else: self.fail('_MaybeParseError not raised')