OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2014, 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 file. |
| 4 |
| 5 /// And end-to-end test that generates code and checks that the output matches |
| 6 /// the code in `static_test.dart`. Techincally we could run the result in an |
| 7 /// isolate, but instead we decided to split that up in two tests. This test |
| 8 /// ensures that we generate the code as it was written in static_test, and |
| 9 /// separately static_test ensures that the smoke.static library behaves as |
| 10 /// expected. |
| 11 library smoke.test.codegen.end_to_end_test; |
| 12 |
| 13 import 'dart:io'; |
| 14 |
| 15 import 'package:analyzer/src/generated/element.dart'; |
| 16 import 'package:smoke/codegen/generator.dart'; |
| 17 import 'package:smoke/codegen/recorder.dart'; |
| 18 import 'package:unittest/unittest.dart'; |
| 19 import 'package:path/path.dart' as path; |
| 20 |
| 21 import 'testing_resolver_utils.dart' show initAnalyzer; |
| 22 |
| 23 void main(List<String> args) { |
| 24 final updateStaticTest = args.length > 0 && args[0] == '--update_static_test'; |
| 25 |
| 26 test('static_test is up to date', () { |
| 27 var scriptPath = path.fromUri(Platform.script); |
| 28 var testDir = path.dirname(path.dirname(scriptPath)); |
| 29 var commonPath = path.join(testDir, 'common.dart'); |
| 30 var testCode = new File('$commonPath').readAsStringSync(); |
| 31 var lib = initAnalyzer({'common.dart': testCode}).libraryFor('common.dart'); |
| 32 var generator = new SmokeCodeGenerator(); |
| 33 var recorder = new Recorder(generator, _resolveImportUrl); |
| 34 |
| 35 lookupMember(String className, String memberName, bool recursive) { |
| 36 recorder.lookupMember(lib.getType(className), memberName, |
| 37 recursive: recursive, includeAccessors: false); |
| 38 } |
| 39 |
| 40 runQuery(String className, QueryOptions options) { |
| 41 recorder.runQuery(lib.getType(className), options, |
| 42 includeAccessors: false); |
| 43 } |
| 44 |
| 45 // Record all getters and setters we use in the tests. |
| 46 [ |
| 47 'i', |
| 48 'j', |
| 49 'j2', |
| 50 'inc0', |
| 51 'inc1', |
| 52 'inc2', |
| 53 'toString' |
| 54 ].forEach(generator.addGetter); |
| 55 ['i', 'j2'].forEach(generator.addSetter); |
| 56 |
| 57 // Record static methods used in the tests |
| 58 recorder.addStaticMethod(lib.getType('A'), 'staticInc'); |
| 59 |
| 60 // Record symbol convertions. |
| 61 generator.addSymbol('i'); |
| 62 |
| 63 /// Record all parent-class relations that we explicitly request. |
| 64 [ |
| 65 'AnnotB', |
| 66 'A', |
| 67 'B', |
| 68 'D', |
| 69 'H' |
| 70 ].forEach((className) => recorder.lookupParent(lib.getType(className))); |
| 71 |
| 72 // Record members for which we implicitly request their declaration in |
| 73 // has-getter and has-setter tests. |
| 74 lookupMember('A', 'i', true); |
| 75 lookupMember('A', 'j2', true); |
| 76 lookupMember('A', 'inc2', true); |
| 77 lookupMember('B', 'a', true); |
| 78 lookupMember('B', 'f', true); |
| 79 lookupMember('D', 'i', true); |
| 80 lookupMember('E', 'y', true); |
| 81 |
| 82 // Record also lookups for non-exisiting members. |
| 83 lookupMember('B', 'i', true); |
| 84 lookupMember('E', 'x', true); |
| 85 lookupMember('E', 'z', true); |
| 86 |
| 87 // Record members for which we explicitly request their declaration. |
| 88 lookupMember('B', 'a', false); |
| 89 lookupMember('B', 'w', false); |
| 90 lookupMember('A', 'inc1', false); |
| 91 lookupMember('F', 'staticMethod', false); |
| 92 lookupMember('G', 'b', false); |
| 93 lookupMember('G', 'd', false); |
| 94 |
| 95 // Lookups from no-such-method test. |
| 96 lookupMember('A', 'noSuchMethod', true); |
| 97 lookupMember('E', 'noSuchMethod', true); |
| 98 lookupMember('E2', 'noSuchMethod', true); |
| 99 |
| 100 // Lookups from has-instance-method and has-static-method tests. |
| 101 lookupMember('A', 'inc0', true); |
| 102 lookupMember('A', 'inc3', true); |
| 103 lookupMember('C', 'inc', true); |
| 104 lookupMember('D', 'inc', true); |
| 105 lookupMember('D', 'inc0', true); |
| 106 lookupMember('F', 'staticMethod', true); |
| 107 lookupMember('F2', 'staticMethod', true); |
| 108 |
| 109 // Record all queries done by the test. |
| 110 runQuery('A', new QueryOptions()); |
| 111 runQuery('D', new QueryOptions(includeInherited: true)); |
| 112 |
| 113 var vars = lib.definingCompilationUnit.topLevelVariables; |
| 114 expect(vars[0].name, 'a1'); |
| 115 expect(vars[1].name, 'a2'); |
| 116 |
| 117 runQuery('H', new QueryOptions( |
| 118 includeInherited: true, |
| 119 withAnnotations: [vars[0], vars[1], lib.getType('Annot')])); |
| 120 |
| 121 runQuery('K', new QueryOptions( |
| 122 includeInherited: true, withAnnotations: [lib.getType('AnnotC')])); |
| 123 |
| 124 runQuery('L', new QueryOptions(includeMethods: true)); |
| 125 runQuery('L2', new QueryOptions( |
| 126 includeInherited: true, includeMethods: true)); |
| 127 |
| 128 var code = _createEntrypoint(generator); |
| 129 var staticTestFile = new File(path.join(testDir, 'static_test.dart')); |
| 130 var existingCode = staticTestFile.readAsStringSync(); |
| 131 if (!updateStaticTest) { |
| 132 expect(code, existingCode); |
| 133 } else if (code == existingCode) { |
| 134 print('static_test.dart is already up to date'); |
| 135 } else { |
| 136 staticTestFile.writeAsStringSync(code); |
| 137 print('static_test.dart has been updated.'); |
| 138 } |
| 139 }); |
| 140 } |
| 141 |
| 142 String _createEntrypoint(SmokeCodeGenerator generator) { |
| 143 var sb = new StringBuffer() |
| 144 ..writeln('/// ---- AUTOGENERATED: DO NOT EDIT THIS FILE --------------') |
| 145 ..writeln('/// To update this test file, call:') |
| 146 ..writeln('/// > dart codegen/end_to_end_test.dart --update_static_test') |
| 147 ..writeln('/// --------------------------------------------------------') |
| 148 ..writeln('\nlibrary smoke.test.static_test;\n') |
| 149 ..writeln("import 'package:unittest/unittest.dart';"); |
| 150 |
| 151 generator.writeImports(sb); |
| 152 sb.writeln("import 'common.dart' as common show main;\n"); |
| 153 generator.writeTopLevelDeclarations(sb); |
| 154 sb.write('\nfinal configuration = '); |
| 155 generator.writeStaticConfiguration(sb, 0); |
| 156 |
| 157 sb |
| 158 ..writeln(';\n') |
| 159 ..writeln('main() {') |
| 160 ..writeln(' setUp(() => useGeneratedCode(configuration));') |
| 161 ..writeln(' common.main();') |
| 162 ..writeln('}'); |
| 163 return sb.toString(); |
| 164 } |
| 165 |
| 166 String _resolveImportUrl(LibraryElement lib) { |
| 167 if (lib.isDartCore) return 'dart:core'; |
| 168 if (lib.displayName == 'smoke.test.common') return 'common.dart'; |
| 169 return 'unknown.dart'; |
| 170 } |
OLD | NEW |