import 'package:petitparser/petitparser.dart'; import 'package:test/test.dart'; import 'utils/matchers.dart'; void main() { final identifier = letter().seq(word().star()).flatten(); final number = char('-') .optional() .seq(digit().plus()) .seq(char('.').seq(digit().plus()).optional()) .flatten(); final quoted = char('"').seq(char('"').neg().star()).seq(char('"')).flatten(); final keyword = string('return') .seq(whitespace().plus().flatten()) .seq(identifier.or(number).or(quoted)) .map((list) => list.last); final javadoc = string( '/**', ).seq(string('*/').neg().star()).seq(string('*/')).flatten(); final multiLine = string('"""') .seq((string(r'\"""') | any()).starLazy(string('"""')).flatten()) .seq(string('"""')) .pick(1); test('valid identifier', () { expect(identifier, isParseSuccess('a', result: 'a')); expect(identifier, isParseSuccess('a1', result: 'a1')); expect(identifier, isParseSuccess('a12', result: 'a12')); expect(identifier, isParseSuccess('ab', result: 'ab')); expect(identifier, isParseSuccess('a1b', result: 'a1b')); }); test('incomplete identifier', () { expect(identifier, isParseSuccess('a=', result: 'a', position: 1)); expect(identifier, isParseSuccess('a1-', result: 'a1', position: 2)); expect(identifier, isParseSuccess('a12+', result: 'a12', position: 3)); expect(identifier, isParseSuccess('ab ', result: 'ab', position: 2)); }); test('invalid identifier', () { expect(identifier, isParseFailure('', message: 'letter expected')); expect(identifier, isParseFailure('1', message: 'letter expected')); expect(identifier, isParseFailure('1a', message: 'letter expected')); }); test('positive number', () { expect(number, isParseSuccess('1', result: '1')); expect(number, isParseSuccess('12', result: '12')); expect(number, isParseSuccess('12.3', result: '12.3')); expect(number, isParseSuccess('12.34', result: '12.34')); }); test('negative number', () { expect(number, isParseSuccess('-1', result: '-1')); expect(number, isParseSuccess('-12', result: '-12')); expect(number, isParseSuccess('-12.3', result: '-12.3')); expect(number, isParseSuccess('-12.34', result: '-12.34')); }); test('incomplete number', () { expect(number, isParseSuccess('1..', result: '1', position: 1)); expect(number, isParseSuccess('12-', result: '12', position: 2)); expect(number, isParseSuccess('12.3.', result: '12.3', position: 4)); expect(number, isParseSuccess('12.34.', result: '12.34', position: 5)); }); test('invalid number', () { expect(number, isParseFailure('', position: 0, message: 'digit expected')); expect(number, isParseFailure('-', position: 1, message: 'digit expected')); expect( number, isParseFailure('-x', position: 1, message: 'digit expected'), ); expect(number, isParseFailure('.', message: 'digit expected')); expect(number, isParseFailure('.1', message: 'digit expected')); }); test('valid string', () { expect(quoted, isParseSuccess('""', result: '""')); expect(quoted, isParseSuccess('"a"', result: '"a"')); expect(quoted, isParseSuccess('"ab"', result: '"ab"')); expect(quoted, isParseSuccess('"abc"', result: '"abc"')); }); test('incomplete string', () { expect(quoted, isParseSuccess('""x', result: '""', position: 2)); expect(quoted, isParseSuccess('"a"x', result: '"a"', position: 3)); expect(quoted, isParseSuccess('"ab"x', result: '"ab"', position: 4)); expect(quoted, isParseSuccess('"abc"x', result: '"abc"', position: 5)); }); test('invalid string', () { expect(quoted, isParseFailure('"', position: 1, message: '"\\"" expected')); expect( quoted, isParseFailure('"a', position: 2, message: '"\\"" expected'), ); expect( quoted, isParseFailure('"ab', position: 3, message: '"\\"" expected'), ); expect(quoted, isParseFailure('a"', message: '"\\"" expected')); expect(quoted, isParseFailure('ab"', message: '"\\"" expected')); }); test('return statement', () { expect(keyword, isParseSuccess('return f', result: 'f')); expect(keyword, isParseSuccess('return f', result: 'f')); expect(keyword, isParseSuccess('return foo', result: 'foo')); expect(keyword, isParseSuccess('return foo', result: 'foo')); expect(keyword, isParseSuccess('return 1', result: '1')); expect(keyword, isParseSuccess('return 1', result: '1')); expect(keyword, isParseSuccess('return -2.3', result: '-2.3')); expect(keyword, isParseSuccess('return -2.3', result: '-2.3')); expect(keyword, isParseSuccess('return "a"', result: '"a"')); expect(keyword, isParseSuccess('return "a"', result: '"a"')); }); test('invalid statement', () { expect(keyword, isParseFailure('retur f', message: '"return" expected')); expect( keyword, isParseFailure('return1', position: 6, message: 'whitespace expected'), ); expect( keyword, isParseFailure('return _', position: 8, message: '"\\"" expected'), ); }); test('javadoc', () { expect(javadoc, isParseSuccess('/** foo */', result: '/** foo */')); expect(javadoc, isParseSuccess('/** * * */', result: '/** * * */')); }); test('multiline', () { expect(multiLine, isParseSuccess(r'"""abc"""', result: r'abc')); expect(multiLine, isParseSuccess(r'"""abc\n"""', result: r'abc\n')); expect( multiLine, isParseSuccess(r'"""abc\"""def"""', result: r'abc\"""def'), ); }); }