| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 library scheduled_process_test; | |
| 6 | |
| 7 import 'dart:async'; | |
| 8 import 'dart:io'; | |
| 9 | |
| 10 import 'package:path/path.dart' as path; | |
| 11 import 'package:scheduled_test/scheduled_process.dart'; | |
| 12 import 'package:scheduled_test/scheduled_stream.dart'; | |
| 13 import 'package:scheduled_test/scheduled_test.dart'; | |
| 14 | |
| 15 import 'package:metatest/metatest.dart'; | |
| 16 import 'utils.dart'; | |
| 17 | |
| 18 void main() => initTests(_test); | |
| 19 | |
| 20 void _test(message) { | |
| 21 initMetatest(message); | |
| 22 | |
| 23 setUpTimeout(); | |
| 24 | |
| 25 expectTestsPass("a process must have kill() or shouldExit() called", () { | |
| 26 var errors; | |
| 27 test('test 1', () { | |
| 28 currentSchedule.onException.schedule(() { | |
| 29 errors = currentSchedule.errors; | |
| 30 }); | |
| 31 | |
| 32 startDartProcess('print("hello!");'); | |
| 33 }); | |
| 34 | |
| 35 test('test 2', () { | |
| 36 expect(errors, everyElement(new isInstanceOf<ScheduleError>())); | |
| 37 expect(errors.length, equals(1)); | |
| 38 expect(errors.first.error, isStateError); | |
| 39 expect(errors.first.error.message, matches(r"^Scheduled process " | |
| 40 r"'[^']+[\\/]dart(\.exe)?' must have shouldExit\(\) or kill\(\) " | |
| 41 r"called before the test is run\.$")); | |
| 42 }); | |
| 43 }, passing: ['test 2']); | |
| 44 | |
| 45 expectTestsPass("a process exits with the expected exit code", () { | |
| 46 test('exit code 0', () { | |
| 47 var process = startDartProcess('exitCode = 0;'); | |
| 48 process.shouldExit(0); | |
| 49 }); | |
| 50 | |
| 51 test('exit code 42', () { | |
| 52 var process = startDartProcess('exitCode = 42;'); | |
| 53 process.shouldExit(42); | |
| 54 }); | |
| 55 }); | |
| 56 | |
| 57 expectTestsPass("a process exiting with an unexpected exit code should cause " | |
| 58 "an error", () { | |
| 59 var errors; | |
| 60 test('test 1', () { | |
| 61 currentSchedule.onException.schedule(() { | |
| 62 errors = currentSchedule.errors; | |
| 63 }); | |
| 64 | |
| 65 var process = startDartProcess('exitCode = 1;'); | |
| 66 process.shouldExit(0); | |
| 67 }); | |
| 68 | |
| 69 test('test 2', () { | |
| 70 expect(errors.single, new isInstanceOf<ScheduleError>()); | |
| 71 }); | |
| 72 }, passing: ['test 2']); | |
| 73 | |
| 74 expectTestsPass("a killed process doesn't care about its exit code", () { | |
| 75 test('exit code 0', () { | |
| 76 var process = startDartProcess('exitCode = 0;'); | |
| 77 process.kill(); | |
| 78 }); | |
| 79 | |
| 80 test('exit code 1', () { | |
| 81 var process = startDartProcess('exitCode = 1;'); | |
| 82 process.kill(); | |
| 83 }); | |
| 84 }); | |
| 85 | |
| 86 expectTestsPass("a killed process stops running", () { | |
| 87 test('test', () { | |
| 88 var process = startDartProcess('while (true);'); | |
| 89 process.kill(); | |
| 90 }); | |
| 91 }); | |
| 92 | |
| 93 expectTestsPass("kill can't be called twice", () { | |
| 94 test('test', () { | |
| 95 var process = startDartProcess(''); | |
| 96 process.kill(); | |
| 97 expect(process.kill, throwsA(isStateError)); | |
| 98 }); | |
| 99 }); | |
| 100 | |
| 101 expectTestsPass("kill can't be called after shouldExit", () { | |
| 102 test('test', () { | |
| 103 var process = startDartProcess(''); | |
| 104 process.shouldExit(0); | |
| 105 expect(process.kill, throwsA(isStateError)); | |
| 106 }); | |
| 107 }); | |
| 108 | |
| 109 expectTestsPass("shouldExit can't be called twice", () { | |
| 110 test('test', () { | |
| 111 var process = startDartProcess(''); | |
| 112 process.shouldExit(0); | |
| 113 expect(() => process.shouldExit(0), throwsA(isStateError)); | |
| 114 }); | |
| 115 }); | |
| 116 | |
| 117 expectTestsPass("shouldExit can't be called after kill", () { | |
| 118 test('test', () { | |
| 119 var process = startDartProcess(''); | |
| 120 process.kill(); | |
| 121 expect(() => process.shouldExit(0), throwsA(isStateError)); | |
| 122 }); | |
| 123 }); | |
| 124 | |
| 125 expectTestsPass("a process that ends while waiting for stdout shouldn't " | |
| 126 "block the test", () { | |
| 127 var errors; | |
| 128 test('test 1', () { | |
| 129 currentSchedule.onException.schedule(() { | |
| 130 errors = currentSchedule.errors; | |
| 131 }); | |
| 132 | |
| 133 var process = startDartProcess(''); | |
| 134 process.stdout.expect('hello'); | |
| 135 process.stdout.expect('world'); | |
| 136 process.shouldExit(0); | |
| 137 }); | |
| 138 | |
| 139 test('test 2', () { | |
| 140 expect(errors, everyElement(new isInstanceOf<ScheduleError>())); | |
| 141 expect(errors.length, anyOf(1, 2)); | |
| 142 expect(errors[0].error, new isInstanceOf<TestFailure>()); | |
| 143 expect(errors[0].error.message, equals( | |
| 144 "Expected: 'hello'\n" | |
| 145 " Emitted: \n" | |
| 146 " Which: unexpected end of stream")); | |
| 147 | |
| 148 // Whether or not this error appears depends on how quickly the "no | |
| 149 // elements" error is handled. | |
| 150 if (errors.length == 2) { | |
| 151 expect(errors[1].error.toString(), matches(r"^Process " | |
| 152 r"'[^']+[\\/]dart(\.exe)? [^']+' ended earlier than scheduled with " | |
| 153 r"exit code 0\.")); | |
| 154 } | |
| 155 }); | |
| 156 }, passing: ['test 2']); | |
| 157 | |
| 158 expectTestsPass("a process that ends during the task immediately before it's " | |
| 159 "scheduled to end shouldn't cause an error", () { | |
| 160 test('test', () { | |
| 161 var process = startDartProcess('stdin.toList();'); | |
| 162 process.closeStdin(); | |
| 163 // Unfortunately, sleeping for a second seems like the best way of | |
| 164 // guaranteeing that the process ends during this task. | |
| 165 schedule(() => new Future.delayed(new Duration(seconds: 1))); | |
| 166 process.shouldExit(0); | |
| 167 }); | |
| 168 }); | |
| 169 | |
| 170 expectTestsPass("stdout exposes the standard output from the process", () { | |
| 171 test('test', () { | |
| 172 var process = startDartProcess(r'print("hello\n\nworld"); print("hi");'); | |
| 173 process.stdout.expect('hello'); | |
| 174 process.stdout.expect(''); | |
| 175 process.stdout.expect('world'); | |
| 176 process.stdout.expect('hi'); | |
| 177 process.stdout.expect(isDone); | |
| 178 process.shouldExit(0); | |
| 179 }); | |
| 180 }); | |
| 181 | |
| 182 expectTestsPass("stderr exposes the stderr from the process", () { | |
| 183 test('test', () { | |
| 184 var process = startDartProcess(r''' | |
| 185 stderr.write("hello\n\nworld\n"); | |
| 186 stderr.write("hi"); | |
| 187 '''); | |
| 188 process.stderr.expect('hello'); | |
| 189 process.stderr.expect(''); | |
| 190 process.stderr.expect('world'); | |
| 191 process.stderr.expect('hi'); | |
| 192 process.stderr.expect(isDone); | |
| 193 process.shouldExit(0); | |
| 194 }); | |
| 195 }); | |
| 196 | |
| 197 expectTestsPass("writeLine schedules a line to be written to the process", | |
| 198 () { | |
| 199 test('test', () { | |
| 200 var process = startDartProcess(r''' | |
| 201 stdinLines.listen((line) => print("> $line")); | |
| 202 '''); | |
| 203 process.writeLine("hello"); | |
| 204 process.stdout.expect("> hello"); | |
| 205 process.writeLine("world"); | |
| 206 process.stdout.expect("> world"); | |
| 207 process.kill(); | |
| 208 }); | |
| 209 }); | |
| 210 | |
| 211 expectTestsPass("closeStdin closes the process's stdin stream", () { | |
| 212 test('test', () { | |
| 213 var process = startDartProcess(r''' | |
| 214 stdin.listen((line) => print("> $line"), | |
| 215 onDone: () => print("stdin closed")); | |
| 216 '''); | |
| 217 process.closeStdin(); | |
| 218 process.shouldExit(0); | |
| 219 process.stdout.expect('stdin closed'); | |
| 220 }); | |
| 221 }); | |
| 222 } | |
| 223 | |
| 224 ScheduledProcess startDartProcess(String script) { | |
| 225 var tempDir = schedule(() => Directory.systemTemp | |
| 226 .createTemp('scheduled_process_test_') | |
| 227 .then((dir) => dir.path), | |
| 228 'create temp dir'); | |
| 229 var dartPath = schedule(() { | |
| 230 return tempDir.then((dir) { | |
| 231 return new File(path.join(dir, 'test.dart')).writeAsString(''' | |
| 232 import 'dart:async'; | |
| 233 import 'dart:convert'; | |
| 234 import 'dart:io'; | |
| 235 | |
| 236 var stdinLines = stdin | |
| 237 .transform(UTF8.decoder) | |
| 238 .transform(new LineSplitter()); | |
| 239 | |
| 240 void main() { | |
| 241 $script | |
| 242 } | |
| 243 ''').then((file) => file.path); | |
| 244 }); | |
| 245 }, 'write script file'); | |
| 246 | |
| 247 currentSchedule.onComplete.schedule(() { | |
| 248 return tempDir.catchError((_) => null).then((dir) { | |
| 249 if (dir == null) return null; | |
| 250 return new Directory(dir).delete(recursive: true); | |
| 251 }); | |
| 252 }, 'clean up temp dir'); | |
| 253 | |
| 254 return new ScheduledProcess.start(Platform.executable, | |
| 255 ['--checked', dartPath]); | |
| 256 } | |
| OLD | NEW |