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

Side by Side Diff: pkg/fasta/lib/testing/kernel_chain.dart

Issue 2631613003: Add Fasta tests. (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
« no previous file with comments | « no previous file | pkg/fasta/lib/testing/suite.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE.md file.
4
5 // TODO(ahe): Copied from closure_conversion branch of kernel, remove this file
6 // when closure_conversion is merged with master.
7
8 library kernel.testing.kernel_chain;
9
10 import 'dart:async' show
11 Future;
12
13 import 'dart:io' show
14 Directory,
15 File,
16 IOSink,
17 Platform;
18
19 import 'dart:typed_data' show
20 Uint8List;
21
22 import 'package:kernel/kernel.dart' show
23 Repository,
24 loadProgramFromBinary;
25
26 import 'package:kernel/text/ast_to_text.dart' show
27 Printer;
28
29 import 'package:testing/testing.dart' show
30 Result,
31 StdioProcess,
32 Step;
33
34 import 'package:kernel/ast.dart' show
35 Library,
36 Program;
37
38 import 'package:kernel/verifier.dart' show
39 VerifyingVisitor;
40
41 import 'package:kernel/binary/ast_to_binary.dart' show
42 BinaryPrinter;
43
44 import 'package:kernel/binary/ast_from_binary.dart' show
45 BinaryBuilder;
46
47 import 'package:kernel/binary/loader.dart' show
48 BinaryLoader;
49
50 import 'package:analyzer/src/generated/sdk.dart' show
51 DartSdk;
52
53 import 'package:kernel/analyzer/loader.dart' show
54 DartLoader,
55 DartOptions,
56 createDartSdk;
57
58 import 'package:kernel/target/targets.dart' show
59 Target,
60 TargetFlags,
61 getTarget;
62
63 import 'package:kernel/repository.dart' show
64 Repository;
65
66 import 'package:testing/testing.dart' show
67 Chain,
68 ChainContext,
69 Result,
70 StdioProcess,
71 Step,
72 TestDescription;
73
74 import 'package:kernel/ast.dart' show
75 Program;
76
77 import 'package:package_config/discovery.dart' show
78 loadPackagesFile;
79
80 typedef Future<TestContext> TestContextConstructor(
81 Chain suite, Map<String, String> environment, String sdk, Uri vm,
82 Uri packages, bool strongMode, DartSdk dartSdk, bool updateExpectations);
83
84 Future<bool> fileExists(Uri base, String path) async {
85 return await new File.fromUri(base.resolve(path)).exists();
86 }
87
88 abstract class TestContext extends ChainContext {
89 final Uri vm;
90
91 final Uri packages;
92
93 final DartOptions options;
94
95 final DartSdk dartSdk;
96
97 TestContext(String sdk, this.vm, Uri packages, bool strongMode, this.dartSdk)
98 : packages = packages,
99 options = new DartOptions(strongMode: strongMode, sdk: sdk,
100 packagePath: packages.toFilePath());
101
102 Future<DartLoader> createLoader() async {
103 Repository repository = new Repository();
104 return new DartLoader(repository, options, await loadPackagesFile(packages),
105 ignoreRedirectingFactories: false, dartSdk: dartSdk);
106 }
107
108 static Future<TestContext> create(Chain suite,
109 Map<String, String> environment,
110 TestContextConstructor constructor) async {
111 const String suggestion =
112 "Try checking the value of environment variable 'DART_AOT_SDK', "
113 "it should point to a patched SDK.";
114 String sdk = await getEnvironmentVariable(
115 "DART_AOT_SDK", Environment.directory,
116 "Please define environment variable 'DART_AOT_SDK' to point to a "
117 "patched SDK.",
118 (String n) => "Couldn't locate '$n'. $suggestion");
119 Uri sdkUri = Uri.base.resolve("$sdk/");
120 const String asyncDart = "lib/async/async.dart";
121 if (!await fileExists(sdkUri, asyncDart)) {
122 throw "Couldn't find '$asyncDart' in '$sdk'. $suggestion";
123 }
124 const String asyncSources = "lib/async/async_sources.gypi";
125 if (await fileExists(sdkUri, asyncSources)) {
126 throw "Found '$asyncSources' in '$sdk', so it isn't a patched SDK. "
127 "$suggestion";
128 }
129
130 String vmPath = await getEnvironmentVariable("DART_AOT_VM", Environment.file ,
Johnni Winther 2017/01/16 08:43:12 Long line.
ahe 2017/01/16 09:03:03 Done.
131 "Please define environment variable 'DART_AOT_VM' to point to a "
132 "Dart VM that reads .dill files.",
133 (String n) => "Couldn't locate '$n'. Please check the value of "
134 "environment variable 'DART_AOT_VM', it should point to a "
135 "Dart VM that reads .dill files.");
136 Uri vm = Uri.base.resolve(vmPath);
137
138 Uri packages = Uri.base.resolve(".packages");
139 bool strongMode = false;
140 bool updateExpectations = environment["updateExpectations"] != "false";
141 return constructor(suite, environment, sdk, vm, packages, strongMode,
142 createDartSdk(sdk, strongMode: strongMode), updateExpectations);
143 }
144 }
145
146 enum Environment {
147 directory,
148 file,
149 }
150
151 Future<String> getEnvironmentVariable(
152 String name, Environment kind, String undefined, notFound(String n)) async {
153 String result = Platform.environment[name];
154 if (result == null) {
155 throw undefined;
156 }
157 switch (kind) {
158 case Environment.directory:
159 if (!await new Directory(result).exists()) throw notFound(result);
160 break;
161
162 case Environment.file:
163 if (!await new File(result).exists()) throw notFound(result);
164 break;
165 }
166 return result;
167 }
168
169 class Kernel extends Step<TestDescription, Program, TestContext> {
170 const Kernel();
171
172 String get name => "kernel";
173
174 Future<Result<Program>> run(
175 TestDescription description, TestContext testContext) async {
176 try {
177 DartLoader loader = await testContext.createLoader();
178 Target target = getTarget(
179 "vm", new TargetFlags(strongMode: testContext.options.strongMode));
180 Program program =
181 loader.loadProgram(description.uri, target: target);
182 for (var error in loader.errors) {
183 return fail(program, "$error");
184 }
185 target.transformProgram(program);
186 return pass(program);
187 } catch (e, s) {
188 return crash(e, s);
189 }
190 }
191 }
192
193
194 class Print extends Step<Program, Program, dynamic> {
195 const Print();
196
197 String get name => "print";
198
199 Future<Result<Program>> run(Program program, _) async {
200 StringBuffer sb = new StringBuffer();
201 for (Library library in program.libraries) {
202 Printer printer = new Printer(sb);
203 if (library.importUri.scheme != "dart" &&
204 library.importUri.scheme != "package") {
205 printer.writeLibraryFile(library);
206 }
207 }
208 print("$sb");
209 return pass(program);
210 }
211 }
212
213 class Verify extends Step<Program, Program, dynamic> {
214 final bool fullCompile;
215
216 const Verify(this.fullCompile);
217
218 String get name => "verify";
219
220 Future<Result<Program>> run(Program program, TestContext testContext) async {
221 try {
222 program.accept(new VerifyingVisitor()..isOutline = !fullCompile);
223 return pass(program);
224 } catch (e, s) {
225 return new Result<Program>(
226 null, testContext.expectationSet["VerificationError"], e, s);
227 }
228 }
229 }
230
231 class MatchExpectation extends Step<Program, Program, dynamic> {
232 final String suffix;
233
234 final bool updateExpectations;
235
236 const MatchExpectation(this.suffix, {this.updateExpectations: true});
Johnni Winther 2017/01/16 08:43:12 Weird default value given the class name.
ahe 2017/01/16 09:03:03 Good point, I've added a todo.
237
238 String get name => "match expectations";
239
240 Future<Result<Program>> run(Program program, _) async {
241 Library library = program.libraries.firstWhere(
242 (Library library) =>library.importUri.scheme != "dart");
Johnni Winther 2017/01/16 08:43:12 `=>library` -> `=> library`
ahe 2017/01/16 09:03:03 Done.
243 Uri uri = library.importUri;
244 StringBuffer buffer = new StringBuffer();
245 new Printer(buffer).writeLibraryFile(library);
246
247 File expectedFile = new File("${uri.toFilePath()}$suffix");
248 if (await expectedFile.exists()) {
249 String expected = await expectedFile.readAsString();
250 if (expected.trim() != "$buffer".trim()) {
251 if (!updateExpectations) {
252 String diff = await runDiff(expectedFile.uri, "$buffer");
253 return fail(null, "$uri doesn't match ${expectedFile.uri}\n$diff");
254 }
255 } else {
256 return pass(program);
257 }
258 }
259 if (updateExpectations) {
260 await openWrite(expectedFile.uri, (IOSink sink) {
261 sink.writeln("$buffer".trim());
262 });
263 return pass(program);
264 } else {
265 return fail(program, """
266 Please create file ${expectedFile.path} with this content:
267 $buffer""");
268 }
269 }
270 }
271
272 class WriteDill extends Step<Program, Uri, dynamic> {
273 const WriteDill();
274
275 String get name => "write .dill";
276
277 Future<Result<Uri>> run(Program program, _) async {
278 Directory tmp = await Directory.systemTemp.createTemp();
279 Uri uri = tmp.uri.resolve("generated.dill");
280 File generated = new File.fromUri(uri);
281 IOSink sink = generated.openWrite();
282 try {
283 new BinaryPrinter(sink).writeProgramFile(program);
284 } catch (e, s) {
285 return fail(uri, e, s);
286 } finally {
287 print("Wrote `${generated.path}`");
288 await sink.close();
289 }
290 return pass(uri);
291 }
292 }
293
294 class ReadDill extends Step<Uri, Uri, dynamic> {
295 const ReadDill();
296
297 String get name => "read .dill";
298
299 Future<Result<Uri>> run(Uri uri, _) async {
300 try {
301 loadProgramFromBinary(uri.toFilePath());
302 } catch (e, s) {
303 return fail(uri, e, s);
304 }
305 return pass(uri);
306 }
307 }
308
309 class Copy extends Step<Program, Program, dynamic> {
310 const Copy();
311
312 String get name => "copy program";
313
314 Future<Result<Program>> run(Program program, _) async {
315 BytesCollector sink = new BytesCollector();
316 new BinaryPrinter(sink).writeProgramFile(program);
317 Uint8List bytes = sink.collect();
318 BinaryLoader loader = new BinaryLoader(new Repository());
319 return pass(new BinaryBuilder(loader, bytes).readProgramFile());
320 }
321 }
322
323 class Run extends Step<Uri, int, TestContext> {
324 const Run();
325
326 String get name => "run";
327
328 bool get isAsync => true;
329
330 bool get isRuntime => true;
331
332 Future<Result<int>> run(Uri uri, TestContext context) async {
333 File generated = new File.fromUri(uri);
334 StdioProcess process;
335 try {
336 process = await StdioProcess.run(
337 context.vm.toFilePath(), [generated.path, "Hello, World!"]);
338 print(process.output);
339 } finally {
340 generated.parent.delete(recursive: true);
341 }
342 return process.toResult();
343 }
344 }
345
346 class BytesCollector implements Sink<List<int>> {
347 final List<List<int>> lists = <List<int>>[];
348
349 int length = 0;
350
351 void add(List<int> data) {
352 lists.add(data);
353 length += data.length;
354 }
355
356 Uint8List collect() {
357 Uint8List result = new Uint8List(length);
358 int offset = 0;
359 for (List<int> list in lists) {
360 result.setRange(offset, offset += list.length, list);
361 }
362 lists.clear();
363 length = 0;
364 return result;
365 }
366
367 void close() {}
368 }
369
370 Future<String> runDiff(Uri expected, String actual) async {
371 StdioProcess process = await StdioProcess.run(
372 "diff", <String>["-u", expected.toFilePath(), "-"], input: actual);
Johnni Winther 2017/01/16 08:43:12 This probably doesn't work on Windows.
ahe 2017/01/16 09:03:03 Added todo.
373 return process.output;
374 }
375
376 Future openWrite(Uri uri, f(IOSink sink)) async {
377 IOSink sink = new File.fromUri(uri).openWrite();
378 try {
379 await f(sink);
380 } finally {
381 await sink.close();
382 }
383 print("Wrote $uri");
384 }
OLDNEW
« no previous file with comments | « no previous file | pkg/fasta/lib/testing/suite.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698