| OLD | NEW |
| (Empty) |
| 1 /// This package contains matches to write tests for parsers. | |
| 2 /// | |
| 3 /// Examples: | |
| 4 /// | |
| 5 /// var json = new JsonParser(); | |
| 6 /// | |
| 7 /// // verifies that the input gets parsed and all input is consumed | |
| 8 /// expect('{"a": 1}', accepts(new JsonParser())); | |
| 9 /// | |
| 10 /// // verifies that the input gets parsed to a dictionary and that all inpu
t is consumed | |
| 11 /// expect('{"a": 1}', parses(new JsonParser(), {'a': 1})); | |
| 12 | |
| 13 library petitparser.test_util; | |
| 14 | |
| 15 import 'package:matcher/matcher.dart'; | |
| 16 import 'package:petitparser/petitparser.dart' hide predicate; | |
| 17 | |
| 18 /// Returns a matcher that succeeds if the [parser] accepts the input. | |
| 19 Matcher accept(Parser parser) { | |
| 20 return parse(parser, predicate((value) => true, 'input')); | |
| 21 } | |
| 22 | |
| 23 /// Returns a matcher that succeeds if the [parser] succeeds and accepts the pro
vided [matcher]. | |
| 24 Matcher parse(Parser parser, matcher, [int position = -1]) { | |
| 25 return new _Parse(parser, wrapMatcher(matcher), position); | |
| 26 } | |
| 27 | |
| 28 class _Parse extends Matcher { | |
| 29 | |
| 30 final Parser parser; | |
| 31 final Matcher matcher; | |
| 32 final int position; | |
| 33 | |
| 34 _Parse(this.parser, this.matcher, this.position); | |
| 35 | |
| 36 @override | |
| 37 bool matches(item, Map matchState) { | |
| 38 Result result = parser.parse(item); | |
| 39 if (result.isFailure) { | |
| 40 addStateInfo(matchState, {'reason': 'failure', 'result': result}); | |
| 41 return false; | |
| 42 } | |
| 43 if (!matcher.matches(result.value, matchState)) { | |
| 44 addStateInfo(matchState, {'reason': 'matcher', 'result': result}); | |
| 45 return false; | |
| 46 } | |
| 47 if (position >= 0 && position != result.value) { | |
| 48 addStateInfo(matchState, {'reason': 'position', 'result': result}); | |
| 49 return false; | |
| 50 } | |
| 51 return true; | |
| 52 } | |
| 53 | |
| 54 @override | |
| 55 Description describe(Description description) { | |
| 56 return description.add('"$parser" accepts ').addDescriptionOf(matcher); | |
| 57 } | |
| 58 | |
| 59 @override | |
| 60 Description describeMismatch(item, Description description, Map matchState, bo
ol verbose) { | |
| 61 description.add('"$parser" produces "${matchState['result']}"'); | |
| 62 switch (matchState['reason']) { | |
| 63 case 'failure': | |
| 64 description.add(' which is not accepted'); | |
| 65 return description; | |
| 66 case 'matcher': | |
| 67 description.add(' which parse result '); | |
| 68 var subDescription = new StringDescription(); | |
| 69 matcher.describeMismatch(matchState['result'].value, subDescription, | |
| 70 matchState['state'], verbose); | |
| 71 if (subDescription.length > 0) { | |
| 72 description.add(subDescription.toString()); | |
| 73 } else { | |
| 74 description.add('doesn\'t match'); | |
| 75 matcher.describe(description); | |
| 76 } | |
| 77 return description; | |
| 78 case 'position': | |
| 79 description | |
| 80 .add(' that consumes input to ') | |
| 81 .add(matchState['result'].position.toString()) | |
| 82 .add(' instead of ') | |
| 83 .add(position.toString()); | |
| 84 return description; | |
| 85 } | |
| 86 throw new Exception('Internal matcher error'); | |
| 87 } | |
| 88 } | |
| OLD | NEW |