Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 file. | |
| 4 | |
| 5 import 'dart:async'; | |
| 6 | |
| 7 import 'package:front_end/compiler_options.dart'; | |
| 8 import 'package:front_end/dependency_grapher.dart'; | |
| 9 import 'package:front_end/memory_file_system.dart'; | |
| 10 import 'package:path/path.dart' as pathos; | |
| 11 import 'package:test/test.dart'; | |
| 12 import 'package:test_reflective_loader/test_reflective_loader.dart'; | |
| 13 | |
| 14 main() { | |
| 15 defineReflectiveSuite(() { | |
| 16 defineReflectiveTests(DependencyGrapherTest); | |
| 17 }); | |
| 18 } | |
| 19 | |
| 20 @reflectiveTest | |
| 21 class DependencyGrapherTest { | |
| 22 LibraryNode checkLibrary(LibraryCycleNode cycle, String uri, | |
| 23 {List<String> dependencies: const [], List<String> parts: const []}) { | |
| 24 var library = cycle.libraries[Uri.parse(uri)]; | |
| 25 expect(library.uri.toString(), uri); | |
|
Siggi Cherem (dart-lang)
2016/12/15 23:51:33
style nit: I prefer '${library.uri}'
It's shorter
Paul Berry
2016/12/16 02:46:45
Done.
| |
| 26 expect(library.dependencies.map((dep) => dep.uri.toString()).toList(), | |
| 27 unorderedEquals(dependencies)); | |
| 28 expect( | |
| 29 library.parts.map((part) => part.toString()), unorderedEquals(parts)); | |
|
Siggi Cherem (dart-lang)
2016/12/15 23:51:33
is .toList needed here (or not needed above?)
Paul Berry
2016/12/16 02:46:45
Not needed above. Good catch.
| |
| 30 return library; | |
| 31 } | |
| 32 | |
| 33 Future<List<LibraryCycleNode>> getCycles(Map<String, String> contents, | |
| 34 [List<String> startingPoints]) async { | |
| 35 // If no starting points given, assume the first entry in [contents] is the | |
| 36 // single starting point. | |
| 37 startingPoints ??= [contents.keys.first]; | |
| 38 var fileSystem = new MemoryFileSystem(pathos.posix, '/'); | |
| 39 contents.forEach((path, text) { | |
| 40 fileSystem.entityForPath(path).writeAsStringSync(text); | |
| 41 }); | |
| 42 // TODO(paulberry): implement and test other option possibilities. | |
| 43 var options = new CompilerOptions() | |
| 44 ..fileSystem = fileSystem | |
| 45 ..chaseDependencies = true; | |
| 46 var graph = await graphForProgram( | |
| 47 startingPoints.map(pathos.posix.toUri).toList(), options); | |
| 48 return graph.topologicallySortedCycles; | |
| 49 } | |
| 50 | |
| 51 /// Sort the given library cycles into a deterministic order based on their | |
| 52 /// URIs for easier unit testing. | |
| 53 List<LibraryCycleNode> sortCycles(Iterable<LibraryCycleNode> cycles) { | |
| 54 var result = cycles.toList(); | |
| 55 String sortKey(LibraryCycleNode node) => node.libraries.keys.join(','); | |
| 56 result.sort((a, b) => Comparable.compare(sortKey(a), sortKey(b))); | |
| 57 return result; | |
| 58 } | |
| 59 | |
| 60 test_exportDependency() async { | |
| 61 var cycles = | |
| 62 await getCycles({'/foo.dart': 'export "bar.dart";', '/bar.dart': ''}); | |
| 63 expect(cycles, hasLength(2)); | |
| 64 expect(cycles[0].libraries, hasLength(1)); | |
| 65 checkLibrary(cycles[0], 'file:///bar.dart'); | |
| 66 expect(cycles[1].libraries, hasLength(1)); | |
| 67 checkLibrary(cycles[1], 'file:///foo.dart', | |
| 68 dependencies: ['file:///bar.dart']); | |
| 69 } | |
| 70 | |
| 71 test_importDependency() async { | |
| 72 var cycles = | |
| 73 await getCycles({'/foo.dart': 'import "bar.dart";', '/bar.dart': ''}); | |
| 74 expect(cycles, hasLength(2)); | |
| 75 expect(cycles[0].libraries, hasLength(1)); | |
| 76 checkLibrary(cycles[0], 'file:///bar.dart'); | |
| 77 expect(cycles[1].libraries, hasLength(1)); | |
| 78 checkLibrary(cycles[1], 'file:///foo.dart', | |
| 79 dependencies: ['file:///bar.dart']); | |
| 80 } | |
| 81 | |
| 82 test_multipleStartingPoints() async { | |
| 83 var cycles = await getCycles({ | |
| 84 '/a.dart': 'import "c.dart";', | |
| 85 '/b.dart': 'import "c.dart";', | |
| 86 '/c.dart': '' | |
| 87 }, [ | |
| 88 '/a.dart', | |
| 89 '/b.dart' | |
| 90 ]); | |
| 91 expect(cycles, hasLength(3)); | |
| 92 expect(cycles[0].libraries, hasLength(1)); | |
| 93 checkLibrary(cycles[0], 'file:///c.dart'); | |
| 94 // The other two cycles might be in any order, so sort them for | |
| 95 // reproducibility. | |
| 96 List<LibraryCycleNode> otherCycles = sortCycles(cycles.sublist(1)); | |
| 97 checkLibrary(otherCycles[0], 'file:///a.dart', | |
| 98 dependencies: ['file:///c.dart']); | |
| 99 checkLibrary(otherCycles[1], 'file:///b.dart', | |
| 100 dependencies: ['file:///c.dart']); | |
| 101 } | |
| 102 | |
| 103 test_parts() async { | |
| 104 var cycles = await getCycles({ | |
| 105 '/foo.dart': 'library foo; part "a.dart"; part "b.dart";', | |
| 106 '/a.dart': 'part of foo;', | |
| 107 '/b.dart': 'part of foo;' | |
| 108 }); | |
| 109 expect(cycles, hasLength(1)); | |
| 110 expect(cycles[0].libraries, hasLength(1)); | |
| 111 checkLibrary(cycles[0], 'file:///foo.dart', | |
| 112 parts: ['file:///a.dart', 'file:///b.dart']); | |
| 113 } | |
| 114 | |
| 115 test_relativeUris() async { | |
| 116 var cycles = await getCycles({ | |
| 117 '/a.dart': 'import "b/c.dart";', | |
| 118 '/b/c.dart': 'import "d/e.dart";', | |
| 119 '/b/d/e.dart': 'import "../f.dart";', | |
| 120 '/b/f.dart': '' | |
| 121 }); | |
| 122 expect(cycles, hasLength(4)); | |
| 123 expect(cycles[0].libraries, hasLength(1)); | |
| 124 checkLibrary(cycles[0], 'file:///b/f.dart'); | |
| 125 expect(cycles[1].libraries, hasLength(1)); | |
| 126 checkLibrary(cycles[1], 'file:///b/d/e.dart', | |
| 127 dependencies: ['file:///b/f.dart']); | |
| 128 expect(cycles[2].libraries, hasLength(1)); | |
| 129 checkLibrary(cycles[2], 'file:///b/c.dart', | |
| 130 dependencies: ['file:///b/d/e.dart']); | |
| 131 expect(cycles[3].libraries, hasLength(1)); | |
| 132 checkLibrary(cycles[3], 'file:///a.dart', | |
| 133 dependencies: ['file:///b/c.dart']); | |
| 134 } | |
| 135 | |
| 136 test_simpleCycle() async { | |
| 137 var cycles = await getCycles( | |
| 138 {'/foo.dart': 'import "bar.dart";', '/bar.dart': 'import "foo.dart";'}); | |
| 139 expect(cycles, hasLength(1)); | |
| 140 expect(cycles[0].libraries, hasLength(2)); | |
| 141 var foo = checkLibrary(cycles[0], 'file:///foo.dart', | |
| 142 dependencies: ['file:///bar.dart']); | |
| 143 var bar = checkLibrary(cycles[0], 'file:///bar.dart', | |
| 144 dependencies: ['file:///foo.dart']); | |
| 145 expect(foo.dependencies[0], same(bar)); | |
| 146 expect(bar.dependencies[0], same(foo)); | |
| 147 } | |
| 148 | |
| 149 test_singleFile() async { | |
| 150 var cycles = await getCycles({'/foo.dart': ''}); | |
| 151 expect(cycles, hasLength(1)); | |
| 152 expect(cycles[0].libraries, hasLength(1)); | |
| 153 checkLibrary(cycles[0], 'file:///foo.dart'); | |
| 154 } | |
| 155 } | |
| OLD | NEW |