Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(738)

Unified Diff: pkg/scheduled_test/test/scheduled_process_test.dart

Issue 12377093: Add a ScheduledProcess class to pkg/scheduled_test. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/scheduled_test/test/scheduled_process_test.dart
diff --git a/pkg/scheduled_test/test/scheduled_process_test.dart b/pkg/scheduled_test/test/scheduled_process_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..d961ff06f03435271b2ae604006aa126d87a60fe
--- /dev/null
+++ b/pkg/scheduled_test/test/scheduled_process_test.dart
@@ -0,0 +1,376 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library scheduled_process_test;
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:pathos/path.dart' as path;
+import 'package:scheduled_test/scheduled_process.dart';
+import 'package:scheduled_test/scheduled_test.dart';
+import 'package:scheduled_test/src/mock_clock.dart' as mock_clock;
+
+import 'metatest.dart';
+import 'utils.dart';
+
+ServerSocket backChannel;
+
+void main() {
+ expectTestsPass("a process must have kill() or shouldExit() called", () {
+ var errors;
+ test('test 1', () {
+ currentSchedule.onException.schedule(() {
+ errors = currentSchedule.errors;
+ });
+
+ startDartProcess('print("hello!");');
+ });
+
+ test('test 2', () {
+ expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+ expect(errors.length, equals(1));
+ expect(errors.first.error, isStateError);
+ expect(errors.first.error.message, matches(r"^Scheduled process "
+ r"'[^']+[\\/]dart' must have shouldExit\(\) or kill\(\) called "
+ r"before the test is run\.$"));
+ });
+ }, passing: ['test 2']);
+
+ expectTestsPass("a process exits with the expected exit code", () {
+ test('exit code 0', () {
+ var process = startDartProcess('exitCode = 0;');
+ process.shouldExit(0);
+ });
+
+ test('exit code 42', () {
+ var process = startDartProcess('exitCode = 42;');
+ process.shouldExit(42);
+ });
+ });
+
+ expectTestsPass("a process exiting with an unexpected exit code should cause "
+ "an error", () {
+ var errors;
+ test('test 1', () {
+ currentSchedule.onException.schedule(() {
+ errors = currentSchedule.errors;
+ });
+
+ var process = startDartProcess('exitCode = 1;');
+ process.shouldExit(0);
+ });
+
+ test('test 2', () {
+ expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+ expect(errors.length, equals(1));
+ expect(errors.first.error, new isInstanceOf<TestFailure>());
+ });
+ }, passing: ['test 2']);
+
+ expectTestsPass("a killed process doesn't care about its exit code", () {
+ test('exit code 0', () {
+ var process = startDartProcess('exitCode = 0;');
+ process.kill();
+ });
+
+ test('exit code 1', () {
+ var process = startDartProcess('exitCode = 1;');
+ process.kill();
+ });
+ });
+
+ expectTestsPass("a killed process stops running", () {
+ test('test', () {
+ var process = startDartProcess('while (true);');
+ process.kill();
+ });
+ });
+
+ expectTestsPass("kill can't be called twice", () {
+ test('test', () {
+ var process = startDartProcess('');
+ process.kill();
+ expect(process.kill, throwsA(isStateError));
+ });
+ });
+
+ expectTestsPass("kill can't be called after shouldExit", () {
+ test('test', () {
+ var process = startDartProcess('');
+ process.shouldExit(0);
+ expect(process.kill, throwsA(isStateError));
+ });
+ });
+
+ expectTestsPass("shouldExit can't be called twice", () {
+ test('test', () {
+ var process = startDartProcess('');
+ process.shouldExit(0);
+ expect(() => process.shouldExit(0), throwsA(isStateError));
+ });
+ });
+
+ expectTestsPass("shouldExit can't be called after kill", () {
+ test('test', () {
+ var process = startDartProcess('');
+ process.kill();
+ expect(() => process.shouldExit(0), throwsA(isStateError));
+ });
+ });
+
+ expectTestsPass("a process that ends while waiting for stdout shouldn't "
+ "block the test", () {
+ var errors;
+ test('test 1', () {
+ currentSchedule.onException.schedule(() {
+ errors = currentSchedule.errors;
+ });
+
+ var process = startDartProcess('');
+ expect(process.nextLine(), completion(equals('hello')));
+ expect(process.nextLine(), completion(equals('world')));
+ process.shouldExit(0);
+ });
+
+ test('test 2', () {
+ expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+ expect(errors.length, equals(2));
+ expect(errors[0].error, isStateError);
+ expect(errors[0].error.message, equals("No elements"));
+ expect(errors[1].error, matches(r"^Process '[^']+[\\/]dart [^']+' ended "
+ r"earlier than scheduled with exit code 0\."));
+ });
+ }, passing: ['test 2']);
+
+ expectTestsPass("a process that ends during the task immediately before it's "
+ "scheduled to end shouldn't cause an error", () {
+ test('test', () {
+ var process = startDartProcess('stdin.toList();');
+ process.closeStdin();
+ // Unfortunately, sleeping for a second seems like the best way of
+ // guaranteeing that the process ends during this task.
+ schedule(() => new Future.delayed(new Duration(seconds: 1)));
+ process.shouldExit(0);
+ });
+ });
+
+ expectTestsPass("nextLine returns the next line of stdout from the process",
+ () {
+ test('test', () {
+ var process = startDartProcess(r'print("hello\n\nworld"); print("hi");');
+ expect(process.nextLine(), completion(equals('hello')));
+ expect(process.nextLine(), completion(equals('')));
+ expect(process.nextLine(), completion(equals('world')));
+ expect(process.nextLine(), completion(equals('hi')));
+ process.shouldExit(0);
+ });
+ });
+
+ expectTestsPass("nextLine throws an error if there's no more stdout", () {
+ var errors;
+ test('test 1', () {
+ currentSchedule.onException.schedule(() {
+ errors = currentSchedule.errors;
+ });
+
+ var process = startDartProcess('print("hello");');
+ expect(process.nextLine(), completion(equals('hello')));
+ expect(process.nextLine(), completion(equals('world')));
+ process.shouldExit(0);
+ });
+
+ test('test 2', () {
+ expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+ expect(errors.length, equals(2));
+ expect(errors[0].error, isStateError);
+ expect(errors[0].error.message, equals("No elements"));
+ expect(errors[1].error, matches(r"^Process '[^']+[\\/]dart [^']+' ended "
+ r"earlier than scheduled with exit code 0\."));
+ });
+ }, passing: ['test 2']);
+
+ expectTestsPass("nextErrLine returns the next line of stderr from the "
+ "process", () {
+ test('test', () {
+ var process = startDartProcess(r'''
+ stderr.addString("hello\n\nworld\n");
+ stderr.addString("hi");
+ ''');
+ expect(process.nextErrLine(), completion(equals('hello')));
+ expect(process.nextErrLine(), completion(equals('')));
+ expect(process.nextErrLine(), completion(equals('world')));
+ expect(process.nextErrLine(), completion(equals('hi')));
+ process.shouldExit(0);
+ });
+ });
+
+ expectTestsPass("nextErrLine throws an error if there's no more stderr", () {
+ var errors;
+ test('test 1', () {
+ currentSchedule.onException.schedule(() {
+ errors = currentSchedule.errors;
+ });
+
+ var process = startDartProcess(r'stderr.addString("hello\n");');
+ expect(process.nextErrLine(), completion(equals('hello')));
+ expect(process.nextErrLine(), completion(equals('world')));
+ process.shouldExit(0);
+ });
+
+ test('test 2', () {
+ expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+ expect(errors.length, equals(2));
+ expect(errors[0].error, isStateError);
+ expect(errors[0].error.message, equals("No elements"));
+ expect(errors[1].error, matches(r"^Process '[^']+[\\/]dart [^']+' ended "
+ r"earlier than scheduled with exit code 0\."));
+ });
+ }, passing: ['test 2']);
+
+ expectTestsPass("remainingStdout returns all the stdout if it's not consumed "
+ "any other way", () {
+ test('test', () {
+ var process = startDartProcess(r'print("hello\n\nworld"); print("hi");');
+ process.shouldExit(0);
+ expect(process.remainingStdout(),
+ completion(equals("hello\n\nworld\nhi")));
+ });
+ });
+
+ expectTestsPass("remainingStdout returns the empty string if there's no "
+ "stdout", () {
+ test('test', () {
+ var process = startDartProcess(r'');
+ process.shouldExit(0);
+ expect(process.remainingStdout(), completion(isEmpty));
+ });
+ });
+
+ expectTestsPass("remainingStdout returns the remaining stdout after the "
+ "lines consumed by nextLine", () {
+ test('test', () {
+ var process = startDartProcess(r'print("hello\n\nworld"); print("hi");');
+ expect(process.nextLine(), completion(equals("hello")));
+ expect(process.nextLine(), completion(equals("")));
+ process.shouldExit(0);
+ expect(process.remainingStdout(), completion(equals("world\nhi")));
+ });
+ });
+
+ expectTestsPass("remainingStdout can't be called before the process is "
+ "scheduled to end", () {
+ test('test', () {
+ var process = startDartProcess(r'');
+ expect(process.remainingStdout, throwsA(isStateError));
+ process.shouldExit(0);
+ });
+ });
+
+ expectTestsPass("remainingStderr returns all the stderr if it's not consumed "
+ "any other way", () {
+ test('test', () {
+ var process = startDartProcess(r'''
+ stderr.addString("hello\n\nworld\n");
+ stderr.addString("hi\n");
+ ''');
+ process.shouldExit(0);
+ expect(process.remainingStderr(),
+ completion(equals("hello\n\nworld\nhi")));
+ });
+ });
+
+ expectTestsPass("remainingStderr returns the empty string if there's no "
+ "stderr", () {
+ test('test', () {
+ var process = startDartProcess(r'');
+ process.shouldExit(0);
+ expect(process.remainingStderr(), completion(isEmpty));
+ });
+ });
+
+ expectTestsPass("remainingStderr returns the remaining stderr after the "
+ "lines consumed by nextLine", () {
+ test('test', () {
+ var process = startDartProcess(r'''
+ stderr.addString("hello\n\nworld\n");
+ stderr.addString("hi\n");
+ ''');
+ expect(process.nextErrLine(), completion(equals("hello")));
+ expect(process.nextErrLine(), completion(equals("")));
+ process.shouldExit(0);
+ expect(process.remainingStderr(), completion(equals("world\nhi")));
+ });
+ });
+
+ expectTestsPass("remainingStderr can't be called before the process is "
+ "scheduled to end", () {
+ test('test', () {
+ var process = startDartProcess(r'');
+ expect(process.remainingStderr, throwsA(isStateError));
+ process.shouldExit(0);
+ });
+ });
+
+ expectTestsPass("writeLine schedules a line to be written to the process",
+ () {
+ test('test', () {
+ var process = startDartProcess(r'''
+ stdinLines.listen((line) => print("> $line"));
+ ''');
+ process.writeLine("hello");
+ expect(process.nextLine(), completion(equals("> hello")));
+ process.writeLine("world");
+ expect(process.nextLine(), completion(equals("> world")));
+ process.kill();
+ });
+ });
+
+ expectTestsPass("closeStdin closes the process's stdin stream", () {
+ test('test', () {
+ currentSchedule.timeout = new Duration(seconds: 1);
+ var process = startDartProcess(r'''
+ stdin.listen((line) => print("> $line"),
+ onDone: () => print("stdin closed"));
+ ''');
+ process.closeStdin();
+ process.shouldExit(0);
+ expect(process.nextLine(), completion(equals('stdin closed')));
+ });
+ });
+}
+
+ScheduledProcess startDartProcess(String script) {
+ var tempDir = schedule(() {
+ return new Directory('').createTemp().then((dir) => dir.path);
Bob Nystrom 2013/03/04 23:52:00 Create this synchronously.
nweiz 2013/03/05 02:16:09 Why? It wouldn't clean up the code at all.
Bob Nystrom 2013/03/05 17:35:06 Couldn't you save a schedule() step here and creat
nweiz 2013/03/08 22:38:09 No, we need to access it from multiple schedule bl
+ }, 'create temp dir');
+
+ var dartPath = schedule(() {
+ return tempDir.then((dir) {
+ var utilsPath = path.absolute(path.join(
+ new Options().script, 'utils.dart'));
+ return new File(path.join(dir, 'test.dart')).writeAsString('''
+ import 'dart:async';
+ import 'dart:io';
+
+ var stdinLines = stdin
+ .transform(new StringDecoder())
+ .transform(new LineTransformer());
+
+ void main() {
+ $script
+ }
+ ''').then((file) => file.path);
+ });
+ }, 'write script file');
+
+ currentSchedule.onComplete.schedule(() {
+ return tempDir.catchError((_) => null).then((dir) {
+ if (dir == null) return;
+ return new Directory(dir).delete(recursive: true);
+ });
+ }, 'clean up temp dir');
+
+ return new ScheduledProcess.start(dartExecutable, ['--checked', dartPath]);
+}

Powered by Google App Engine
This is Rietveld 408576698