OLD | NEW |
| (Empty) |
1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE.md file. | |
4 | |
5 /// Messages used by fletch_test_suite.dart to communicate with test.py. | |
6 library fletch_tests.messages; | |
7 | |
8 import 'dart:convert' show | |
9 JSON; | |
10 | |
11 import 'dart:io' as io show stdout; | |
12 | |
13 import 'dart:async' show | |
14 StreamTransformer; | |
15 | |
16 StreamTransformer<String, Message> get messageTransformer { | |
17 return new StreamTransformer<String, Message> | |
18 .fromHandlers(handleData: (String line, Sink<Message> sink) { | |
19 sink.add(new Message.fromJson(line)); | |
20 }); | |
21 } | |
22 | |
23 abstract class Message { | |
24 const Message(); | |
25 | |
26 factory Message.fromJson(String json) { | |
27 Map<String, dynamic> data = JSON.decode(json); | |
28 String type = data['type']; | |
29 switch (type) { | |
30 case 'InternalErrorMessage': | |
31 return new InternalErrorMessage.fromJsonData(data); | |
32 | |
33 case 'Info': return new Info.fromJsonData(data); | |
34 case 'ListTests': return const ListTests(); | |
35 case 'ListTestsReply': return new ListTestsReply.fromJsonData(data); | |
36 case 'RunTest': return new RunTest.fromJsonData(data); | |
37 case 'TimedOut': return new TimedOut.fromJsonData(data); | |
38 case 'TestFailed': return new TestFailed.fromJsonData(data); | |
39 case 'TestPassed': return new TestPassed.fromJsonData(data); | |
40 case 'TestStdoutLine': return new TestStdoutLine.fromJsonData(data); | |
41 } | |
42 | |
43 throw "Unknown message: $type"; | |
44 } | |
45 | |
46 String get type; | |
47 | |
48 String toString() => "$type()"; | |
49 | |
50 Map<String, dynamic> toJson() => <String, dynamic>{'type': type}; | |
51 | |
52 void addTo(StringSink sink) { | |
53 sink.writeln(JSON.encode(this)); | |
54 } | |
55 } | |
56 | |
57 /// Notify that an error occurred. | |
58 abstract class ErrorMessage extends Message { | |
59 final String error; | |
60 | |
61 final String stackTrace; | |
62 | |
63 const ErrorMessage(this.error, this.stackTrace); | |
64 | |
65 ErrorMessage.fromJsonData(Map<String, dynamic> data) | |
66 : this(data['error'], data['stackTrace']); | |
67 | |
68 Map<String, dynamic> toJson() { | |
69 Map<String, dynamic> result = super.toJson(); | |
70 result['error'] = '$error'; | |
71 result['stackTrace'] = stackTrace == null ? null : '$stackTrace'; | |
72 return result; | |
73 } | |
74 | |
75 String toString() => "$type($error,$stackTrace)"; | |
76 } | |
77 | |
78 /// Notify that an internal error occurred in this framework (there's a bug in | |
79 /// the framework). | |
80 class InternalErrorMessage extends ErrorMessage { | |
81 const InternalErrorMessage(String error, String stackTrace) | |
82 : super(error, stackTrace); | |
83 | |
84 InternalErrorMessage.fromJsonData(Map<String, dynamic> data) | |
85 : super.fromJsonData(data); | |
86 | |
87 String get type => 'InternalErrorMessage'; | |
88 } | |
89 | |
90 /// Request a listing of all tests. | |
91 class ListTests extends Message { | |
92 const ListTests(); | |
93 | |
94 String get type => 'ListTests'; | |
95 } | |
96 | |
97 /// List of all tests (the response to [ListTests]). | |
98 class ListTestsReply extends Message { | |
99 final List<String> tests; | |
100 | |
101 const ListTestsReply(this.tests); | |
102 | |
103 ListTestsReply.fromJsonData(Map<String, dynamic> data) | |
104 : this(data['tests']); | |
105 | |
106 String get type => 'ListTestsReply'; | |
107 | |
108 Map<String, dynamic> toJson() { | |
109 Map<String, dynamic> result = super.toJson(); | |
110 result['tests'] = tests; | |
111 return result; | |
112 } | |
113 | |
114 String toString() => "$type($tests)"; | |
115 } | |
116 | |
117 /// Abstract message with a name. | |
118 abstract class NamedMessage extends Message { | |
119 final String name; | |
120 | |
121 const NamedMessage(this.name); | |
122 | |
123 NamedMessage.fromJsonData(Map<String, dynamic> data) | |
124 : this(data['name']); | |
125 | |
126 Map<String, dynamic> toJson() { | |
127 Map<String, dynamic> result = super.toJson(); | |
128 result['name'] = name; | |
129 return result; | |
130 } | |
131 | |
132 String toString() => "$type($name)"; | |
133 } | |
134 | |
135 /// Request that test [name] is run. | |
136 class RunTest extends NamedMessage { | |
137 const RunTest(String name) | |
138 : super(name); | |
139 | |
140 RunTest.fromJsonData(Map<String, dynamic> data) | |
141 : super.fromJsonData(data); | |
142 | |
143 String get type => 'RunTest'; | |
144 } | |
145 | |
146 /// Notify that test [name] timed out. | |
147 /// | |
148 /// This message is bi-directional, it is used by test.dart to tell | |
149 /// fletch_test_suite.dart that a test has timed out, as well as by | |
150 /// fletch_test_suite.dart to tell test.dart that the test did in fact time out | |
151 /// (due to interprocess communication, and lack of synchronization, it is | |
152 /// possible for a test to complete normally before it is terminated). | |
153 class TimedOut extends NamedMessage { | |
154 const TimedOut(String name) | |
155 : super(name); | |
156 | |
157 TimedOut.fromJsonData(Map<String, dynamic> data) | |
158 : super.fromJsonData(data); | |
159 | |
160 String get type => 'TimedOut'; | |
161 } | |
162 | |
163 /// Test [name] failed. A possible reply to [RunTest]. | |
164 class TestFailed extends ErrorMessage implements NamedMessage { | |
165 final String name; | |
166 | |
167 const TestFailed(this.name, String error, String stackTrace) | |
168 : super(error, stackTrace); | |
169 | |
170 TestFailed.fromJsonData(Map<String, dynamic> data) | |
171 : this(data['name'], data['error'], data['stackTrace']); | |
172 | |
173 String get type => 'TestFailed'; | |
174 | |
175 Map<String, dynamic> toJson() { | |
176 Map<String, dynamic> result = super.toJson(); | |
177 result['name'] = name; | |
178 return result; | |
179 } | |
180 | |
181 String toString() => "$type($name, $error, $stackTrace)"; | |
182 } | |
183 | |
184 /// Test [name] passed. A possible reply to [RunTest]. | |
185 class TestPassed extends NamedMessage { | |
186 const TestPassed(String name) | |
187 : super(name); | |
188 | |
189 TestPassed.fromJsonData(Map<String, dynamic> data) | |
190 : this(data['name']); | |
191 | |
192 String get type => 'TestPassed'; | |
193 } | |
194 | |
195 /// Debug information. | |
196 class Info extends Message { | |
197 final String data; | |
198 | |
199 const Info(this.data); | |
200 | |
201 Info.fromJsonData(Map<String, dynamic> data) | |
202 : this(data['data']); | |
203 | |
204 String get type => 'Info'; | |
205 | |
206 Map<String, dynamic> toJson() { | |
207 Map<String, dynamic> result = super.toJson(); | |
208 result['data'] = data; | |
209 return result; | |
210 } | |
211 | |
212 String toString() => "$type('$data')"; | |
213 } | |
214 | |
215 /// A line on stdout from test [name]. | |
216 class TestStdoutLine extends NamedMessage { | |
217 final String line; | |
218 | |
219 const TestStdoutLine(String name, this.line) | |
220 : super(name); | |
221 | |
222 TestStdoutLine.fromJsonData(Map<String, dynamic> data) | |
223 : this(data['name'], data['line']); | |
224 | |
225 String get type => 'TestStdoutLine'; | |
226 | |
227 Map<String, dynamic> toJson() { | |
228 Map<String, dynamic> result = super.toJson(); | |
229 result['line'] = line; | |
230 return result; | |
231 } | |
232 | |
233 String toString() => "$type($name, $line)"; | |
234 } | |
OLD | NEW |