2018-03-12 04:38:29 +01:00
|
|
|
// Copyright 2018 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.
|
|
|
|
|
2023-05-19 22:22:44 +02:00
|
|
|
@TestOn('vm')
|
|
|
|
|
2018-03-12 04:38:29 +01:00
|
|
|
import 'package:test/test.dart';
|
|
|
|
import 'package:source_span/source_span.dart';
|
|
|
|
import 'package:stack_trace/stack_trace.dart';
|
|
|
|
|
|
|
|
import 'package:sass/sass.dart';
|
|
|
|
|
2019-06-06 20:42:44 +02:00
|
|
|
import 'test_importer.dart';
|
|
|
|
|
2019-11-06 01:28:26 +01:00
|
|
|
void main() {
|
2018-03-12 04:38:29 +01:00
|
|
|
group("with @warn", () {
|
|
|
|
test("passes the message and stack trace to the logger", () {
|
|
|
|
var mustBeCalled = expectAsync0(() {});
|
|
|
|
compileString('''
|
|
|
|
@mixin foo {@warn heck}
|
|
|
|
@include foo;
|
2021-03-17 03:25:39 +01:00
|
|
|
''', logger: _TestLogger.withWarn((message,
|
2021-03-17 04:51:32 +01:00
|
|
|
{span, trace, deprecation = false}) {
|
2018-03-12 04:38:29 +01:00
|
|
|
expect(message, equals("heck"));
|
|
|
|
expect(span, isNull);
|
2021-03-17 04:51:32 +01:00
|
|
|
expect(trace!.frames.first.member, equals('foo()'));
|
2018-03-12 04:38:29 +01:00
|
|
|
expect(deprecation, isFalse);
|
|
|
|
mustBeCalled();
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
|
|
|
|
test("stringifies the argument", () {
|
|
|
|
var mustBeCalled = expectAsync0(() {});
|
2021-03-17 04:51:32 +01:00
|
|
|
compileString('@warn #abc', logger:
|
|
|
|
_TestLogger.withWarn((message, {span, trace, deprecation = false}) {
|
2018-03-12 04:38:29 +01:00
|
|
|
expect(message, equals("#abc"));
|
|
|
|
mustBeCalled();
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
|
|
|
|
test("doesn't inspect the argument", () {
|
|
|
|
var mustBeCalled = expectAsync0(() {});
|
2021-03-17 04:51:32 +01:00
|
|
|
compileString('@warn null', logger:
|
|
|
|
_TestLogger.withWarn((message, {span, trace, deprecation = false}) {
|
2018-03-12 04:38:29 +01:00
|
|
|
expect(message, isEmpty);
|
|
|
|
mustBeCalled();
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
group("with @debug", () {
|
|
|
|
test("passes the message and span to the logger", () {
|
|
|
|
compileString('@debug heck',
|
2018-11-16 00:16:24 +01:00
|
|
|
logger: _TestLogger.withDebug(expectAsync2((message, span) {
|
2018-03-12 04:38:29 +01:00
|
|
|
expect(message, equals("heck"));
|
|
|
|
expect(span.start.line, equals(0));
|
|
|
|
expect(span.start.column, equals(0));
|
|
|
|
expect(span.end.line, equals(0));
|
|
|
|
expect(span.end.column, equals(11));
|
|
|
|
})));
|
|
|
|
});
|
|
|
|
|
|
|
|
test("stringifies the argument", () {
|
|
|
|
compileString('@debug #abc',
|
2018-11-16 00:16:24 +01:00
|
|
|
logger: _TestLogger.withDebug(expectAsync2((message, span) {
|
2018-03-12 04:38:29 +01:00
|
|
|
expect(message, equals("#abc"));
|
|
|
|
})));
|
|
|
|
});
|
|
|
|
|
|
|
|
test("inspects the argument", () {
|
|
|
|
compileString('@debug null',
|
2018-11-16 00:16:24 +01:00
|
|
|
logger: _TestLogger.withDebug(expectAsync2((message, span) {
|
2018-03-12 04:38:29 +01:00
|
|
|
expect(message, equals("null"));
|
|
|
|
})));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test("with a parser warning passes the message and span", () {
|
|
|
|
var mustBeCalled = expectAsync0(() {});
|
2021-03-17 03:25:39 +01:00
|
|
|
compileString('a {b: c && d}', logger:
|
2021-03-17 04:51:32 +01:00
|
|
|
_TestLogger.withWarn((message, {span, trace, deprecation = false}) {
|
2018-03-12 04:38:29 +01:00
|
|
|
expect(message, contains('"&&" means two copies'));
|
|
|
|
|
2021-03-17 04:51:32 +01:00
|
|
|
expect(span!.start.line, equals(0));
|
2018-03-12 04:38:29 +01:00
|
|
|
expect(span.start.column, equals(8));
|
|
|
|
expect(span.end.line, equals(0));
|
|
|
|
expect(span.end.column, equals(10));
|
|
|
|
|
|
|
|
expect(trace, isNull);
|
|
|
|
expect(deprecation, isFalse);
|
|
|
|
mustBeCalled();
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
|
|
|
|
test("with a runner warning passes the message, span, and trace", () {
|
|
|
|
var mustBeCalled = expectAsync0(() {});
|
|
|
|
compileString('''
|
|
|
|
@mixin foo {#{blue} {x: y}}
|
|
|
|
@include foo;
|
2021-03-17 04:51:32 +01:00
|
|
|
''', logger:
|
|
|
|
_TestLogger.withWarn((message, {span, trace, deprecation = false}) {
|
2018-03-12 04:38:29 +01:00
|
|
|
expect(message, contains("color value blue"));
|
|
|
|
|
2021-03-17 04:51:32 +01:00
|
|
|
expect(span!.start.line, equals(0));
|
2018-03-12 04:38:29 +01:00
|
|
|
expect(span.start.column, equals(22));
|
|
|
|
expect(span.end.line, equals(0));
|
|
|
|
expect(span.end.column, equals(26));
|
|
|
|
|
2021-03-17 04:51:32 +01:00
|
|
|
expect(trace!.frames.first.member, equals('foo()'));
|
2018-03-12 04:38:29 +01:00
|
|
|
expect(deprecation, isFalse);
|
|
|
|
mustBeCalled();
|
|
|
|
}));
|
|
|
|
});
|
2019-06-06 20:42:44 +02:00
|
|
|
|
|
|
|
group("with warn()", () {
|
|
|
|
group("from a function", () {
|
|
|
|
test("synchronously", () {
|
|
|
|
var mustBeCalled = expectAsync0(() {});
|
|
|
|
compileString("""
|
|
|
|
@function bar() {@return foo()}
|
|
|
|
a {b: bar()}
|
|
|
|
""", functions: [
|
|
|
|
Callable("foo", "", expectAsync1((_) {
|
|
|
|
warn("heck");
|
|
|
|
return sassNull;
|
|
|
|
}))
|
2021-03-17 03:25:39 +01:00
|
|
|
], logger: _TestLogger.withWarn((message,
|
2021-03-17 04:51:32 +01:00
|
|
|
{span, trace, deprecation = false}) {
|
2019-06-06 20:42:44 +02:00
|
|
|
expect(message, equals("heck"));
|
|
|
|
|
2021-03-17 04:51:32 +01:00
|
|
|
expect(span!.start.line, equals(0));
|
2019-06-06 20:42:44 +02:00
|
|
|
expect(span.start.column, equals(33));
|
|
|
|
expect(span.end.line, equals(0));
|
|
|
|
expect(span.end.column, equals(38));
|
|
|
|
|
2021-03-17 04:51:32 +01:00
|
|
|
expect(trace!.frames.first.member, equals('bar()'));
|
2019-06-06 20:42:44 +02:00
|
|
|
expect(deprecation, isFalse);
|
|
|
|
mustBeCalled();
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
|
|
|
|
test("asynchronously", () {
|
|
|
|
var mustBeCalled = expectAsync0(() {});
|
|
|
|
compileStringAsync("""
|
|
|
|
@function bar() {@return foo()}
|
|
|
|
a {b: bar()}
|
|
|
|
""", functions: [
|
|
|
|
AsyncCallable("foo", "", expectAsync1((_) async {
|
|
|
|
warn("heck");
|
|
|
|
return sassNull;
|
|
|
|
}))
|
2021-03-17 03:25:39 +01:00
|
|
|
], logger: _TestLogger.withWarn((message,
|
2021-03-17 04:51:32 +01:00
|
|
|
{span, trace, deprecation = false}) {
|
2019-06-06 20:42:44 +02:00
|
|
|
expect(message, equals("heck"));
|
|
|
|
|
2021-03-17 04:51:32 +01:00
|
|
|
expect(span!.start.line, equals(0));
|
2019-06-06 20:42:44 +02:00
|
|
|
expect(span.start.column, equals(33));
|
|
|
|
expect(span.end.line, equals(0));
|
|
|
|
expect(span.end.column, equals(38));
|
|
|
|
|
2021-03-17 04:51:32 +01:00
|
|
|
expect(trace!.frames.first.member, equals('bar()'));
|
2019-06-06 20:42:44 +02:00
|
|
|
expect(deprecation, isFalse);
|
|
|
|
mustBeCalled();
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
|
|
|
|
test("asynchronously after a gap", () {
|
|
|
|
var mustBeCalled = expectAsync0(() {});
|
|
|
|
compileStringAsync("""
|
|
|
|
@function bar() {@return foo()}
|
|
|
|
a {b: bar()}
|
|
|
|
""", functions: [
|
|
|
|
AsyncCallable("foo", "", expectAsync1((_) async {
|
|
|
|
await Future<void>.delayed(Duration.zero);
|
|
|
|
warn("heck");
|
|
|
|
return sassNull;
|
|
|
|
}))
|
2021-03-17 03:25:39 +01:00
|
|
|
], logger: _TestLogger.withWarn((message,
|
2021-03-17 04:51:32 +01:00
|
|
|
{span, trace, deprecation = false}) {
|
2019-06-06 20:42:44 +02:00
|
|
|
expect(message, equals("heck"));
|
|
|
|
|
2021-03-17 04:51:32 +01:00
|
|
|
expect(span!.start.line, equals(0));
|
2019-06-06 20:42:44 +02:00
|
|
|
expect(span.start.column, equals(33));
|
|
|
|
expect(span.end.line, equals(0));
|
|
|
|
expect(span.end.column, equals(38));
|
|
|
|
|
2021-03-17 04:51:32 +01:00
|
|
|
expect(trace!.frames.first.member, equals('bar()'));
|
2019-06-06 20:42:44 +02:00
|
|
|
expect(deprecation, isFalse);
|
|
|
|
mustBeCalled();
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test("from an importer", () {
|
|
|
|
var mustBeCalled = expectAsync0(() {});
|
|
|
|
compileString("@import 'foo';", importers: [
|
|
|
|
TestImporter((url) => Uri.parse("u:$url"), (url) {
|
|
|
|
warn("heck");
|
|
|
|
return ImporterResult("", indented: false);
|
|
|
|
})
|
2021-03-17 04:51:32 +01:00
|
|
|
], logger:
|
|
|
|
_TestLogger.withWarn((message, {span, trace, deprecation = false}) {
|
2019-06-06 20:42:44 +02:00
|
|
|
expect(message, equals("heck"));
|
|
|
|
|
2021-03-17 04:51:32 +01:00
|
|
|
expect(span!.start.line, equals(0));
|
2019-06-06 20:42:44 +02:00
|
|
|
expect(span.start.column, equals(8));
|
|
|
|
expect(span.end.line, equals(0));
|
|
|
|
expect(span.end.column, equals(13));
|
|
|
|
|
2021-03-17 04:51:32 +01:00
|
|
|
expect(trace!.frames.first.member, equals('@import'));
|
2019-06-06 20:42:44 +02:00
|
|
|
expect(deprecation, isFalse);
|
|
|
|
mustBeCalled();
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
|
|
|
|
test("with deprecation", () {
|
|
|
|
var mustBeCalled = expectAsync0(() {});
|
|
|
|
compileString("a {b: foo()}", functions: [
|
|
|
|
Callable("foo", "", expectAsync1((_) {
|
|
|
|
warn("heck", deprecation: true);
|
|
|
|
return sassNull;
|
|
|
|
}))
|
2021-03-17 04:51:32 +01:00
|
|
|
], logger:
|
|
|
|
_TestLogger.withWarn((message, {span, trace, deprecation = false}) {
|
2019-06-06 20:42:44 +02:00
|
|
|
expect(message, equals("heck"));
|
|
|
|
expect(deprecation, isTrue);
|
|
|
|
mustBeCalled();
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
|
|
|
|
test("throws an error outside a callback", () {
|
2021-10-16 02:21:24 +02:00
|
|
|
expect(() => warn("heck"), throwsStateError);
|
2019-06-06 20:42:44 +02:00
|
|
|
});
|
|
|
|
});
|
2018-03-12 04:38:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// A [Logger] whose [warn] and [debug] methods are provided by callbacks.
|
|
|
|
class _TestLogger implements Logger {
|
2021-03-17 04:51:32 +01:00
|
|
|
final void Function(String, {FileSpan? span, Trace? trace, bool deprecation})
|
|
|
|
_warn;
|
2018-03-12 04:38:29 +01:00
|
|
|
final void Function(String, SourceSpan) _debug;
|
|
|
|
|
|
|
|
_TestLogger.withWarn(this._warn) : _debug = const Logger.stderr().debug;
|
|
|
|
|
|
|
|
_TestLogger.withDebug(this._debug) : _warn = const Logger.stderr().warn;
|
|
|
|
|
|
|
|
void warn(String message,
|
2021-03-17 03:25:39 +01:00
|
|
|
{FileSpan? span, Trace? trace, bool deprecation = false}) =>
|
2018-03-12 04:38:29 +01:00
|
|
|
_warn(message, span: span, trace: trace, deprecation: deprecation);
|
|
|
|
void debug(String message, SourceSpan span) => _debug(message, span);
|
|
|
|
}
|