@@ -7,6 +7,206 @@ import 'package:test/test.dart';
7
7
import 'mini_types.dart' ;
8
8
9
9
main () {
10
+ group ('parse' , () {
11
+ var throwsParseError = throwsA (TypeMatcher <ParseError >());
12
+
13
+ group ('non-function type:' , () {
14
+ test ('no type args' , () {
15
+ var t = Type ('int' ) as NonFunctionType ;
16
+ expect (t.name, 'int' );
17
+ expect (t.args, isEmpty);
18
+ });
19
+
20
+ test ('type arg' , () {
21
+ var t = Type ('List<int>' ) as NonFunctionType ;
22
+ expect (t.name, 'List' );
23
+ expect (t.args, hasLength (1 ));
24
+ expect (t.args[0 ].type, 'int' );
25
+ });
26
+
27
+ test ('type args' , () {
28
+ var t = Type ('Map<int, String>' ) as NonFunctionType ;
29
+ expect (t.name, 'Map' );
30
+ expect (t.args, hasLength (2 ));
31
+ expect (t.args[0 ].type, 'int' );
32
+ expect (t.args[1 ].type, 'String' );
33
+ });
34
+
35
+ test ('invalid type arg separator' , () {
36
+ expect (() => Type ('Map<int) String>' ), throwsParseError);
37
+ });
38
+ });
39
+
40
+ test ('invalid initial token' , () {
41
+ expect (() => Type ('<' ), throwsParseError);
42
+ });
43
+
44
+ test ('unknown type' , () {
45
+ var t = Type ('?' );
46
+ expect (t, TypeMatcher <UnknownType >());
47
+ });
48
+
49
+ test ('question type' , () {
50
+ var t = Type ('int?' ) as QuestionType ;
51
+ expect (t.innerType.type, 'int' );
52
+ });
53
+
54
+ test ('star type' , () {
55
+ var t = Type ('int*' ) as StarType ;
56
+ expect (t.innerType.type, 'int' );
57
+ });
58
+
59
+ test ('promoted type variable' , () {
60
+ var t = Type ('T&int' ) as PromotedTypeVariableType ;
61
+ expect (t.innerType.type, 'T' );
62
+ expect (t.promotion.type, 'int' );
63
+ });
64
+
65
+ test ('parenthesized type' , () {
66
+ var t = Type ('(int)' );
67
+ expect (t.type, 'int' );
68
+ });
69
+
70
+ test ('invalid token terminating parenthesized type' , () {
71
+ expect (() => Type ('(?<' ), throwsParseError);
72
+ });
73
+
74
+ group ('function type:' , () {
75
+ test ('no parameters' , () {
76
+ var t = Type ('int Function()' ) as FunctionType ;
77
+ expect (t.returnType.type, 'int' );
78
+ expect (t.positionalParameters, isEmpty);
79
+ });
80
+
81
+ test ('positional parameter' , () {
82
+ var t = Type ('int Function(String)' ) as FunctionType ;
83
+ expect (t.returnType.type, 'int' );
84
+ expect (t.positionalParameters, hasLength (1 ));
85
+ expect (t.positionalParameters[0 ].type, 'String' );
86
+ });
87
+
88
+ test ('positional parameters' , () {
89
+ var t = Type ('int Function(String, double)' ) as FunctionType ;
90
+ expect (t.returnType.type, 'int' );
91
+ expect (t.positionalParameters, hasLength (2 ));
92
+ expect (t.positionalParameters[0 ].type, 'String' );
93
+ expect (t.positionalParameters[1 ].type, 'double' );
94
+ });
95
+
96
+ test ('invalid parameter separator' , () {
97
+ expect (() => Type ('int Function(String Function()< double)' ),
98
+ throwsParseError);
99
+ });
100
+
101
+ test ('invalid token after Function' , () {
102
+ expect (() => Type ('int Function&)' ), throwsParseError);
103
+ });
104
+ });
105
+
106
+ group ('record type:' , () {
107
+ test ('no fields' , () {
108
+ var t = Type ('()' ) as RecordType ;
109
+ expect (t.positional, isEmpty);
110
+ expect (t.named, isEmpty);
111
+ });
112
+
113
+ test ('named field' , () {
114
+ var t = Type ('({int x})' ) as RecordType ;
115
+ expect (t.positional, isEmpty);
116
+ expect (t.named, hasLength (1 ));
117
+ expect (t.named[0 ].name, 'x' );
118
+ expect (t.named[0 ].type.type, 'int' );
119
+ });
120
+
121
+ test ('named field followed by comma' , () {
122
+ var t = Type ('({int x,})' ) as RecordType ;
123
+ expect (t.positional, isEmpty);
124
+ expect (t.named, hasLength (1 ));
125
+ expect (t.named[0 ].name, 'x' );
126
+ expect (t.named[0 ].type.type, 'int' );
127
+ });
128
+
129
+ test ('named field followed by invalid token' , () {
130
+ expect (() => Type ('({int x))' ), throwsParseError);
131
+ });
132
+
133
+ test ('named field name is not an identifier' , () {
134
+ expect (() => Type ('({int )})' ), throwsParseError);
135
+ });
136
+
137
+ test ('named fields' , () {
138
+ var t = Type ('({int x, String y})' ) as RecordType ;
139
+ expect (t.positional, isEmpty);
140
+ expect (t.named, hasLength (2 ));
141
+ expect (t.named[0 ].name, 'x' );
142
+ expect (t.named[0 ].type.type, 'int' );
143
+ expect (t.named[1 ].name, 'y' );
144
+ expect (t.named[1 ].type.type, 'String' );
145
+ });
146
+
147
+ test ('curly braces followed by invalid token' , () {
148
+ expect (() => Type ('({int x}&' ), throwsParseError);
149
+ });
150
+
151
+ test ('curly braces but no named fields' , () {
152
+ expect (() => Type ('({})' ), throwsParseError);
153
+ });
154
+
155
+ test ('positional field' , () {
156
+ var t = Type ('(int,)' ) as RecordType ;
157
+ expect (t.named, isEmpty);
158
+ expect (t.positional, hasLength (1 ));
159
+ expect (t.positional[0 ].type, 'int' );
160
+ });
161
+
162
+ group ('positional fields:' , () {
163
+ test ('two' , () {
164
+ var t = Type ('(int, String)' ) as RecordType ;
165
+ expect (t.named, isEmpty);
166
+ expect (t.positional, hasLength (2 ));
167
+ expect (t.positional[0 ].type, 'int' );
168
+ expect (t.positional[1 ].type, 'String' );
169
+ });
170
+
171
+ test ('three' , () {
172
+ var t = Type ('(int, String, double)' ) as RecordType ;
173
+ expect (t.named, isEmpty);
174
+ expect (t.positional, hasLength (3 ));
175
+ expect (t.positional[0 ].type, 'int' );
176
+ expect (t.positional[1 ].type, 'String' );
177
+ expect (t.positional[2 ].type, 'double' );
178
+ });
179
+ });
180
+
181
+ test ('named and positional fields' , () {
182
+ var t = Type ('(int, {String x})' ) as RecordType ;
183
+ expect (t.positional, hasLength (1 ));
184
+ expect (t.positional[0 ].type, 'int' );
185
+ expect (t.named, hasLength (1 ));
186
+ expect (t.named[0 ].name, 'x' );
187
+ expect (t.named[0 ].type.type, 'String' );
188
+ });
189
+
190
+ test ('terminated by invalid token' , () {
191
+ expect (() => Type ('(int, String(' ), throwsParseError);
192
+ });
193
+ });
194
+
195
+ group ('invalid token:' , () {
196
+ test ('before other tokens' , () {
197
+ expect (() => Type ('#int' ), throwsParseError);
198
+ });
199
+
200
+ test ('at end' , () {
201
+ expect (() => Type ('int#' ), throwsParseError);
202
+ });
203
+ });
204
+
205
+ test ('extra token after type' , () {
206
+ expect (() => Type ('int)' ), throwsParseError);
207
+ });
208
+ });
209
+
10
210
group ('recursivelyDemote:' , () {
11
211
group ('FunctionType:' , () {
12
212
group ('return type:' , () {
0 commit comments