Skip to content

Commit c4963fd

Browse files
committed
Add tests
1 parent 7da9794 commit c4963fd

File tree

2 files changed

+170
-6
lines changed

2 files changed

+170
-6
lines changed

pkgs/yaml/test/utils.dart

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
import 'package:test/test.dart';
99
import 'package:yaml/src/equality.dart' as equality;
10+
import 'package:yaml/src/scanner.dart';
11+
import 'package:yaml/src/token.dart';
1012
import 'package:yaml/yaml.dart';
1113

1214
/// A matcher that validates that a closure or Future throws a [YamlException].
@@ -93,3 +95,34 @@ String indentLiteral(String text) {
9395

9496
return lines.join('\n');
9597
}
98+
99+
/// Generates tokens that can be consumed by a yaml parser.
100+
Iterable<Token> generateTokens(String source) sync* {
101+
final scanner = Scanner(source);
102+
103+
do {
104+
if (scanner.peek() case Token token) {
105+
yield token;
106+
scanner.advance();
107+
continue;
108+
}
109+
110+
break;
111+
} while (true);
112+
}
113+
114+
/// Matches a [TagDirectiveToken] emitted by a [Scanner]
115+
Matcher isATagDirective(String handle, String prefix) =>
116+
isA<TagDirectiveToken>()
117+
.having((t) => t.handle, 'handle', equals(handle))
118+
.having((t) => t.prefix, 'prefix', equals(prefix));
119+
120+
extension PadUtil on String {
121+
/// Applies an indent of 8 spaces to a multiline string to ensure strings
122+
/// are compatible with existing matchers.
123+
///
124+
/// See [cleanUpLiteral].
125+
String asIndented() => split('\n')
126+
.map((line) => line.isEmpty ? line : '${' ' * 8}$line')
127+
.join('\n');
128+
}

pkgs/yaml/test/yaml_test.dart

Lines changed: 137 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import 'package:test/test.dart';
1111
import 'package:yaml/src/error_listener.dart';
12+
import 'package:yaml/src/token.dart';
1213
import 'package:yaml/yaml.dart';
1314

1415
import 'utils.dart';
@@ -1030,8 +1031,90 @@ void main() {
10301031
bar''');
10311032
});
10321033

1033-
// Examples 6.18 through 6.22 test custom tag URIs, which this
1034-
// implementation currently doesn't plan to support.
1034+
// Examples 6.18 through 6.22 test custom tag URIs. Inspect the lower level
1035+
// event generator to check correctness of the tag directives we parse
1036+
// (and ignore?)
1037+
test('[Example 6.18]', () {
1038+
const source = '''
1039+
# Global
1040+
%TAG ! tag:example.com,2000:app/
1041+
---
1042+
!foo "bar"
1043+
''';
1044+
1045+
expect(
1046+
generateTokens(source),
1047+
anyElement(isATagDirective('!', 'tag:example.com,2000:app/')),
1048+
);
1049+
1050+
expectYamlLoads('bar', source.asIndented());
1051+
});
1052+
1053+
test('[Example 6.19]', () {
1054+
const source = '''
1055+
%TAG !! tag:example.com,2000:app/
1056+
---
1057+
!!int 1 - 3 # Interval, not integer
1058+
''';
1059+
1060+
expect(
1061+
generateTokens(source),
1062+
anyElement(isATagDirective('!!', 'tag:example.com,2000:app/')),
1063+
);
1064+
1065+
expectYamlLoads('1 - 3', source.asIndented());
1066+
});
1067+
1068+
test('[Example 6.20]', () {
1069+
const source = '''
1070+
%TAG !e! tag:example.com,2000:app/
1071+
---
1072+
!e!foo "bar"
1073+
''';
1074+
1075+
expect(
1076+
generateTokens(source),
1077+
anyElement(isATagDirective('!e!', 'tag:example.com,2000:app/')),
1078+
);
1079+
1080+
expectYamlLoads('bar', source.asIndented());
1081+
});
1082+
1083+
test('[Example 6.21]', () {
1084+
const source = '''
1085+
%TAG !m! !my-
1086+
--- # Bulb here
1087+
!m!light fluorescent
1088+
...
1089+
%TAG !m! !my-
1090+
--- # Color here
1091+
!m!light green
1092+
''';
1093+
1094+
expect(
1095+
generateTokens(source).whereType<TagDirectiveToken>(),
1096+
1097+
// Two different documents. Same directive
1098+
everyElement(isATagDirective('!m!', '!my-')),
1099+
);
1100+
1101+
expectYamlStreamLoads(['fluorescent', 'green'], source.asIndented());
1102+
});
1103+
1104+
test('[Example 6.22]', () {
1105+
const source = '''
1106+
%TAG !e! tag:example.com,2000:app/
1107+
---
1108+
- !e!foo "bar"
1109+
''';
1110+
1111+
expect(
1112+
generateTokens(source),
1113+
anyElement(isATagDirective('!e!', 'tag:example.com,2000:app/')),
1114+
);
1115+
1116+
expectYamlLoads(['bar'], source.asIndented());
1117+
});
10351118
});
10361119

10371120
group('6.9: Node Properties', () {
@@ -1048,16 +1131,37 @@ void main() {
10481131
&a2 baz : *a1''');
10491132
});
10501133

