Merge pull request #303 from sass/relative-import-from-relative-path

Fix a relative import bug in the JS API
This commit is contained in:
Natalie Weizenbaum 2018-04-21 15:24:57 -07:00 committed by GitHub
commit 2c967f0070
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 55 additions and 52 deletions

View File

@ -15,6 +15,9 @@
`sourceMapContents`, `sourceMapEmbed`, and `sourceMapRoot` options to
`render()` and `renderSync()`.
* Fix a bug where passing a relative path to `render()` or `renderSync()` would
cause relative imports to break.
## 1.2.1
* Always emit units in compressed mode for `0` dimensions other than lengths and

View File

@ -90,6 +90,7 @@ void _render(
/// Converts Sass to CSS asynchronously.
Future<RenderResult> _renderAsync(RenderOptions options) async {
var start = new DateTime.now();
var file = options.file == null ? null : p.absolute(options.file);
CompileResult result;
if (options.data != null) {
result = await compileStringAsync(options.data,
@ -100,10 +101,10 @@ Future<RenderResult> _renderAsync(RenderOptions options) async {
useSpaces: options.indentType != 'tab',
indentWidth: _parseIndentWidth(options.indentWidth),
lineFeed: _parseLineFeed(options.linefeed),
url: options.file == null ? 'stdin' : p.toUri(options.file).toString(),
url: options.file == null ? 'stdin' : p.toUri(file).toString(),
sourceMap: _enableSourceMaps(options));
} else if (options.file != null) {
result = await compileAsync(options.file,
result = await compileAsync(file,
nodeImporter: _parseImporter(options, start),
functions: _parseFunctions(options, asynch: true),
indented: options.indentedSyntax,
@ -128,6 +129,7 @@ Future<RenderResult> _renderAsync(RenderOptions options) async {
RenderResult _renderSync(RenderOptions options) {
try {
var start = new DateTime.now();
var file = options.file == null ? null : p.absolute(options.file);
CompileResult result;
if (options.data != null) {
result = compileString(options.data,
@ -138,11 +140,10 @@ RenderResult _renderSync(RenderOptions options) {
useSpaces: options.indentType != 'tab',
indentWidth: _parseIndentWidth(options.indentWidth),
lineFeed: _parseLineFeed(options.linefeed),
url:
options.file == null ? 'stdin' : p.toUri(options.file).toString(),
url: options.file == null ? 'stdin' : p.toUri(file).toString(),
sourceMap: _enableSourceMaps(options));
} else if (options.file != null) {
result = compile(options.file,
result = compile(file,
nodeImporter: _parseImporter(options, start),
functions: DelegatingList.typed(_parseFunctions(options)),
indented: options.indentedSyntax,

View File

@ -24,10 +24,6 @@ String sassPath;
void main() {
setUpAll(ensureNpmPackage);
setUpAll(() {
// Make sure the module is loaded before we change the working directory.
sass;
});
useSandbox();
setUp(() async {
@ -73,13 +69,7 @@ void main() {
group("import precedence:", () {
group("in sandbox dir", () {
String oldWorkingDirectory;
setUp(() {
oldWorkingDirectory = currentPath;
chdir(sandbox);
});
tearDown(() => chdir(oldWorkingDirectory));
setUp(runTestInSandbox);
test("relative file is #1", () async {
var subDir = p.join(sandbox, 'sub');

View File

@ -8,6 +8,8 @@ import 'package:dart2_constant/convert.dart' as convert;
import 'package:js/js.dart';
import 'package:test/test.dart';
import 'package:sass/src/io.dart';
import '../hybrid.dart';
import 'api.dart';
@ -69,3 +71,14 @@ RenderError renderSyncError(RenderOptions options) {
throw "Expected renderSync() to throw an error.";
}
/// Runs the rest of the test with the working directory in the sandbox
/// directory.
void runTestInSandbox() {
// Make sure the module is loaded before we change the working directory.
sass;
var oldWorkingDirectory = currentPath;
chdir(sandbox);
addTearDown(() => chdir(oldWorkingDirectory));
}

View File

@ -30,28 +30,40 @@ void main() {
group("renderSync()", () {
test("renders a file", () {
expect(renderSync(new RenderOptions(file: sassPath)), equals('''
a {
b: c;
}'''));
expect(renderSync(new RenderOptions(file: sassPath)),
equalsIgnoringWhitespace('a { b: c; }'));
});
test("renders a file from a relative path", () {
runTestInSandbox();
expect(renderSync(new RenderOptions(file: 'test.scss')),
equalsIgnoringWhitespace('a { b: c; }'));
});
test("renders a file with the indented syntax", () async {
var indentedPath = p.join(sandbox, 'test.sass');
await writeTextFile(indentedPath, 'a\n b: c');
expect(renderSync(new RenderOptions(file: indentedPath)), equals('''
a {
b: c;
}'''));
expect(renderSync(new RenderOptions(file: indentedPath)),
equalsIgnoringWhitespace('a { b: c; }'));
});
test("supports relative imports for a file", () async {
var importerPath = p.join(sandbox, 'importer.scss');
await writeTextFile(importerPath, '@import "test"');
expect(renderSync(new RenderOptions(file: importerPath)), equals('''
a {
b: c;
}'''));
expect(renderSync(new RenderOptions(file: importerPath)),
equalsIgnoringWhitespace('a { b: c; }'));
});
// Regression test for #284
test("supports relative imports for a file from a relative path", () async {
await createDirectory(p.join(sandbox, 'subdir'));
var importerPath = p.join(sandbox, 'subdir/importer.scss');
await writeTextFile(importerPath, '@import "../test"');
runTestInSandbox();
expect(renderSync(new RenderOptions(file: 'subdir/importer.scss')),
equalsIgnoringWhitespace('a { b: c; }'));
});
test("supports absolute path imports", () async {
@ -64,10 +76,8 @@ a {
});
test("renders a string", () {
expect(renderSync(new RenderOptions(data: "a {b: c}")), equals('''
a {
b: c;
}'''));
expect(renderSync(new RenderOptions(data: "a {b: c}")),
equalsIgnoringWhitespace('a { b: c; }'));
});
test("one of data and file must be set", () {
@ -80,20 +90,14 @@ a {
expect(
renderSync(new RenderOptions(
data: "@import 'test'", includePaths: [sandbox])),
equals('''
a {
b: c;
}'''));
equalsIgnoringWhitespace('a { b: c; }'));
});
test("can render the indented syntax", () {
expect(
renderSync(
new RenderOptions(data: "a\n b: c", indentedSyntax: true)),
equals('''
a {
b: c;
}'''));
equalsIgnoringWhitespace('a { b: c; }'));
});
test("the indented syntax flag takes precedence over the file extension",
@ -102,20 +106,14 @@ a {
await writeTextFile(scssPath, 'a\n b: c');
expect(
renderSync(new RenderOptions(file: scssPath, indentedSyntax: true)),
equals('''
a {
b: c;
}'''));
equalsIgnoringWhitespace('a { b: c; }'));
});
test("supports the expanded output style", () {
expect(
renderSync(
new RenderOptions(file: sassPath, outputStyle: 'expanded')),
equals('''
a {
b: c;
}'''));
equals('a {\n b: c;\n}'));
});
test("doesn't support other output styles", () {
@ -390,10 +388,8 @@ a {
group("render()", () {
test("renders a file", () async {
expect(await render(new RenderOptions(file: sassPath)), equals('''
a {
b: c;
}'''));
expect(await render(new RenderOptions(file: sassPath)),
equalsIgnoringWhitespace('a { b: c; }'));
});
test("throws an error that has a useful toString", () async {