Add more CLI tests.

This commit is contained in:
Natalie Weizenbaum 2016-12-02 17:30:09 -08:00
parent 7de1b84e8c
commit 8b6548fc61
8 changed files with 158 additions and 13 deletions

View File

@ -21,8 +21,7 @@ main(List<String> args) async {
help: 'Output style.',
allowed: ['expanded'],
defaultsTo: 'expanded')
..addFlag('color',
abbr: 'c', help: 'Whether to emit terminal colors.', defaultsTo: true)
..addFlag('color', abbr: 'c', help: 'Whether to emit terminal colors.')
..addFlag('trace', help: 'Print full Dart stack traces for exceptions.')
..addFlag('help',
abbr: 'h', help: 'Print this usage information.', negatable: false)
@ -46,7 +45,7 @@ main(List<String> args) async {
return;
}
var color = options['color'] as bool;
var color = (options['color'] as bool) ?? hasTerminal;
try {
var css = render(options.rest.first, color: color);
if (css.isNotEmpty) print(css);

View File

@ -20,6 +20,9 @@ class Stderr {
/// The standard error for the current process.
Stderr get stderr => null;
/// Returns whether or not stdout is connected to an interactive terminal.
bool get hasTerminal => false;
/// Reads the file at [path].
String readFile(String path) => null;

View File

@ -44,6 +44,11 @@ external _Stderr get _stderr;
final stderr = new Stderr(_stderr);
bool get hasTerminal => _hasTerminal ?? false;
@JS("process.stdout.isTTY")
external bool get _hasTerminal;
@JS("process.exitCode")
external int get exitCode;

View File

@ -8,6 +8,8 @@ export 'dart:io' show exitCode;
io.Stdout get stderr => io.stderr;
bool get hasTerminal => io.stdout.hasTerminal;
String readFile(String path) => new io.File(path).readAsStringSync();
bool fileExists(String path) => new io.File(path).existsSync();

View File

@ -2,20 +2,97 @@
// MIT-style license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
import 'package:scheduled_test/descriptor.dart' as d;
import 'package:scheduled_test/scheduled_process.dart';
import 'package:scheduled_test/scheduled_stream.dart';
import 'package:scheduled_test/scheduled_test.dart';
import 'utils.dart';
/// Defines test that are shared between the Dart and Node.js CLI test suites.
void sharedTests(
ScheduledProcess startExecutable(List arguments, {workingDirectory})) {
void sharedTests(ScheduledProcess runSass(List arguments)) {
useSandbox();
test("--help prints the usage documentation", () {
// Checking the entire output is brittle, so just do a sanity check to make
// sure it's not totally busted.
var sass = startExecutable(["--help"]);
var sass = runSass(["--help"]);
sass.stdout.expect("Compile Sass to CSS.");
sass.stdout
.expect(consumeThrough(contains("Print this usage information.")));
sass.shouldExit(64);
});
test("compiles a Sass file to CSS", () {
d.file("test.scss", "a {b: 1 + 2}").create();
var sass = runSass(["test.scss", "test.css"]);
sass.stdout.expect(inOrder([
"a {",
" b: 3;",
"}",
]));
sass.shouldExit(0);
});
test("supports relative imports", () {
d.file("test.scss", "@import 'dir/test'").create();
d.dir("dir", [d.file("test.scss", "a {b: 1 + 2}")]).create();
var sass = runSass(["test.scss", "test.css"]);
sass.stdout.expect(inOrder([
"a {",
" b: 3;",
"}",
]));
sass.shouldExit(0);
});
test("gracefully reports syntax errors", () {
d.file("test.scss", "a {b: }").create();
var sass = runSass(["test.scss", "test.css"]);
sass.stderr.expect(inOrder([
"Error: Expected expression.",
"a {b: }",
" ^",
" test.scss 1:7",
]));
sass.shouldExit(65);
});
test("gracefully reports runtime errors", () {
d.file("test.scss", "a {b: 1px + 1deg}").create();
var sass = runSass(["test.scss", "test.css"]);
sass.stderr.expect(inOrder([
"Error: Incompatible units deg and px.",
"a {b: 1px + 1deg}",
" ^^^^^^^^^^",
" test.scss 1:7 root stylesheet",
]));
sass.shouldExit(65);
});
test("reports errors with colors with --color", () {
d.file("test.scss", "a {b: }").create();
var sass = runSass(["--color", "test.scss", "test.css"]);
sass.stderr.expect(inOrder([
"Error: Expected expression.",
"a {b: \u001b[31m\u001b[0m}",
" \u001b[31m^\u001b[0m",
" test.scss 1:7",
]));
sass.shouldExit(65);
});
test("prints full stack traces with --trace", () {
d.file("test.scss", "a {b: }").create();
var sass = runSass(["--trace", "test.scss", "test.css"]);
sass.stderr.expect(consumeThrough(contains("\.dart")));
sass.shouldExit(65);
});
}

View File

@ -4,12 +4,25 @@
import 'dart:io';
import 'package:path/path.dart' as p;
import 'package:scheduled_test/scheduled_process.dart';
import 'package:scheduled_test/scheduled_test.dart';
import 'cli_shared.dart';
import 'utils.dart';
void main() {
sharedTests((arguments, {workingDirectory}) => new ScheduledProcess.start(
Platform.executable, <Object>["bin/sass.dart"]..addAll(arguments),
workingDirectory: workingDirectory, description: "sass"));
sharedTests(_runSass);
test("--version prints the Sass version", () {
var sass = _runSass(["--version"]);
sass.stdout.expect(matches(new RegExp(r"^\d+\.\d+\.\d+")));
sass.shouldExit(0);
});
}
ScheduledProcess _runSass(List arguments) => new ScheduledProcess.start(
Platform.executable,
<Object>[p.absolute("bin/sass.dart")]..addAll(arguments),
workingDirectory: sandbox,
description: "sass");

View File

@ -3,13 +3,14 @@
// https://opensource.org/licenses/MIT.
@Tags(const ['node'])
import 'dart:io';
import 'package:path/path.dart' as p;
import 'package:scheduled_test/scheduled_process.dart';
import 'package:scheduled_test/scheduled_test.dart';
import 'cli_shared.dart';
import 'utils.dart';
void main() {
setUpAll(() {
@ -18,7 +19,16 @@ void main() {
grinder.shouldExit(0);
});
sharedTests((arguments, {workingDirectory}) => new ScheduledProcess.start(
"node", <Object>["build/npm/sass.js"]..addAll(arguments),
workingDirectory: workingDirectory, description: "sass"));
sharedTests(_runSass);
test("--version prints the Sass and dart2js versions", () {
var sass = _runSass(["--version"]);
sass.stdout.expect(matches(
new RegExp(r"^\d+\.\d+\.\d+.* compiled with dart2js \d+\.\d+\.\d+")));
sass.shouldExit(0);
});
}
ScheduledProcess _runSass(List arguments) => new ScheduledProcess.start(
"node", <Object>[p.absolute("build/npm/sass.js")]..addAll(arguments),
workingDirectory: sandbox, description: "sass");

36
test/utils.dart Normal file
View File

@ -0,0 +1,36 @@
// Copyright 2016 Google Inc. Use of this source code is governed by an
// MIT-style license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
import 'dart:io';
import 'package:scheduled_test/descriptor.dart' as d;
import 'package:scheduled_test/scheduled_test.dart';
/// The path to the sandbox directory.
///
/// This is only set in tests for which [useSandbox] is active.
String get sandbox => _sandbox;
String _sandbox;
/// Declares a [setUp] function that creates a sandbox diretory and sets it as
/// the default for scheduled_test's directory descriptors.
///
/// This should be called outside of any tests.
void useSandbox() {
setUp(() {
_sandbox = Directory.systemTemp.createTempSync("dart-sass-test").path;
d.defaultRoot = _sandbox;
currentSchedule.onComplete.schedule(() {
try {
new Directory(_sandbox).deleteSync(recursive: true);
} on IOException catch (_) {
// Silently swallow exceptions on Windows. If the test failed, there may
// still be lingering processes that have files in the sandbox open,
// which will cause this to fail on Windows.
if (!Platform.isWindows) rethrow;
}
}, 'deleting the sandbox directory');
});
}