1051-
// Example 6.24 tests custom tag URIs, which this implementation currently
1052-
// doesn't plan to support.
1134+
test('[Example 6.24]', () {
1135+
expectYamlLoads({'foo': 'baz'}, '''
1136+
!<tag:yaml.org,2002:str> foo :
1137+
!<!bar> baz''');
1138+
});
10531139

10541140
test('[Example 6.25]', () {
10551141
expectYamlFails('- !<!> foo');
10561142
expectYamlFails('- !<\$:?> foo');
10571143
});
10581144

1059-
// Examples 6.26 and 6.27 test custom tag URIs, which this implementation
1060-
// currently doesn't plan to support.
1145+
test('[Example 6.26]', () {
1146+
expectYamlLoads(['foo', 'bar', 'baz'], '''
1147+
%TAG !e! tag:example.com,2000:app/
1148+
---
1149+
- !local foo
1150+
- !!str bar
1151+
- !e!tag%21 baz''');
1152+
});
1153+
1154+
test('[Example 6.27]', () {
1155+
expectYamlFails('''
1156+
%TAG !e! tag:example,2000:app/
1157+
---
1158+
- !e! foo''');
1159+
1160+
expectYamlFails('''
1161+
%TAG !e! tag:example,2000:app/
1162+
---
1163+
- !h!bar foo''');
1164+
});
10611165

10621166
test('[Example 6.28]', () {
10631167
expectYamlLoads(['12', 12, '12'], '''
@@ -1073,6 +1177,33 @@ void main() {
10731177
First occurrence: &anchor Value
10741178
Second occurrence: *anchor''');
10751179
});
1180+
1181+
// Custom & verbatim tags should nudge parser to a load node as a generic
1182+
// kind.
1183+
test('Represents scalars partially as strings', () {
1184+
expectYamlLoads(['3', 'false', '3.10'], '''
1185+
%TAG !! !no-type
1186+
%TAG !isA! !generic-kind
1187+
---
1188+
- !!int 3
1189+
- !isA!bool false
1190+
- !<!generic> 3.10''');
1191+
});
1192+
1193+
test('Composes collections completely', () {
1194+
expectYamlLoads([
1195+
<Object?, Object?>{},
1196+
<Object?>[],
1197+
['list']
1198+
], '''
1199+
%TAG !! !no-type
1200+
%TAG !isA! !generic-kind
1201+
---
1202+
- !!map {}
1203+
- !isA!list []
1204+
- !<!generic>
1205+
- list''');
1206+
});
10761207
});
10771208

10781209
// Chapter 7: Flow Styles

0 commit comments

Comments
 (0)