Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(646)

Side by Side Diff: pkg/testing/lib/src/chain.dart

Issue 2623413003: Implement custom status file expectations. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE.md file.
4 4
5 library testing.chain; 5 library testing.chain;
6 6
7 import 'dart:async' show 7 import 'dart:async' show
8 Future, 8 Future,
9 Stream; 9 Stream;
10 10
11 import 'dart:convert' show 11 import 'dart:convert' show
12 JSON, 12 JSON,
13 JsonEncoder; 13 JsonEncoder;
14 14
15 import 'dart:io' show 15 import 'dart:io' show
16 Directory, 16 Directory,
17 File, 17 File,
18 FileSystemEntity, 18 FileSystemEntity,
19 exitCode; 19 exitCode;
20 20
21 import 'suite.dart' show 21 import 'suite.dart' show
22 Suite; 22 Suite;
23 23
24 import '../testing.dart' show 24 import '../testing.dart' show
25 TestDescription; 25 TestDescription;
26 26
27 import 'test_dart/status_file_parser.dart' show 27 import 'test_dart/status_file_parser.dart' show
28 Expectation,
29 ReadTestExpectations, 28 ReadTestExpectations,
30 TestExpectations; 29 TestExpectations;
31 30
32 import 'zone_helper.dart' show 31 import 'zone_helper.dart' show
33 runGuarded; 32 runGuarded;
34 33
35 import 'error_handling.dart' show 34 import 'error_handling.dart' show
36 withErrorHandling; 35 withErrorHandling;
37 36
38 import 'log.dart' show 37 import 'log.dart' show
39 logMessage, 38 logMessage,
40 logStepComplete, 39 logStepComplete,
41 logStepStart, 40 logStepStart,
42 logSuiteComplete, 41 logSuiteComplete,
43 logTestComplete, 42 logTestComplete,
44 logUnexpectedResult, 43 logUnexpectedResult,
45 splitLines; 44 splitLines;
46 45
47 import 'multitest.dart' show 46 import 'multitest.dart' show
48 MultitestTransformer, 47 MultitestTransformer,
49 isError; 48 isError;
50 49
50 import 'expectation.dart' show
51 Expectation,
52 ExpectationSet;
53
51 typedef Future<ChainContext> CreateContext( 54 typedef Future<ChainContext> CreateContext(
52 Chain suite, Map<String, String> environment); 55 Chain suite, Map<String, String> environment);
53 56
54 /// A test suite for tool chains, for example, a compiler. 57 /// A test suite for tool chains, for example, a compiler.
55 class Chain extends Suite { 58 class Chain extends Suite {
56 final Uri source; 59 final Uri source;
57 60
58 final Uri uri; 61 final Uri uri;
59 62
60 final List<RegExp> pattern; 63 final List<RegExp> pattern;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 "exclude": []..addAll(exclude.map((RegExp r) => r.pattern)), 115 "exclude": []..addAll(exclude.map((RegExp r) => r.pattern)),
113 }; 116 };
114 } 117 }
115 } 118 }
116 119
117 abstract class ChainContext { 120 abstract class ChainContext {
118 const ChainContext(); 121 const ChainContext();
119 122
120 List<Step> get steps; 123 List<Step> get steps;
121 124
125 ExpectationSet get expectationSet => ExpectationSet.Default;
126
122 Future<Null> run(Chain suite, Set<String> selectors) async { 127 Future<Null> run(Chain suite, Set<String> selectors) async {
123 TestExpectations expectations = await ReadTestExpectations( 128 TestExpectations expectations = await ReadTestExpectations(
124 <String>[suite.statusFile.toFilePath()], {}); 129 <String>[suite.statusFile.toFilePath()], {}, expectationSet);
125 Stream<TestDescription> stream = list(suite); 130 Stream<TestDescription> stream = list(suite);
126 if (suite.processMultitests) { 131 if (suite.processMultitests) {
127 stream = stream.transform(new MultitestTransformer()); 132 stream = stream.transform(new MultitestTransformer());
128 } 133 }
129 List<TestDescription> descriptions = await stream.toList(); 134 List<TestDescription> descriptions = await stream.toList();
130 descriptions.sort(); 135 descriptions.sort();
131 Map<TestDescription, Result> unexpectedResults = 136 Map<TestDescription, Result> unexpectedResults =
132 <TestDescription, Result>{}; 137 <TestDescription, Result>{};
133 Map<TestDescription, Set<Expectation>> unexpectedOutcomes = 138 Map<TestDescription, Set<Expectation>> unexpectedOutcomes =
134 <TestDescription, Set<Expectation>>{}; 139 <TestDescription, Set<Expectation>>{};
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 } 187 }
183 }, printLineOnStdout: sb.writeln); 188 }, printLineOnStdout: sb.writeln);
184 } else { 189 } else {
185 future = new Future.value(null); 190 future = new Future.value(null);
186 } 191 }
187 future = future.then((Result currentResult) { 192 future = future.then((Result currentResult) {
188 if (currentResult != null) { 193 if (currentResult != null) {
189 logStepComplete(completed, unexpectedResults.length, 194 logStepComplete(completed, unexpectedResults.length,
190 descriptions.length, suite, description, lastStepRun); 195 descriptions.length, suite, description, lastStepRun);
191 result = currentResult; 196 result = currentResult;
192 if (currentResult.outcome == Expectation.PASS) { 197 if (currentResult.outcome == Expectation.Pass) {
193 // The input to the next step is the output of this step. 198 // The input to the next step is the output of this step.
194 return doStep(result.output); 199 return doStep(result.output);
195 } 200 }
196 } 201 }
197 if (description.multitestExpectations != null) { 202 if (description.multitestExpectations != null) {
198 if (isError(description.multitestExpectations)) { 203 if (isError(description.multitestExpectations)) {
199 result = toNegativeTestResult( 204 result = toNegativeTestResult(
200 result, description.multitestExpectations); 205 result, description.multitestExpectations);
201 } 206 }
202 } else if (lastStep == lastStepRun && 207 } else if (lastStep == lastStepRun &&
203 description.shortName.endsWith("negative_test")) { 208 description.shortName.endsWith("negative_test")) {
204 if (result.outcome == Expectation.PASS) { 209 if (result.outcome == Expectation.Pass) {
205 result.addLog("Negative test didn't report an error.\n"); 210 result.addLog("Negative test didn't report an error.\n");
206 } else if (result.outcome == Expectation.FAIL) { 211 } else if (result.outcome == Expectation.Fail) {
207 result.addLog("Negative test reported an error as expeceted.\n"); 212 result.addLog("Negative test reported an error as expeceted.\n");
208 } 213 }
209 result = toNegativeTestResult(result); 214 result = toNegativeTestResult(result);
210 } 215 }
211 if (!expectedOutcomes.contains(result.outcome)) { 216 if (!expectedOutcomes.contains(result.outcome)) {
212 result.addLog("$sb"); 217 result.addLog("$sb");
213 unexpectedResults[description] = result; 218 unexpectedResults[description] = result;
214 unexpectedOutcomes[description] = expectedOutcomes; 219 unexpectedOutcomes[description] = expectedOutcomes;
215 logUnexpectedResult(suite, description, result, expectedOutcomes); 220 logUnexpectedResult(suite, description, result, expectedOutcomes);
216 } else { 221 } else {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 String path = entity.uri.path; 259 String path = entity.uri.path;
255 if (suite.exclude.any((RegExp r) => path.contains(r))) continue; 260 if (suite.exclude.any((RegExp r) => path.contains(r))) continue;
256 if (suite.pattern.any((RegExp r) => path.contains(r))) { 261 if (suite.pattern.any((RegExp r) => path.contains(r))) {
257 yield new TestDescription(suite.uri, entity); 262 yield new TestDescription(suite.uri, entity);
258 } 263 }
259 } 264 }
260 } else { 265 } else {
261 throw "${suite.uri} isn't a directory"; 266 throw "${suite.uri} isn't a directory";
262 } 267 }
263 } 268 }
269
270 Result toNegativeTestResult(Result result, [Set<String> expectations]) {
271 Expectation outcome = result.outcome;
272 if (outcome == Expectation.Pass) {
273 if (expectations == null) {
274 outcome = Expectation.Fail;
275 } else if (expectations.contains("compile-time error")) {
276 outcome = expectationSet["MissingCompileTimeError"];
277 } else if (expectations.contains("runtime error") ||
278 expectations.contains("dynamic type error")) {
279 outcome = expectationSet["MissingRuntimeError"];
280 } else {
281 outcome = Expectation.Fail;
282 }
283 } else if (outcome == Expectation.Fail) {
284 outcome = Expectation.Pass;
285 }
286 return result.copyWithOutcome(outcome);
287 }
264 } 288 }
265 289
266 abstract class Step<I, O, C extends ChainContext> { 290 abstract class Step<I, O, C extends ChainContext> {
267 const Step(); 291 const Step();
268 292
269 String get name; 293 String get name;
270 294
271 bool get isAsync => false; 295 bool get isAsync => false;
272 296
273 bool get isCompiler => false; 297 bool get isCompiler => false;
(...skipping 22 matching lines...) Expand all
296 320
297 final error; 321 final error;
298 322
299 final StackTrace trace; 323 final StackTrace trace;
300 324
301 final List<String> logs = <String>[]; 325 final List<String> logs = <String>[];
302 326
303 Result(this.output, this.outcome, this.error, this.trace); 327 Result(this.output, this.outcome, this.error, this.trace);
304 328
305 Result.pass(O output) 329 Result.pass(O output)
306 : this(output, Expectation.PASS, null, null); 330 : this(output, Expectation.Pass, null, null);
307 331
308 Result.crash(error, StackTrace trace) 332 Result.crash(error, StackTrace trace)
309 : this(null, Expectation.CRASH, error, trace); 333 : this(null, Expectation.Crash, error, trace);
310 334
311 Result.fail(O output, [error, StackTrace trace]) 335 Result.fail(O output, [error, StackTrace trace])
312 : this(output, Expectation.FAIL, error, trace); 336 : this(output, Expectation.Fail, error, trace);
313 337
314 String get log => logs.join(); 338 String get log => logs.join();
315 339
316 void addLog(String log) { 340 void addLog(String log) {
317 logs.add(log); 341 logs.add(log);
318 } 342 }
319 343
320 Result<O> copyWithOutcome(Expectation outcome) { 344 Result<O> copyWithOutcome(Expectation outcome) {
321 return new Result<O>(output, outcome, error, trace) 345 return new Result<O>(output, outcome, error, trace)
322 ..logs.addAll(logs); 346 ..logs.addAll(logs);
323 } 347 }
324 } 348 }
325 349
326 /// This is called from generated code. 350 /// This is called from generated code.
327 Future<Null> runChain( 351 Future<Null> runChain(
328 CreateContext f, Map<String, String> environment, Set<String> selectors, 352 CreateContext f, Map<String, String> environment, Set<String> selectors,
329 String json) { 353 String json) {
330 return withErrorHandling(() async { 354 return withErrorHandling(() async {
331 Chain suite = new Suite.fromJsonMap(Uri.base, JSON.decode(json)); 355 Chain suite = new Suite.fromJsonMap(Uri.base, JSON.decode(json));
332 print("Running ${suite.name}"); 356 print("Running ${suite.name}");
333 ChainContext context = await f(suite, environment); 357 ChainContext context = await f(suite, environment);
334 return context.run(suite, selectors); 358 return context.run(suite, selectors);
335 }); 359 });
336 } 360 }
337
338 Result toNegativeTestResult(Result result, [Set<String> expectations]) {
339 Expectation outcome = result.outcome;
340 if (outcome == Expectation.PASS) {
341 if (expectations == null) {
342 outcome = Expectation.FAIL;
343 } else if (expectations.contains("compile-time error")) {
344 outcome = Expectation.MISSING_COMPILETIME_ERROR;
345 } else if (expectations.contains("runtime error") ||
346 expectations.contains("dynamic type error")) {
347 outcome = Expectation.MISSING_RUNTIME_ERROR;
348 } else {
349 outcome = Expectation.FAIL;
350 }
351 } else if (outcome == Expectation.FAIL) {
352 outcome = Expectation.PASS;
353 }
354 return result.copyWithOutcome(outcome);
355 }
OLDNEW
« no previous file with comments | « no previous file | pkg/testing/lib/src/expectation.dart » ('j') | pkg/testing/lib/src/expectation.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698