mirror of
https://github.com/danog/dart-sass.git
synced 2024-12-03 10:08:01 +01:00
Merge branch 'master' into feature.use
This commit is contained in:
commit
93a3a6f9f3
39
.travis.yml
39
.travis.yml
@ -64,6 +64,9 @@ jobs:
|
|||||||
env: DART_CHANNEL=dev
|
env: DART_CHANNEL=dev
|
||||||
- <<: *dart-tests
|
- <<: *dart-tests
|
||||||
os: windows
|
os: windows
|
||||||
|
# File system watching is extra flaky on Dart 2.5.0 on Windows (see
|
||||||
|
# dart-lang/sdk#38334).
|
||||||
|
env: DART_VERSION=2.4.1
|
||||||
- <<: *dart-tests
|
- <<: *dart-tests
|
||||||
os: osx
|
os: osx
|
||||||
|
|
||||||
@ -110,10 +113,12 @@ jobs:
|
|||||||
(type IN (push, api)) AND (repo = sass/dart-sass) AND tag =~ ^\d+\.\d+\.\d+([+-].*)?$
|
(type IN (push, api)) AND (repo = sass/dart-sass) AND tag =~ ^\d+\.\d+\.\d+([+-].*)?$
|
||||||
script: pub run grinder sanity-check-before-release
|
script: pub run grinder sanity-check-before-release
|
||||||
|
|
||||||
# Deploy Linux and Windows releases to GitHub. Mac OS releases are deployed in
|
# Deploy Linux releases to GitHub. Mac OS releases are deployed in a later
|
||||||
# a later stage so that we can build application snapshots on Mac OS bots.
|
# stage so that we can build application snapshots on Mac OS bots, and Windows
|
||||||
|
# releases are deployed later so they can use Dart 2.4.1 to work around
|
||||||
|
# dart-lang/sdk#38334.
|
||||||
- stage: deploy 1
|
- stage: deploy 1
|
||||||
name: "GitHub: Windows and Linux"
|
name: "GitHub: Linux"
|
||||||
if: *deploy-if
|
if: *deploy-if
|
||||||
env: &github-env
|
env: &github-env
|
||||||
- GITHUB_USER=sassbot
|
- GITHUB_USER=sassbot
|
||||||
@ -125,7 +130,7 @@ jobs:
|
|||||||
script: skip # Don't run tests
|
script: skip # Don't run tests
|
||||||
deploy:
|
deploy:
|
||||||
provider: script
|
provider: script
|
||||||
script: pub run grinder github-release github-linux github-windows
|
script: pub run grinder github-release github-linux
|
||||||
skip_cleanup: true # Don't clean up the Dart SDK.
|
skip_cleanup: true # Don't clean up the Dart SDK.
|
||||||
|
|
||||||
# This causes the deploy to only be build when a tag is pushed. This
|
# This causes the deploy to only be build when a tag is pushed. This
|
||||||
@ -183,6 +188,9 @@ jobs:
|
|||||||
- name: Chocolatey
|
- name: Chocolatey
|
||||||
if: *deploy-if
|
if: *deploy-if
|
||||||
env:
|
env:
|
||||||
|
# File system watching is extra flaky on Dart 2.5.0 on Windows (see
|
||||||
|
# dart-lang/sdk#38334).
|
||||||
|
- DART_VERSION=2.4.1
|
||||||
# CHOCO_TOKEN="..."
|
# CHOCO_TOKEN="..."
|
||||||
- secure: "cW11kQYBBEElfVsc1pJfVEHOMYwt0ZK+9STZHwSPbAISlplIRnsimMN7TqCY2aLnkWXyUMU7DphIl9uQ86M4BT1bJopsHbapj27bFSlKWHlBSDB/xylFHywV41Yk5lMlr8DLMbsSzVahasyR34xS6HYIRlDpZ9TFiQuDQNJxQmqTZJg/FC+3nqCI7tyMKGkWc48ikTcmqDMHsG9CudG2u+Q3S9sLNXArh9T4tSnAyWkTvSrS05mvFx5tC83PcG9/VkioTId+VRSJchwTmCxDFDROrTikTXZMtYn8wMAQ2wQ34TQXNZMZ9uiHA6W0IuJV2EnYerJbqV2lrJq9xqZywKu6HW6i4GhrCvizALNFZx/N7s/10xuf3UcuWizYml/e0MYT+6t4ojTYBMKv+Cx+H2Y2Jdpvdn2ZAIl6LaU3pLw4OIPJ7aXjDwZd63MPxtwGwVLHbH7Zu+oUv1erIq5LtatuocGWipD8WdiMBQvyCuDRMowpLPoAbj+mevOf+xlY2Eym4tOXpxM7iY3lXFHROo5dQbhsARfVF9J1gl5PuYXvCjxqTfK/ef9t3ZoDbi57+yAJUWlZfWa5r1zKE8OS0pA8GfQRLom/Lt0wKVw4Xiofgolzd9pEHi4JpsYIQb8O+u1ACQU6nBCS87CGrQ+ylnzKfGUs0aW2K3gvbkg0LUg="
|
- secure: "cW11kQYBBEElfVsc1pJfVEHOMYwt0ZK+9STZHwSPbAISlplIRnsimMN7TqCY2aLnkWXyUMU7DphIl9uQ86M4BT1bJopsHbapj27bFSlKWHlBSDB/xylFHywV41Yk5lMlr8DLMbsSzVahasyR34xS6HYIRlDpZ9TFiQuDQNJxQmqTZJg/FC+3nqCI7tyMKGkWc48ikTcmqDMHsG9CudG2u+Q3S9sLNXArh9T4tSnAyWkTvSrS05mvFx5tC83PcG9/VkioTId+VRSJchwTmCxDFDROrTikTXZMtYn8wMAQ2wQ34TQXNZMZ9uiHA6W0IuJV2EnYerJbqV2lrJq9xqZywKu6HW6i4GhrCvizALNFZx/N7s/10xuf3UcuWizYml/e0MYT+6t4ojTYBMKv+Cx+H2Y2Jdpvdn2ZAIl6LaU3pLw4OIPJ7aXjDwZd63MPxtwGwVLHbH7Zu+oUv1erIq5LtatuocGWipD8WdiMBQvyCuDRMowpLPoAbj+mevOf+xlY2Eym4tOXpxM7iY3lXFHROo5dQbhsARfVF9J1gl5PuYXvCjxqTfK/ef9t3ZoDbi57+yAJUWlZfWa5r1zKE8OS0pA8GfQRLom/Lt0wKVw4Xiofgolzd9pEHi4JpsYIQb8O+u1ACQU6nBCS87CGrQ+ylnzKfGUs0aW2K3gvbkg0LUg="
|
||||||
script: skip
|
script: skip
|
||||||
@ -232,3 +240,26 @@ jobs:
|
|||||||
script: pub run grinder github-mac-os
|
script: pub run grinder github-mac-os
|
||||||
skip_cleanup: true
|
skip_cleanup: true
|
||||||
on: {tags: true}
|
on: {tags: true}
|
||||||
|
|
||||||
|
- name: "GitHub: Windows"
|
||||||
|
if: *deploy-if
|
||||||
|
env:
|
||||||
|
# We can't re-use the github-env alias here because we also need to
|
||||||
|
# override DART_VERSION.
|
||||||
|
#
|
||||||
|
# File system watching is extra flaky on Dart 2.5.0 on Windows (see
|
||||||
|
# dart-lang/sdk#38334).
|
||||||
|
- DART_VERSION=2.4.1
|
||||||
|
- GITHUB_USER=sassbot
|
||||||
|
# GITHUB_AUTH="..."
|
||||||
|
#
|
||||||
|
# Note that this overrides the read-only auth token that's set for all
|
||||||
|
# builds.
|
||||||
|
- secure: "AAP74aT+8SQmwGeHrCsZ7GgppvCCkDAZXszivocMy3Fi9gfMCLABBCh67pGINJX4VlLW7ftPF3xivlvgGu+e4ncXz9m9jIPZ9Iza3cW5jCnCgyRGZD98gwabIDFWiv4X9V2xnJA2p1ZuYBf8Sh3TTipUFBKMjlnxVxYkIOTud4rUss/htFhxVA/oFTo0ThTZwXuxJ+GRGTM4PcuHPJvPf18iRPs2AHFV6ZP51xgc3AsXC6Zyom5EJeX0yGj9zWQ0XCjnuFdGsI6G9jmkrmqgAXuUipgqAn0tjxPYp9R/1HqnBLD3Zbrvyi5pCiSFclU6CS6kTDbefzPOc5+zrnlkaolVeF8tQ+EhZiZqtLnpLYUz9bgknoFUapUN4N0R36sKBStdRv54+sMeoOzpQ8ep3PeZW5nWbak12wcrDx38ToWs6hQ4ycb0SQDZZatHsASpSu2nX8HwzZSDAZmsAdB+epPmgA0CBjWVG1ycmVnT6l3OopUmbaY3pXBNzFUXq5Fcd7Q39/MfrmHpyxSc3QVf8xNtUx9ggYtK0Kwx6dgykhNMVzFGZRVyQgwpaiyDqgMGEU2GQzzcJhgKo9+y1fDtdfj/cctmvJ2Fo1fkk+DMkEPUHGOVo6uKFnartky9iLm1WiHDMruJ6SIOJzAnb+TMBWQTSwI+F4wyEiRVR8Zv4uA="
|
||||||
|
|
||||||
|
script: skip
|
||||||
|
deploy:
|
||||||
|
provider: script
|
||||||
|
script: pub run grinder github-windows
|
||||||
|
skip_cleanup: true
|
||||||
|
on: {tags: true}
|
||||||
|
23
CHANGELOG.md
23
CHANGELOG.md
@ -1,3 +1,26 @@
|
|||||||
|
## 1.22.12
|
||||||
|
|
||||||
|
* **Potentially breaking bug fix:** character sequences consisting of two or
|
||||||
|
more hyphens followed by a number (such as `--123`), or two or more hyphens on
|
||||||
|
their own (such as `--`), are now parsed as identifiers [in accordance with
|
||||||
|
the CSS spec][ident-token-diagram].
|
||||||
|
|
||||||
|
[ident-token-diagram]: https://drafts.csswg.org/css-syntax-3/#ident-token-diagram
|
||||||
|
|
||||||
|
The sequence `--` was previously parsed as multiple applications of the `-`
|
||||||
|
operator. Since this is unlikely to be used intentionally in practice, we
|
||||||
|
consider this bug fix safe.
|
||||||
|
|
||||||
|
### Command-Line Interface
|
||||||
|
|
||||||
|
* Fix a bug where changes in `.css` files would be ignored in `--watch` mode.
|
||||||
|
|
||||||
|
### JavaScript API
|
||||||
|
|
||||||
|
* Allow underscore-separated custom functions to be defined.
|
||||||
|
|
||||||
|
* Improve the performance of Node.js compilation involving many `@import`s.
|
||||||
|
|
||||||
## 1.22.11
|
## 1.22.11
|
||||||
|
|
||||||
* Don't try to load unquoted plain-CSS indented-syntax imports.
|
* Don't try to load unquoted plain-CSS indented-syntax imports.
|
||||||
|
@ -122,7 +122,9 @@ class _Watcher {
|
|||||||
Future<void> watch(MultiDirWatcher watcher) async {
|
Future<void> watch(MultiDirWatcher watcher) async {
|
||||||
await for (var event in _debounceEvents(watcher.events)) {
|
await for (var event in _debounceEvents(watcher.events)) {
|
||||||
var extension = p.extension(event.path);
|
var extension = p.extension(event.path);
|
||||||
if (extension != '.sass' && extension != '.scss') continue;
|
if (extension != '.sass' && extension != '.scss' && extension != '.css') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case ChangeType.MODIFY:
|
case ChangeType.MODIFY:
|
||||||
|
@ -156,6 +156,13 @@ String _cleanErrorMessage(_SystemError error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool fileExists(String path) {
|
bool fileExists(String path) {
|
||||||
|
return _systemErrorToFileSystemException(() {
|
||||||
|
// `existsSync()` is faster than `statSync()`, but it doesn't clarify
|
||||||
|
// whether the entity in question is a file or a directory. Since false
|
||||||
|
// negatives are much more common than false positives, it works out in our
|
||||||
|
// favor to check this first.
|
||||||
|
if (!_fs.existsSync(path)) return false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return _fs.statSync(path).isFile();
|
return _fs.statSync(path).isFile();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -163,9 +170,17 @@ bool fileExists(String path) {
|
|||||||
if (systemError.code == 'ENOENT') return false;
|
if (systemError.code == 'ENOENT') return false;
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dirExists(String path) {
|
bool dirExists(String path) {
|
||||||
|
return _systemErrorToFileSystemException(() {
|
||||||
|
// `existsSync()` is faster than `statSync()`, but it doesn't clarify
|
||||||
|
// whether the entity in question is a file or a directory. Since false
|
||||||
|
// negatives are much more common than false positives, it works out in our
|
||||||
|
// favor to check this first.
|
||||||
|
if (!_fs.existsSync(path)) return false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return _fs.statSync(path).isDirectory();
|
return _fs.statSync(path).isDirectory();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -173,6 +188,7 @@ bool dirExists(String path) {
|
|||||||
if (systemError.code == 'ENOENT') return false;
|
if (systemError.code == 'ENOENT') return false;
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ensureDir(String path) {
|
void ensureDir(String path) {
|
||||||
|
@ -147,12 +147,18 @@ class Parser {
|
|||||||
@protected
|
@protected
|
||||||
String identifier({bool normalize = false, bool unit = false}) {
|
String identifier({bool normalize = false, bool unit = false}) {
|
||||||
// NOTE: this logic is largely duplicated in
|
// NOTE: this logic is largely duplicated in
|
||||||
// StylesheetParser._interpolatedIdentifier and isIdentifier in utils.dart.
|
// StylesheetParser.interpolatedIdentifier. Most changes here should be
|
||||||
// Most changes here should be mirrored there.
|
// mirrored there.
|
||||||
|
|
||||||
var text = StringBuffer();
|
var text = StringBuffer();
|
||||||
while (scanner.scanChar($dash)) {
|
if (scanner.scanChar($dash)) {
|
||||||
text.writeCharCode($dash);
|
text.writeCharCode($dash);
|
||||||
|
|
||||||
|
if (scanner.scanChar($dash)) {
|
||||||
|
text.writeCharCode($dash);
|
||||||
|
_identifierBody(text, normalize: normalize, unit: unit);
|
||||||
|
return text.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var first = scanner.peekChar();
|
var first = scanner.peekChar();
|
||||||
@ -580,11 +586,7 @@ class Parser {
|
|||||||
|
|
||||||
var second = scanner.peekChar(forward + 1);
|
var second = scanner.peekChar(forward + 1);
|
||||||
if (second == null) return false;
|
if (second == null) return false;
|
||||||
if (isNameStart(second) || second == $backslash) return true;
|
return isNameStart(second) || second == $backslash || second == $dash;
|
||||||
if (second != $dash) return false;
|
|
||||||
|
|
||||||
var third = scanner.peekChar(forward + 2);
|
|
||||||
return third != null && isNameStart(third);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether the scanner is immediately before a sequence of characters
|
/// Returns whether the scanner is immediately before a sequence of characters
|
||||||
|
@ -3102,8 +3102,14 @@ relase. For details, see http://bit.ly/moz-document.
|
|||||||
var start = scanner.state;
|
var start = scanner.state;
|
||||||
var buffer = InterpolationBuffer();
|
var buffer = InterpolationBuffer();
|
||||||
|
|
||||||
while (scanner.scanChar($dash)) {
|
if (scanner.scanChar($dash)) {
|
||||||
buffer.writeCharCode($dash);
|
buffer.writeCharCode($dash);
|
||||||
|
|
||||||
|
if (scanner.scanChar($dash)) {
|
||||||
|
buffer.writeCharCode($dash);
|
||||||
|
_interpolatedIdentifierBody(buffer);
|
||||||
|
return buffer.interpolation(scanner.spanFrom(start));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var first = scanner.peekChar();
|
var first = scanner.peekChar();
|
||||||
@ -3119,6 +3125,13 @@ relase. For details, see http://bit.ly/moz-document.
|
|||||||
scanner.error("Expected identifier.");
|
scanner.error("Expected identifier.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_interpolatedIdentifierBody(buffer);
|
||||||
|
return buffer.interpolation(scanner.spanFrom(start));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Consumes a chunk of a possibly-interpolated CSS identifier after the name
|
||||||
|
/// start, and adds the contents to the [buffer] buffer.
|
||||||
|
void _interpolatedIdentifierBody(InterpolationBuffer buffer) {
|
||||||
while (true) {
|
while (true) {
|
||||||
var next = scanner.peekChar();
|
var next = scanner.peekChar();
|
||||||
if (next == null) {
|
if (next == null) {
|
||||||
@ -3136,8 +3149,6 @@ relase. For details, see http://bit.ly/moz-document.
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer.interpolation(scanner.spanFrom(start));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Consumes interpolation.
|
/// Consumes interpolation.
|
||||||
@ -3384,15 +3395,8 @@ relase. For details, see http://bit.ly/moz-document.
|
|||||||
if (first != $dash) return false;
|
if (first != $dash) return false;
|
||||||
var second = scanner.peekChar(1);
|
var second = scanner.peekChar(1);
|
||||||
if (second == null) return false;
|
if (second == null) return false;
|
||||||
if (isNameStart(second) || second == $backslash) return true;
|
|
||||||
|
|
||||||
if (second == $hash) return scanner.peekChar(2) == $lbrace;
|
if (second == $hash) return scanner.peekChar(2) == $lbrace;
|
||||||
if (second != $dash) return false;
|
return isNameStart(second) || second == $backslash || second == $dash;
|
||||||
|
|
||||||
var third = scanner.peekChar(2);
|
|
||||||
if (third == null) return false;
|
|
||||||
if (third == $hash) return scanner.peekChar(3) == $lbrace;
|
|
||||||
return isNameStart(third);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether the scanner is immediately before a sequence of characters
|
/// Returns whether the scanner is immediately before a sequence of characters
|
||||||
|
@ -442,7 +442,7 @@ class _EvaluateVisitor
|
|||||||
|
|
||||||
functions = [...?functions, ...globalFunctions, ...metaFunctions];
|
functions = [...?functions, ...globalFunctions, ...metaFunctions];
|
||||||
for (var function in functions) {
|
for (var function in functions) {
|
||||||
_builtInFunctions[function.name] = function;
|
_builtInFunctions[function.name.replaceAll("_", "-")] = function;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
// DO NOT EDIT. This file was generated from async_evaluate.dart.
|
// DO NOT EDIT. This file was generated from async_evaluate.dart.
|
||||||
// See tool/grind/synchronize.dart for details.
|
// See tool/grind/synchronize.dart for details.
|
||||||
//
|
//
|
||||||
// Checksum: 5c9f270ef574f9c6062421ed1866af3d07672b46
|
// Checksum: 3fc19891432af3cebdc0f36730e57cbbf672d959
|
||||||
//
|
//
|
||||||
// ignore_for_file: unused_import
|
// ignore_for_file: unused_import
|
||||||
|
|
||||||
@ -448,7 +448,7 @@ class _EvaluateVisitor
|
|||||||
|
|
||||||
functions = [...?functions, ...globalFunctions, ...metaFunctions];
|
functions = [...?functions, ...globalFunctions, ...metaFunctions];
|
||||||
for (var function in functions) {
|
for (var function in functions) {
|
||||||
_builtInFunctions[function.name] = function;
|
_builtInFunctions[function.name.replaceAll("_", "-")] = function;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ import 'interface/statement.dart';
|
|||||||
/// The default implementation of the visit methods all return `null`.
|
/// The default implementation of the visit methods all return `null`.
|
||||||
abstract class RecursiveStatementVisitor<T> implements StatementVisitor<T> {
|
abstract class RecursiveStatementVisitor<T> implements StatementVisitor<T> {
|
||||||
T visitAtRootRule(AtRootRule node) {
|
T visitAtRootRule(AtRootRule node) {
|
||||||
visitInterpolation(node.query);
|
if (node.query != null) visitInterpolation(node.query);
|
||||||
return visitChildren(node);
|
return visitChildren(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ abstract class RecursiveStatementVisitor<T> implements StatementVisitor<T> {
|
|||||||
|
|
||||||
T visitDeclaration(Declaration node) {
|
T visitDeclaration(Declaration node) {
|
||||||
visitInterpolation(node.name);
|
visitInterpolation(node.name);
|
||||||
visitExpression(node.value);
|
if (node.value != null) visitExpression(node.value);
|
||||||
return node.children == null ? null : visitChildren(node);
|
return node.children == null ? null : visitChildren(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
name: sass
|
name: sass
|
||||||
version: 1.22.11
|
version: 1.22.12
|
||||||
description: A Sass implementation in Dart.
|
description: A Sass implementation in Dart.
|
||||||
author: Sass Team
|
author: Sass Team
|
||||||
homepage: https://github.com/sass/dart-sass
|
homepage: https://github.com/sass/dart-sass
|
||||||
|
@ -5,6 +5,10 @@
|
|||||||
// OS X's modification time reporting is flaky, so we skip these tests on it.
|
// OS X's modification time reporting is flaky, so we skip these tests on it.
|
||||||
@TestOn('vm && !mac-os')
|
@TestOn('vm && !mac-os')
|
||||||
|
|
||||||
|
// File watching is inherently flaky at the OS level. To mitigate this, we do a
|
||||||
|
// few retries when the tests fail.
|
||||||
|
@Retry(3)
|
||||||
|
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
import '../dart_test.dart';
|
import '../dart_test.dart';
|
||||||
|
@ -6,6 +6,10 @@
|
|||||||
@TestOn('vm && !mac-os')
|
@TestOn('vm && !mac-os')
|
||||||
@Tags(['node'])
|
@Tags(['node'])
|
||||||
|
|
||||||
|
// File watching is inherently flaky at the OS level. To mitigate this, we do a
|
||||||
|
// few retries when the tests fail.
|
||||||
|
@Retry(3)
|
||||||
|
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
import '../../ensure_npm_package.dart';
|
import '../../ensure_npm_package.dart';
|
||||||
|
@ -499,6 +499,26 @@ void sharedTests(Future<TestProcess> runSass(Iterable<String> arguments)) {
|
|||||||
]).validate();
|
]).validate();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Regression test for #806
|
||||||
|
test("with a .css extension", () async {
|
||||||
|
await d.file("test.css", "a {b: c}").create();
|
||||||
|
|
||||||
|
var sass = await watch(["test.css:out.css"]);
|
||||||
|
await expectLater(
|
||||||
|
sass.stdout, emits('Compiled test.css to out.css.'));
|
||||||
|
await expectLater(sass.stdout, _watchingForChanges);
|
||||||
|
await tickIfPoll();
|
||||||
|
|
||||||
|
await d.file("test.css", "x {y: z}").create();
|
||||||
|
await expectLater(
|
||||||
|
sass.stdout, emits('Compiled test.css to out.css.'));
|
||||||
|
await sass.kill();
|
||||||
|
|
||||||
|
await d
|
||||||
|
.file("out.css", equalsIgnoringWhitespace("x { y: z; }"))
|
||||||
|
.validate();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group("doesn't recompile the watched file", () {
|
group("doesn't recompile the watched file", () {
|
||||||
|
@ -130,4 +130,28 @@ main() {
|
|||||||
|
|
||||||
expect(css, equalsIgnoringWhitespace("a { b: 1; }"));
|
expect(css, equalsIgnoringWhitespace("a { b: 1; }"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
group("are dash-normalized", () {
|
||||||
|
test("when defined with dashes", () {
|
||||||
|
expect(
|
||||||
|
compileString('a {b: foo_bar()}', functions: [
|
||||||
|
Callable("foo-bar", "", expectAsync1((arguments) {
|
||||||
|
expect(arguments, isEmpty);
|
||||||
|
return sassNull;
|
||||||
|
}))
|
||||||
|
]),
|
||||||
|
isEmpty);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("when defined with underscores", () {
|
||||||
|
expect(
|
||||||
|
compileString('a {b: foo-bar()}', functions: [
|
||||||
|
Callable("foo_bar", "", expectAsync1((arguments) {
|
||||||
|
expect(arguments, isEmpty);
|
||||||
|
return sassNull;
|
||||||
|
}))
|
||||||
|
]),
|
||||||
|
isEmpty);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,30 @@ void main() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
group("are dash-normalized", () {
|
||||||
|
test("when defined with dashes", () {
|
||||||
|
expect(
|
||||||
|
renderSync(RenderOptions(
|
||||||
|
data: "a {b: foo_bar()}",
|
||||||
|
functions: jsify({
|
||||||
|
"foo-bar": allowInterop(expectAsync0(
|
||||||
|
() => callConstructor(sass.types.Number, [12])))
|
||||||
|
}))),
|
||||||
|
equalsIgnoringWhitespace("a { b: 12; }"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("when defined with underscores", () {
|
||||||
|
expect(
|
||||||
|
renderSync(RenderOptions(
|
||||||
|
data: "a {b: foo-bar()}",
|
||||||
|
functions: jsify({
|
||||||
|
"foo_bar": allowInterop(expectAsync0(
|
||||||
|
() => callConstructor(sass.types.Number, [12])))
|
||||||
|
}))),
|
||||||
|
equalsIgnoringWhitespace("a { b: 12; }"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
group("rejects function calls that", () {
|
group("rejects function calls that", () {
|
||||||
test("have too few arguments", () {
|
test("have too few arguments", () {
|
||||||
var error = renderSyncError(RenderOptions(
|
var error = renderSyncError(RenderOptions(
|
||||||
|
Loading…
Reference in New Issue
Block a user