mirror of
https://github.com/danog/dart-sass.git
synced 2025-01-21 21:31:11 +01:00
parent
ed1d6ef6b1
commit
a003e5c31f
16
CHANGELOG.md
16
CHANGELOG.md
@ -5,6 +5,22 @@
|
|||||||
* Don't crash when evaluating CSS variables whose names are entirely
|
* Don't crash when evaluating CSS variables whose names are entirely
|
||||||
interpolated (for example, `#{--foo}: ...`).
|
interpolated (for example, `#{--foo}: ...`).
|
||||||
|
|
||||||
|
### Dart API
|
||||||
|
|
||||||
|
* Added an `Importer` class. This can be extended by users to provide support
|
||||||
|
for custom resolution for `@import` rules.
|
||||||
|
|
||||||
|
* Added built-in `FilesystemImporter` and `PackageImporter` implementations that
|
||||||
|
support resolving `file:` and `package:` URLs, respectively.
|
||||||
|
|
||||||
|
* Added an `importers` argument to the `compile()` and `compileString()`
|
||||||
|
functions that provides `Importer`s to use when resolving `@import` rules.
|
||||||
|
|
||||||
|
* Added a `loadPaths` argument to the `compile()` and `compileString()`
|
||||||
|
functions that provides paths to search for stylesheets when resolving
|
||||||
|
`@import` rules. This is a shorthand for passing `FilesystemImporter`s to the
|
||||||
|
`importers` argument.
|
||||||
|
|
||||||
## 1.0.0-beta.2
|
## 1.0.0-beta.2
|
||||||
|
|
||||||
* Add support for the `::slotted()` pseudo-element.
|
* Add support for the `::slotted()` pseudo-element.
|
||||||
|
@ -4,22 +4,46 @@
|
|||||||
|
|
||||||
import 'src/compile.dart' as c;
|
import 'src/compile.dart' as c;
|
||||||
import 'src/exception.dart';
|
import 'src/exception.dart';
|
||||||
|
import 'src/importer.dart';
|
||||||
import 'src/sync_package_resolver.dart';
|
import 'src/sync_package_resolver.dart';
|
||||||
|
|
||||||
|
export 'src/importer.dart';
|
||||||
|
export 'src/importer/filesystem.dart';
|
||||||
|
export 'src/importer/package.dart';
|
||||||
|
export 'src/importer/result.dart';
|
||||||
|
|
||||||
/// Loads the Sass file at [path], compiles it to CSS, and returns the result.
|
/// Loads the Sass file at [path], compiles it to CSS, and returns the result.
|
||||||
///
|
///
|
||||||
/// If [color] is `true`, this will use terminal colors in warnings.
|
/// If [color] is `true`, this will use terminal colors in warnings.
|
||||||
///
|
///
|
||||||
/// If [packageResolver] is provided, it's used to resolve `package:` imports.
|
/// Imports are resolved by trying, in order:
|
||||||
/// Otherwise, they aren't supported. It takes a [SyncPackageResolver][] from
|
///
|
||||||
/// the `package_resolver` package.
|
/// * Loading a file relative to [path].
|
||||||
|
///
|
||||||
|
/// * Each importer in [importers].
|
||||||
|
///
|
||||||
|
/// * Each load path in [loadPaths]. Note that this is a shorthand for adding
|
||||||
|
/// [FilesystemImporter]s to [importers].
|
||||||
|
///
|
||||||
|
/// * `package:` resolution using [packageResolver], which is a
|
||||||
|
/// [SyncPackageResolver][] from the `package_resolver` package. Note that
|
||||||
|
/// this is a shorthand for adding a [PackageImporter] to [importers].
|
||||||
///
|
///
|
||||||
/// [SyncPackageResolver]: https://www.dartdocs.org/documentation/package_resolver/latest/package_resolver/SyncPackageResolver-class.html
|
/// [SyncPackageResolver]: https://www.dartdocs.org/documentation/package_resolver/latest/package_resolver/SyncPackageResolver-class.html
|
||||||
///
|
///
|
||||||
/// Throws a [SassException] if conversion fails.
|
/// Throws a [SassException] if conversion fails.
|
||||||
String compile(String path,
|
String compile(String path,
|
||||||
{bool color: false, SyncPackageResolver packageResolver}) =>
|
{bool color: false,
|
||||||
c.compile(path, color: color, packageResolver: packageResolver).css;
|
Iterable<Importer> importers,
|
||||||
|
Iterable<String> loadPaths,
|
||||||
|
SyncPackageResolver packageResolver}) {
|
||||||
|
var result = c.compile(path,
|
||||||
|
color: color,
|
||||||
|
importers: importers,
|
||||||
|
loadPaths: loadPaths,
|
||||||
|
packageResolver: packageResolver);
|
||||||
|
return result.css;
|
||||||
|
}
|
||||||
|
|
||||||
/// Compiles [source] to CSS and returns the result.
|
/// Compiles [source] to CSS and returns the result.
|
||||||
///
|
///
|
||||||
@ -27,25 +51,41 @@ String compile(String path,
|
|||||||
/// otherwise (and by default) it uses SCSS. If [color] is `true`, this will use
|
/// otherwise (and by default) it uses SCSS. If [color] is `true`, this will use
|
||||||
/// terminal colors in warnings.
|
/// terminal colors in warnings.
|
||||||
///
|
///
|
||||||
/// If [packageResolver] is provided, it's used to resolve `package:` imports.
|
/// Imports are resolved by trying, in order:
|
||||||
/// Otherwise, they aren't supported. It takes a [SyncPackageResolver][] from
|
///
|
||||||
/// the `package_resolver` package.
|
/// * The given [importer], with the imported URL resolved relative to [url].
|
||||||
|
///
|
||||||
|
/// * Each importer in [importers].
|
||||||
|
///
|
||||||
|
/// * Each load path in [loadPaths]. Note that this is a shorthand for adding
|
||||||
|
/// [FilesystemImporter]s to [importers].
|
||||||
|
///
|
||||||
|
/// * `package:` resolution using [packageResolver], which is a
|
||||||
|
/// [SyncPackageResolver][] from the `package_resolver` package. Note that
|
||||||
|
/// this is a shorthand for adding a [PackageImporter] to [importers].
|
||||||
///
|
///
|
||||||
/// [SyncPackageResolver]: https://www.dartdocs.org/documentation/package_resolver/latest/package_resolver/SyncPackageResolver-class.html
|
/// [SyncPackageResolver]: https://www.dartdocs.org/documentation/package_resolver/latest/package_resolver/SyncPackageResolver-class.html
|
||||||
///
|
///
|
||||||
/// The [url] indicates the location from which [source] was loaded. It may may
|
/// The [url] indicates the location from which [source] was loaded. It may be a
|
||||||
/// be a [String] or a [Uri].
|
/// [String] or a [Uri]. If [importer] is passed, [url] must be passed as well
|
||||||
|
/// and `importer.load(url)` should return `source`.
|
||||||
///
|
///
|
||||||
/// Throws a [SassException] if conversion fails.
|
/// Throws a [SassException] if conversion fails.
|
||||||
String compileString(String source,
|
String compileString(String source,
|
||||||
{bool indented: false,
|
{bool indented: false,
|
||||||
bool color: false,
|
bool color: false,
|
||||||
|
Iterable<Importer> importers,
|
||||||
|
Iterable<String> loadPaths,
|
||||||
SyncPackageResolver packageResolver,
|
SyncPackageResolver packageResolver,
|
||||||
|
Importer importer,
|
||||||
url}) {
|
url}) {
|
||||||
var result = c.compileString(source,
|
var result = c.compileString(source,
|
||||||
indented: indented,
|
indented: indented,
|
||||||
color: color,
|
color: color,
|
||||||
|
importers: importers,
|
||||||
|
loadPaths: loadPaths,
|
||||||
packageResolver: packageResolver,
|
packageResolver: packageResolver,
|
||||||
|
importer: importer,
|
||||||
url: url);
|
url: url);
|
||||||
return result.css;
|
return result.css;
|
||||||
}
|
}
|
||||||
|
113
test/dart_api/importer_test.dart
Normal file
113
test/dart_api/importer_test.dart
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
// Copyright 2017 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.
|
||||||
|
|
||||||
|
@TestOn('vm')
|
||||||
|
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
import 'package:sass/sass.dart';
|
||||||
|
import 'package:sass/src/exception.dart';
|
||||||
|
|
||||||
|
main() {
|
||||||
|
test("uses an importer to resolve an @import", () {
|
||||||
|
var css = compileString('@import "orange";', importers: [
|
||||||
|
new _TestImporter((url) => url, (url) {
|
||||||
|
return new ImporterResult('.$url {color: $url}', indented: false);
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(css, equals(".orange {\n color: orange;\n}"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("passes the canonicalized URL to the importer", () {
|
||||||
|
var css = compileString('@import "orange";', importers: [
|
||||||
|
new _TestImporter((url) => new Uri(path: 'blue'), (url) {
|
||||||
|
return new ImporterResult('.$url {color: $url}', indented: false);
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(css, equals(".blue {\n color: blue;\n}"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("only invokes the importer once for a given canonicalization", () {
|
||||||
|
var css = compileString("""
|
||||||
|
@import "orange";
|
||||||
|
@import "orange";
|
||||||
|
""", importers: [
|
||||||
|
new _TestImporter(
|
||||||
|
(url) => new Uri(path: 'blue'),
|
||||||
|
expectAsync1((url) {
|
||||||
|
return new ImporterResult('.$url {color: $url}', indented: false);
|
||||||
|
}, count: 1))
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(css, equals("""
|
||||||
|
.blue {
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blue {
|
||||||
|
color: blue;
|
||||||
|
}"""));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("wraps an error in canonicalize()", () {
|
||||||
|
expect(() {
|
||||||
|
compileString('@import "orange";', importers: [
|
||||||
|
new _TestImporter((url) {
|
||||||
|
throw "this import is bad actually";
|
||||||
|
}, expectAsync1((_) => null, count: 0))
|
||||||
|
]);
|
||||||
|
}, throwsA(predicate((error) {
|
||||||
|
expect(error, new isInstanceOf<SassException>());
|
||||||
|
expect(
|
||||||
|
error.toString(), startsWith("Error: this import is bad actually"));
|
||||||
|
return true;
|
||||||
|
})));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("wraps an error in load()", () {
|
||||||
|
expect(() {
|
||||||
|
compileString('@import "orange";', importers: [
|
||||||
|
new _TestImporter((url) => url, (url) {
|
||||||
|
throw "this import is bad actually";
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
}, throwsA(predicate((error) {
|
||||||
|
expect(error, new isInstanceOf<SassException>());
|
||||||
|
expect(
|
||||||
|
error.toString(), startsWith("Error: this import is bad actually"));
|
||||||
|
return true;
|
||||||
|
})));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("prefers .message to .toString() for an importer error", () {
|
||||||
|
expect(() {
|
||||||
|
compileString('@import "orange";', importers: [
|
||||||
|
new _TestImporter((url) => url, (url) {
|
||||||
|
throw new FormatException("bad format somehow");
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
}, throwsA(predicate((error) {
|
||||||
|
expect(error, new isInstanceOf<SassException>());
|
||||||
|
// FormatException.toString() starts with "FormatException:", but
|
||||||
|
// the error message should not.
|
||||||
|
expect(error.toString(), startsWith("Error: bad format somehow"));
|
||||||
|
return true;
|
||||||
|
})));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An [Importer] whose [canonicalize] and [load] methods are provided by
|
||||||
|
/// closures.
|
||||||
|
class _TestImporter extends Importer {
|
||||||
|
final Uri Function(Uri url) _canonicalize;
|
||||||
|
final ImporterResult Function(Uri url) _load;
|
||||||
|
|
||||||
|
_TestImporter(this._canonicalize, this._load);
|
||||||
|
|
||||||
|
Uri canonicalize(Uri url) => _canonicalize(url);
|
||||||
|
|
||||||
|
ImporterResult load(Uri url) => _load(url);
|
||||||
|
}
|
175
test/dart_api_test.dart
Normal file
175
test/dart_api_test.dart
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
// Copyright 2017 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.
|
||||||
|
|
||||||
|
@TestOn('vm')
|
||||||
|
|
||||||
|
import 'package:package_resolver/package_resolver.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
import 'package:test_descriptor/test_descriptor.dart' as d;
|
||||||
|
|
||||||
|
import 'package:sass/sass.dart';
|
||||||
|
import 'package:sass/src/exception.dart';
|
||||||
|
import 'package:sass/src/util/path.dart';
|
||||||
|
|
||||||
|
main() {
|
||||||
|
group("importers", () {
|
||||||
|
test("is used to resolve imports", () async {
|
||||||
|
await d.dir("subdir", [d.file("subtest.scss", "a {b: c}")]).create();
|
||||||
|
await d.file("test.scss", '@import "subtest.scss";').create();
|
||||||
|
|
||||||
|
var css = compile(p.join(d.sandbox, "test.scss"),
|
||||||
|
importers: [new FilesystemImporter(p.join(d.sandbox, 'subdir'))]);
|
||||||
|
expect(css, equals("a {\n b: c;\n}"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("are checked in order", () async {
|
||||||
|
await d
|
||||||
|
.dir("first", [d.file("other.scss", "a {b: from-first}")]).create();
|
||||||
|
await d
|
||||||
|
.dir("second", [d.file("other.scss", "a {b: from-second}")]).create();
|
||||||
|
await d.file("test.scss", '@import "other";').create();
|
||||||
|
|
||||||
|
var css = compile(p.join(d.sandbox, "test.scss"), importers: [
|
||||||
|
new FilesystemImporter(p.join(d.sandbox, 'first')),
|
||||||
|
new FilesystemImporter(p.join(d.sandbox, 'second'))
|
||||||
|
]);
|
||||||
|
expect(css, equals("a {\n b: from-first;\n}"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group("loadPaths", () {
|
||||||
|
test("is used to import file: URLs", () async {
|
||||||
|
await d.dir("subdir", [d.file("subtest.scss", "a {b: c}")]).create();
|
||||||
|
await d.file("test.scss", '@import "subtest.scss";').create();
|
||||||
|
|
||||||
|
var css = compile(p.join(d.sandbox, "test.scss"),
|
||||||
|
loadPaths: [p.join(d.sandbox, 'subdir')]);
|
||||||
|
expect(css, equals("a {\n b: c;\n}"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("can import partials", () async {
|
||||||
|
await d.dir("subdir", [d.file("_subtest.scss", "a {b: c}")]).create();
|
||||||
|
await d.file("test.scss", '@import "subtest.scss";').create();
|
||||||
|
|
||||||
|
var css = compile(p.join(d.sandbox, "test.scss"),
|
||||||
|
loadPaths: [p.join(d.sandbox, 'subdir')]);
|
||||||
|
expect(css, equals("a {\n b: c;\n}"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("adds a .scss extension", () async {
|
||||||
|
await d.dir("subdir", [d.file("subtest.scss", "a {b: c}")]).create();
|
||||||
|
await d.file("test.scss", '@import "subtest";').create();
|
||||||
|
|
||||||
|
var css = compile(p.join(d.sandbox, "test.scss"),
|
||||||
|
loadPaths: [p.join(d.sandbox, 'subdir')]);
|
||||||
|
expect(css, equals("a {\n b: c;\n}"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("adds a .sass extension", () async {
|
||||||
|
await d.dir("subdir", [d.file("subtest.sass", "a\n b: c")]).create();
|
||||||
|
await d.file("test.scss", '@import "subtest";').create();
|
||||||
|
|
||||||
|
var css = compile(p.join(d.sandbox, "test.scss"),
|
||||||
|
loadPaths: [p.join(d.sandbox, 'subdir')]);
|
||||||
|
expect(css, equals("a {\n b: c;\n}"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("are checked in order", () async {
|
||||||
|
await d
|
||||||
|
.dir("first", [d.file("other.scss", "a {b: from-first}")]).create();
|
||||||
|
await d
|
||||||
|
.dir("second", [d.file("other.scss", "a {b: from-second}")]).create();
|
||||||
|
await d.file("test.scss", '@import "other";').create();
|
||||||
|
|
||||||
|
var css = compile(p.join(d.sandbox, "test.scss"),
|
||||||
|
loadPaths: [p.join(d.sandbox, 'first'), p.join(d.sandbox, 'second')]);
|
||||||
|
expect(css, equals("a {\n b: from-first;\n}"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group("packageResolver", () {
|
||||||
|
test("is used to import package: URLs", () async {
|
||||||
|
await d.dir("subdir", [d.file("test.scss", "a {b: 1 + 2}")]).create();
|
||||||
|
|
||||||
|
await d
|
||||||
|
.file("test.scss", '@import "package:fake_package/test";')
|
||||||
|
.create();
|
||||||
|
var resolver = new SyncPackageResolver.config(
|
||||||
|
{"fake_package": p.toUri(p.join(d.sandbox, 'subdir'))});
|
||||||
|
|
||||||
|
var css =
|
||||||
|
compile(p.join(d.sandbox, "test.scss"), packageResolver: resolver);
|
||||||
|
expect(css, equals("a {\n b: 3;\n}"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("doesn't import a package URL from a missing package", () async {
|
||||||
|
await d
|
||||||
|
.file("test.scss", '@import "package:fake_package/test_aux";')
|
||||||
|
.create();
|
||||||
|
var resolver = new SyncPackageResolver.config({});
|
||||||
|
|
||||||
|
expect(() => compile(d.sandbox + "/test.scss", packageResolver: resolver),
|
||||||
|
throwsA(new isInstanceOf<SassRuntimeException>()));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group("import precedence", () {
|
||||||
|
test("relative imports take precedence over importers", () async {
|
||||||
|
await d.dir(
|
||||||
|
"subdir", [d.file("other.scss", "a {b: from-load-path}")]).create();
|
||||||
|
await d.file("other.scss", "a {b: from-relative}").create();
|
||||||
|
await d.file("test.scss", '@import "other";').create();
|
||||||
|
|
||||||
|
var css = compile(p.join(d.sandbox, "test.scss"),
|
||||||
|
importers: [new FilesystemImporter(p.join(d.sandbox, 'subdir'))]);
|
||||||
|
expect(css, equals("a {\n b: from-relative;\n}"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("the original importer takes precedence over other importers",
|
||||||
|
() async {
|
||||||
|
await d.dir(
|
||||||
|
"original", [d.file("other.scss", "a {b: from-original}")]).create();
|
||||||
|
await d
|
||||||
|
.dir("other", [d.file("other.scss", "a {b: from-other}")]).create();
|
||||||
|
|
||||||
|
var css = compileString('@import "other";',
|
||||||
|
importer: new FilesystemImporter(p.join(d.sandbox, 'original')),
|
||||||
|
url: p.toUri(p.join(d.sandbox, 'original', 'test.scss')),
|
||||||
|
importers: [new FilesystemImporter(p.join(d.sandbox, 'other'))]);
|
||||||
|
expect(css, equals("a {\n b: from-original;\n}"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("importers take precedence over load paths", () async {
|
||||||
|
await d.dir("load-path",
|
||||||
|
[d.file("other.scss", "a {b: from-load-path}")]).create();
|
||||||
|
await d.dir(
|
||||||
|
"importer", [d.file("other.scss", "a {b: from-importer}")]).create();
|
||||||
|
await d.file("test.scss", '@import "other";').create();
|
||||||
|
|
||||||
|
var css = compile(p.join(d.sandbox, "test.scss"),
|
||||||
|
importers: [new FilesystemImporter(p.join(d.sandbox, 'importer'))],
|
||||||
|
loadPaths: [p.join(d.sandbox, 'load-path')]);
|
||||||
|
expect(css, equals("a {\n b: from-importer;\n}"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("importers take precedence over packageResolver", () async {
|
||||||
|
await d.dir("package",
|
||||||
|
[d.file("other.scss", "a {b: from-package-resolver}")]).create();
|
||||||
|
await d.dir(
|
||||||
|
"importer", [d.file("other.scss", "a {b: from-importer}")]).create();
|
||||||
|
await d
|
||||||
|
.file("test.scss", '@import "package:fake_package/other";')
|
||||||
|
.create();
|
||||||
|
|
||||||
|
var css = compile(p.join(d.sandbox, "test.scss"),
|
||||||
|
importers: [
|
||||||
|
new PackageImporter(new SyncPackageResolver.config(
|
||||||
|
{"fake_package": p.toUri(p.join(d.sandbox, 'importer'))}))
|
||||||
|
],
|
||||||
|
packageResolver: new SyncPackageResolver.config(
|
||||||
|
{"fake_package": p.toUri(p.join(d.sandbox, 'package'))}));
|
||||||
|
expect(css, equals("a {\n b: from-importer;\n}"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -1,37 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
@TestOn('vm')
|
|
||||||
|
|
||||||
import 'package:package_resolver/package_resolver.dart';
|
|
||||||
import 'package:test/test.dart';
|
|
||||||
import 'package:test_descriptor/test_descriptor.dart' as d;
|
|
||||||
|
|
||||||
import 'package:sass/sass.dart';
|
|
||||||
import 'package:sass/src/exception.dart';
|
|
||||||
import 'package:sass/src/util/path.dart';
|
|
||||||
|
|
||||||
main() {
|
|
||||||
test("successfully imports a package URL", () async {
|
|
||||||
await d.dir("subdir", [d.file("test.scss", "a {b: 1 + 2}")]).create();
|
|
||||||
|
|
||||||
await d.file("test.scss", '@import "package:fake_package/test";').create();
|
|
||||||
var resolver = new SyncPackageResolver.config(
|
|
||||||
{"fake_package": p.toUri(p.join(d.sandbox, 'subdir'))});
|
|
||||||
|
|
||||||
var css =
|
|
||||||
compile(p.join(d.sandbox, "test.scss"), packageResolver: resolver);
|
|
||||||
expect(css, equals("a {\n b: 3;\n}"));
|
|
||||||
});
|
|
||||||
|
|
||||||
test("imports a package URL from a missing package", () async {
|
|
||||||
await d
|
|
||||||
.file("test.scss", '@import "package:fake_package/test_aux";')
|
|
||||||
.create();
|
|
||||||
var resolver = new SyncPackageResolver.config({});
|
|
||||||
|
|
||||||
expect(() => compile(d.sandbox + "/test.scss", packageResolver: resolver),
|
|
||||||
throwsA(new isInstanceOf<SassRuntimeException>()));
|
|
||||||
});
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user