Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /// Test infrastructure for testing pub. Unlike typical unit tests, most pub | 5 /// Test infrastructure for testing pub. Unlike typical unit tests, most pub |
| 6 /// tests are integration tests that stage some stuff on the file system, run | 6 /// tests are integration tests that stage some stuff on the file system, run |
| 7 /// pub, and then validate the results. This library provides an API to build | 7 /// pub, and then validate the results. This library provides an API to build |
| 8 /// tests like that. | 8 /// tests like that. |
| 9 library test_pub; | 9 library test_pub; |
| 10 | 10 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 140 if (_server == null) return new Future.value(); | 140 if (_server == null) return new Future.value(); |
| 141 _server.close(); | 141 _server.close(); |
| 142 _server = null; | 142 _server = null; |
| 143 _portCompleterCache = null; | 143 _portCompleterCache = null; |
| 144 // TODO(nweiz): Remove this once issue 4155 is fixed. Pumping the event loop | 144 // TODO(nweiz): Remove this once issue 4155 is fixed. Pumping the event loop |
| 145 // *seems* to be enough to ensure that the server is actually closed, but I'm | 145 // *seems* to be enough to ensure that the server is actually closed, but I'm |
| 146 // putting this at 10ms to be safe. | 146 // putting this at 10ms to be safe. |
| 147 return sleep(10); | 147 return sleep(10); |
| 148 } | 148 } |
| 149 | 149 |
| 150 /// The [d.DirectoryDescriptor] describing the server layout of packages that | 150 /// The [d.DirectoryDescriptor] describing the server layout of `/api/packages` |
| 151 /// are being served via [servePackages]. This is `null` if [servePackages] has | 151 /// on the test server. |
| 152 /// not yet been called for this test. | 152 /// |
| 153 /// This contains metadata for packages that are being served via | |
| 154 /// [servePackages]. It's `null` if [servePackages] has not yet been called for | |
| 155 /// this test. | |
| 156 d.DirectoryDescriptor _servedApiPackageDir; | |
| 157 | |
| 158 /// The [d.DirectoryDescriptor] describing the server layout of `/packages` on | |
| 159 /// the test server. | |
| 160 /// | |
| 161 /// This contains the tarballs for packages that are being served via | |
| 162 /// [servePackages]. It's `null` if [servePackages] has not yet been called for | |
| 163 /// this test. | |
| 153 d.DirectoryDescriptor _servedPackageDir; | 164 d.DirectoryDescriptor _servedPackageDir; |
| 154 | 165 |
| 155 /// A map from package names to version numbers to YAML-serialized pubspecs for | 166 /// A map from package names to version numbers to parsed pubspec maps for those |
|
Bob Nystrom
2013/06/04 20:21:41
Remove "to version numbers".
nweiz
2013/06/04 21:04:17
Done.
| |
| 156 /// those packages. This represents the packages currently being served by | 167 /// packages. This represents the packages currently being served by |
| 157 /// [servePackages], and is `null` if [servePackages] has not yet been called | 168 /// [servePackages], and is `null` if [servePackages] has not yet been called |
| 158 /// for this test. | 169 /// for this test. |
| 159 Map<String, Map<String, String>> _servedPackages; | 170 Map<String, List<Map>> _servedPackages; |
| 160 | 171 |
| 161 /// Creates an HTTP server that replicates the structure of pub.dartlang.org. | 172 /// Creates an HTTP server that replicates the structure of pub.dartlang.org. |
| 162 /// [pubspecs] is a list of unserialized pubspecs representing the packages to | 173 /// [pubspecs] is a list of unserialized pubspecs representing the packages to |
| 163 /// serve. | 174 /// serve. |
| 164 /// | 175 /// |
| 165 /// Subsequent calls to [servePackages] will add to the set of packages that | 176 /// Subsequent calls to [servePackages] will add to the set of packages that |
| 166 /// are being served. Previous packages will continue to be served. | 177 /// are being served. Previous packages will continue to be served. |
| 167 void servePackages(List<Map> pubspecs) { | 178 void servePackages(List<Map> pubspecs) { |
| 168 if (_servedPackages == null || _servedPackageDir == null) { | 179 if (_servedPackages == null || _servedPackageDir == null) { |
| 169 _servedPackages = <String, Map<String, String>>{}; | 180 _servedPackages = <String, List<Map>>{}; |
| 181 _servedApiPackageDir = d.dir('packages', []); | |
| 170 _servedPackageDir = d.dir('packages', []); | 182 _servedPackageDir = d.dir('packages', []); |
| 171 serve([_servedPackageDir]); | 183 serve([ |
| 184 d.dir('api', [_servedApiPackageDir]), | |
| 185 _servedPackageDir | |
| 186 ]); | |
| 172 | 187 |
| 173 currentSchedule.onComplete.schedule(() { | 188 currentSchedule.onComplete.schedule(() { |
| 174 _servedPackages = null; | 189 _servedPackages = null; |
| 190 _servedApiPackageDir = null; | |
| 175 _servedPackageDir = null; | 191 _servedPackageDir = null; |
| 176 }, 'cleaning up served packages'); | 192 }, 'cleaning up served packages'); |
| 177 } | 193 } |
| 178 | 194 |
| 179 schedule(() { | 195 schedule(() { |
| 180 return awaitObject(pubspecs).then((resolvedPubspecs) { | 196 return awaitObject(pubspecs).then((resolvedPubspecs) { |
| 181 for (var spec in resolvedPubspecs) { | 197 for (var spec in resolvedPubspecs) { |
| 182 var name = spec['name']; | 198 var name = spec['name']; |
| 183 var version = spec['version']; | 199 var version = spec['version']; |
| 184 var versions = _servedPackages.putIfAbsent( | 200 var versions = _servedPackages.putIfAbsent(name, () => []); |
| 185 name, () => <String, String>{}); | 201 versions.add(spec); |
| 186 versions[version] = yaml(spec); | |
| 187 } | 202 } |
| 188 | 203 |
| 204 _servedApiPackageDir.contents.clear(); | |
| 189 _servedPackageDir.contents.clear(); | 205 _servedPackageDir.contents.clear(); |
| 190 for (var name in _servedPackages.keys) { | 206 for (var name in _servedPackages.keys) { |
| 191 var versions = _servedPackages[name].keys.toList(); | 207 _servedApiPackageDir.contents.addAll([ |
| 192 _servedPackageDir.contents.addAll([ | 208 d.file('$name', json.stringify({ |
| 193 d.file('$name.json', json.stringify({'versions': versions})), | 209 'name': name, |
| 210 'uploaders': ['nweiz@google.com'], | |
| 211 'versions': _servedPackages[name].map(packageVersionApiMap).toList() | |
| 212 })), | |
| 194 d.dir(name, [ | 213 d.dir(name, [ |
| 195 d.dir('versions', flatten(versions.map((version) { | 214 d.dir('versions', _servedPackages[name].map((pubspec) { |
| 196 return [ | 215 return d.file(pubspec['version'], json.stringify( |
| 197 d.file('$version.yaml', _servedPackages[name][version]), | 216 packageVersionApiMap(pubspec, full: true))); |
| 198 d.tar('$version.tar.gz', [ | 217 })) |
| 199 d.file('pubspec.yaml', _servedPackages[name][version]), | |
| 200 d.libDir(name, '$name $version') | |
| 201 ]) | |
| 202 ]; | |
| 203 }))) | |
| 204 ]) | 218 ]) |
| 205 ]); | 219 ]); |
| 220 | |
| 221 _servedPackageDir.contents.add(d.dir(name, [ | |
| 222 d.dir('versions', _servedPackages[name].map((pubspec) { | |
| 223 var version = pubspec['version']; | |
| 224 return d.tar('$version.tar.gz', [ | |
| 225 d.file('pubspec.yaml', json.stringify(pubspec)), | |
| 226 d.libDir(name, '$name $version') | |
| 227 ]); | |
| 228 })) | |
| 229 ])); | |
| 206 } | 230 } |
| 207 }); | 231 }); |
| 208 }, 'initializing the package server'); | 232 }, 'initializing the package server'); |
| 209 } | 233 } |
| 210 | 234 |
| 211 /// Converts [value] into a YAML string. | 235 /// Converts [value] into a YAML string. |
| 212 String yaml(value) => json.stringify(value); | 236 String yaml(value) => json.stringify(value); |
| 213 | 237 |
| 214 /// The full path to the created sandbox directory for an integration test. | 238 /// The full path to the created sandbox directory for an integration test. |
| 215 String get sandboxDir => _sandboxDir; | 239 String get sandboxDir => _sandboxDir; |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 625 return description['name']; | 649 return description['name']; |
| 626 case "path": | 650 case "path": |
| 627 return path.basename(description); | 651 return path.basename(description); |
| 628 case "sdk": | 652 case "sdk": |
| 629 return description; | 653 return description; |
| 630 default: | 654 default: |
| 631 return description; | 655 return description; |
| 632 } | 656 } |
| 633 } | 657 } |
| 634 | 658 |
| 659 /// Returns a Map in the format used by the pub.dartlang.org API to represent a | |
| 660 /// package version. | |
| 661 /// | |
| 662 /// [pubspec] is the parsed pubspec of the package version. If [full] is true, | |
| 663 /// this returns the complete map, including metadata that's only included when | |
| 664 /// requesting the package version directly. | |
| 665 Map packageVersionApiMap(Map pubspec, {bool full: false}) { | |
| 666 var name = pubspec['name']; | |
| 667 var version = pubspec['version']; | |
| 668 var map = { | |
| 669 'pubspec': pubspec, | |
| 670 'version': version, | |
| 671 'url': '/api/packages/$name/versions/$version', | |
| 672 'archive_url': '/packages/$name/versions/$version.tar.gz', | |
| 673 'new_dartdoc_url': '/api/packages/$name/versions/$version' | |
| 674 '/new_dartdoc', | |
| 675 'package_url': '/api/packages/$name' | |
| 676 }; | |
| 677 | |
| 678 if (full) { | |
| 679 mapAddAll(map, { | |
| 680 'downloads': 0, | |
| 681 'created': '2012-09-25T18:38:28.685260', | |
| 682 'libraries': ['$name.dart'], | |
| 683 'uploader': ['nweiz@google.com'] | |
| 684 }); | |
| 685 } | |
| 686 | |
| 687 return map; | |
| 688 } | |
| 689 | |
| 635 /// Compares the [actual] output from running pub with [expected]. For [String] | 690 /// Compares the [actual] output from running pub with [expected]. For [String] |
| 636 /// patterns, ignores leading and trailing whitespace differences and tries to | 691 /// patterns, ignores leading and trailing whitespace differences and tries to |
| 637 /// report the offending difference in a nice way. For other [Pattern]s, just | 692 /// report the offending difference in a nice way. For other [Pattern]s, just |
| 638 /// reports whether the output contained the pattern. | 693 /// reports whether the output contained the pattern. |
| 639 void _validateOutput(List<String> failures, String pipe, Pattern expected, | 694 void _validateOutput(List<String> failures, String pipe, Pattern expected, |
| 640 List<String> actual) { | 695 List<String> actual) { |
| 641 if (expected == null) return; | 696 if (expected == null) return; |
| 642 | 697 |
| 643 if (expected is RegExp) { | 698 if (expected is RegExp) { |
| 644 _validateOutputRegex(failures, pipe, expected, actual); | 699 _validateOutputRegex(failures, pipe, expected, actual); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 741 bool matches(item, MatchState matchState) { | 796 bool matches(item, MatchState matchState) { |
| 742 if (item is! Pair) return false; | 797 if (item is! Pair) return false; |
| 743 return _firstMatcher.matches(item.first, matchState) && | 798 return _firstMatcher.matches(item.first, matchState) && |
| 744 _lastMatcher.matches(item.last, matchState); | 799 _lastMatcher.matches(item.last, matchState); |
| 745 } | 800 } |
| 746 | 801 |
| 747 Description describe(Description description) { | 802 Description describe(Description description) { |
| 748 description.addAll("(", ", ", ")", [_firstMatcher, _lastMatcher]); | 803 description.addAll("(", ", ", ")", [_firstMatcher, _lastMatcher]); |
| 749 } | 804 } |
| 750 } | 805 } |
| OLD | NEW |