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