| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 /** | 5 /** |
| 6 * Test infrastructure for testing pub. Unlike typical unit tests, most pub | 6 * Test infrastructure for testing pub. Unlike typical unit tests, most pub |
| 7 * tests are integration tests that stage some stuff on the file system, run | 7 * tests are integration tests that stage some stuff on the file system, run |
| 8 * pub, and then validate the results. This library provides an API to build | 8 * pub, and then validate the results. This library provides an API to build |
| 9 * tests like that. | 9 * tests like that. |
| 10 */ | 10 */ |
| 11 #library('test_pub'); | 11 #library('test_pub'); |
| 12 | 12 |
| 13 #import('dart:io'); | 13 #import('dart:io'); |
| 14 #import('dart:isolate'); |
| 15 #import('dart:json'); |
| 14 #import('dart:uri'); | 16 #import('dart:uri'); |
| 15 | 17 |
| 16 #import('../../../lib/unittest/unittest.dart'); | 18 #import('../../../lib/unittest/unittest.dart'); |
| 17 #import('../../lib/file_system.dart', prefix: 'fs'); | 19 #import('../../lib/file_system.dart', prefix: 'fs'); |
| 18 #import('../../pub/io.dart'); | 20 #import('../../pub/io.dart'); |
| 19 #import('../../pub/utils.dart'); | 21 #import('../../pub/utils.dart'); |
| 20 #import('../../pub/yaml/yaml.dart'); | 22 #import('../../pub/yaml/yaml.dart'); |
| 21 | 23 |
| 22 /** | 24 /** |
| 23 * Creates a new [FileDescriptor] with [name] and [contents]. | 25 * Creates a new [FileDescriptor] with [name] and [contents]. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 50 void serve(String host, int port, [List<Descriptor> contents]) { | 52 void serve(String host, int port, [List<Descriptor> contents]) { |
| 51 var baseDir = dir("serve-dir", contents); | 53 var baseDir = dir("serve-dir", contents); |
| 52 if (host == 'localhost') { | 54 if (host == 'localhost') { |
| 53 host = '127.0.0.1'; | 55 host = '127.0.0.1'; |
| 54 } | 56 } |
| 55 | 57 |
| 56 _schedule((_) { | 58 _schedule((_) { |
| 57 var server = new HttpServer(); | 59 var server = new HttpServer(); |
| 58 server.defaultRequestHandler = (request, response) { | 60 server.defaultRequestHandler = (request, response) { |
| 59 var path = request.uri.replaceFirst("/", "").split("/"); | 61 var path = request.uri.replaceFirst("/", "").split("/"); |
| 60 var stream = baseDir.load(path); | |
| 61 response.persistentConnection = false; | 62 response.persistentConnection = false; |
| 62 if (stream == null) { | 63 var stream; |
| 64 try { |
| 65 stream = baseDir.load(path); |
| 66 } catch (var e) { |
| 63 response.statusCode = 404; | 67 response.statusCode = 404; |
| 68 response.contentLength = 0; |
| 64 response.outputStream.close(); | 69 response.outputStream.close(); |
| 65 return; | 70 return; |
| 66 } | 71 } |
| 67 | 72 |
| 68 var future = consumeInputStream(stream); | 73 var future = consumeInputStream(stream); |
| 69 future.then((data) { | 74 future.then((data) { |
| 70 response.statusCode = 200; | 75 response.statusCode = 200; |
| 71 response.contentLength = data.length; | 76 response.contentLength = data.length; |
| 72 response.outputStream.write(data); | 77 response.outputStream.write(data); |
| 73 response.outputStream.close(); | 78 response.outputStream.close(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 95 void servePackages(String host, int port, List<String> pubspecs) { | 100 void servePackages(String host, int port, List<String> pubspecs) { |
| 96 var packages = <Map<String, String>>{}; | 101 var packages = <Map<String, String>>{}; |
| 97 pubspecs.forEach((spec) { | 102 pubspecs.forEach((spec) { |
| 98 var parsed = loadYaml(spec); | 103 var parsed = loadYaml(spec); |
| 99 var name = parsed['name']; | 104 var name = parsed['name']; |
| 100 var version = parsed['version']; | 105 var version = parsed['version']; |
| 101 packages.putIfAbsent(name, () => <String>{})[version] = spec; | 106 packages.putIfAbsent(name, () => <String>{})[version] = spec; |
| 102 }); | 107 }); |
| 103 | 108 |
| 104 serve(host, port, [ | 109 serve(host, port, [ |
| 105 dir('packages', packages.getKeys().map((name) { | 110 dir('packages', flatten(packages.getKeys().map((name) { |
| 106 return dir(name, [ | 111 return [ |
| 107 dir('versions', packages[name].getKeys().map((version) { | 112 file('$name.json', |
| 108 return tar('$version.tar.gz', [ | 113 JSON.stringify({'versions': packages[name].getKeys()})), |
| 109 file('pubspec.yaml', packages[name][version]), | 114 dir(name, [ |
| 110 file('$name.dart', 'main() => print("$name $version");') | 115 dir('versions', flatten(packages[name].getKeys().map((version) { |
| 111 ]); | 116 return [ |
| 112 })) | 117 file('$version.yaml', packages[name][version]), |
| 113 ]); | 118 tar('$version.tar.gz', [ |
| 114 })) | 119 file('pubspec.yaml', packages[name][version]), |
| 120 file('$name.dart', 'main() => print("$name $version");') |
| 121 ]) |
| 122 ]; |
| 123 }))) |
| 124 ]) |
| 125 ]; |
| 126 }))) |
| 115 ]); | 127 ]); |
| 116 } | 128 } |
| 117 | 129 |
| 118 /** | 130 /** |
| 119 * The path of the package cache directory used for tests. Relative to the | 131 * The path of the package cache directory used for tests. Relative to the |
| 120 * sandbox directory. | 132 * sandbox directory. |
| 121 */ | 133 */ |
| 122 final String cachePath = "cache"; | 134 final String cachePath = "cache"; |
| 123 | 135 |
| 124 /** | 136 /** |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 'but contained:\n\n$text'); | 515 'but contained:\n\n$text'); |
| 504 }); | 516 }); |
| 505 }); | 517 }); |
| 506 } | 518 } |
| 507 | 519 |
| 508 /** | 520 /** |
| 509 * Loads the contents of the file. | 521 * Loads the contents of the file. |
| 510 */ | 522 */ |
| 511 InputStream load(List<String> path) { | 523 InputStream load(List<String> path) { |
| 512 if (!path.isEmpty()) { | 524 if (!path.isEmpty()) { |
| 513 var joinedPath = Strings.join('/', path); | 525 var joinedPath = Strings.join(path, '/'); |
| 514 throw "Can't load $joinedPath from within $name: not a directory."; | 526 throw "Can't load $joinedPath from within $name: not a directory."; |
| 515 } | 527 } |
| 516 | 528 |
| 517 var stream = new ListInputStream(); | 529 var stream = new ListInputStream(); |
| 518 stream.write(contents.charCodes()); | 530 stream.write(contents.charCodes()); |
| 531 stream.markEndOfStream(); |
| 519 return stream; | 532 return stream; |
| 520 } | 533 } |
| 521 } | 534 } |
| 522 | 535 |
| 523 /** | 536 /** |
| 524 * Describes a directory and its contents. These are used both for setting up | 537 * Describes a directory and its contents. These are used both for setting up |
| 525 * an expected directory tree before running a test, and for validating that | 538 * an expected directory tree before running a test, and for validating that |
| 526 * the file system matches some expectations after running it. | 539 * the file system matches some expectations after running it. |
| 527 */ | 540 */ |
| 528 class DirectoryDescriptor extends Descriptor { | 541 class DirectoryDescriptor extends Descriptor { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 if (path.isEmpty()) { | 601 if (path.isEmpty()) { |
| 589 throw "Can't load the contents of $name: is a directory."; | 602 throw "Can't load the contents of $name: is a directory."; |
| 590 } | 603 } |
| 591 | 604 |
| 592 for (var descriptor in contents) { | 605 for (var descriptor in contents) { |
| 593 if (descriptor.name == path[0]) { | 606 if (descriptor.name == path[0]) { |
| 594 return descriptor.load(path.getRange(1, path.length - 1)); | 607 return descriptor.load(path.getRange(1, path.length - 1)); |
| 595 } | 608 } |
| 596 } | 609 } |
| 597 | 610 |
| 598 throw "Directory $name doesn't contain ${Strings.join('/', path)}."; | 611 throw "Directory $name doesn't contain ${Strings.join(path, '/')}."; |
| 599 } | 612 } |
| 600 } | 613 } |
| 601 | 614 |
| 602 /** | 615 /** |
| 603 * Describes a Git repository and its contents. | 616 * Describes a Git repository and its contents. |
| 604 */ | 617 */ |
| 605 class GitRepoDescriptor extends DirectoryDescriptor { | 618 class GitRepoDescriptor extends DirectoryDescriptor { |
| 606 GitRepoDescriptor(Pattern name, List<Descriptor> contents) | 619 GitRepoDescriptor(Pattern name, List<Descriptor> contents) |
| 607 : super(name, contents); | 620 : super(name, contents); |
| 608 | 621 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 */ | 700 */ |
| 688 Future validate(String path) { | 701 Future validate(String path) { |
| 689 throw "TODO(nweiz): implement this"; | 702 throw "TODO(nweiz): implement this"; |
| 690 } | 703 } |
| 691 | 704 |
| 692 /** | 705 /** |
| 693 * Loads the contents of this tar file. | 706 * Loads the contents of this tar file. |
| 694 */ | 707 */ |
| 695 InputStream load(List<String> path) { | 708 InputStream load(List<String> path) { |
| 696 if (!path.isEmpty()) { | 709 if (!path.isEmpty()) { |
| 697 var joinedPath = Strings.join('/', path); | 710 var joinedPath = Strings.join(path, '/'); |
| 698 throw "Can't load $joinedPath from within $name: not a directory."; | 711 throw "Can't load $joinedPath from within $name: not a directory."; |
| 699 } | 712 } |
| 700 | 713 |
| 701 var sinkStream = new ListInputStream(); | 714 var sinkStream = new ListInputStream(); |
| 702 var tempDir; | 715 var tempDir; |
| 703 // TODO(nweiz): propagate any errors to the return value. See issue 3657. | 716 // TODO(nweiz): propagate any errors to the return value. See issue 3657. |
| 704 createTempDir("pub-test-tmp-").chain((_tempDir) { | 717 createTempDir("pub-test-tmp-").chain((_tempDir) { |
| 705 tempDir = _tempDir; | 718 tempDir = _tempDir; |
| 706 return create(tempDir); | 719 return create(tempDir); |
| 707 }).then((tar) { | 720 }).then((tar) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 722 } | 735 } |
| 723 | 736 |
| 724 /** | 737 /** |
| 725 * Schedules a callback to be called after Pub is run with [runPub], even if it | 738 * Schedules a callback to be called after Pub is run with [runPub], even if it |
| 726 * fails. | 739 * fails. |
| 727 */ | 740 */ |
| 728 void _scheduleCleanup(_ScheduledEvent event) { | 741 void _scheduleCleanup(_ScheduledEvent event) { |
| 729 if (_scheduledCleanup == null) _scheduledCleanup = []; | 742 if (_scheduledCleanup == null) _scheduledCleanup = []; |
| 730 _scheduledCleanup.add(event); | 743 _scheduledCleanup.add(event); |
| 731 } | 744 } |
| OLD | NEW |