Skip to content

Commit

Permalink
Fix bugs with imports, test matchers style
Browse files Browse the repository at this point in the history
  • Loading branch information
wkillerud committed Nov 4, 2024
1 parent 2299a6f commit 1492d1c
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 36 deletions.
4 changes: 2 additions & 2 deletions pkgs/sass_language_server/test/utils/uri_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ void main() {
expect(
filePathToUri(
"c:\\workspace\\dart-sass-language-server\\extension\\test\\electron\\document-links\\fixtures"),
Uri.parse(
"file:///c:/workspace/dart-sass-language-server/extension/test/electron/document-links/fixtures"));
equals(Uri.parse(
"file:///c:/workspace/dart-sass-language-server/extension/test/electron/document-links/fixtures")));
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import 'stylesheet_document_link.dart';

typedef UnresolvedLinkData = (StylesheetDocumentLink, bool);

final quotes = RegExp('["\']');

class DocumentLinkVisitor with sass.RecursiveStatementVisitor {
List<UnresolvedLinkData> unresolvedLinks = [];

Expand Down Expand Up @@ -56,12 +58,13 @@ class DocumentLinkVisitor with sass.RecursiveStatementVisitor {
@override
void visitImportRule(sass.ImportRule node) {
super.visitImportRule(node);
const isSassLink = true;
for (var import in node.imports) {
if (import is sass.DynamicImport) {
const isSassLink = true;
unresolvedLinks.add((
StylesheetDocumentLink(
type: LinkType.import,
target: import.url,
range: lsp.Range(
end: lsp.Position(
line: import.urlSpan.end.line,
Expand All @@ -75,9 +78,29 @@ class DocumentLinkVisitor with sass.RecursiveStatementVisitor {
));
} else {
var staticImport = import as sass.StaticImport;

Uri? target;
if (import.url.isPlain) {
// This text includes quotes (if they are present, optional in Indented)
target = Uri.tryParse(import.span.text.replaceAll(quotes, ''));
} else if (import.url.contents.isNotEmpty) {
// drill down to the link target from f. ex. `@import url("foo.css");`
var maybeUrlFunction = import.url.contents.first;
if (maybeUrlFunction is sass.InterpolatedFunctionExpression) {
if (maybeUrlFunction.arguments.positional.isNotEmpty) {
var arg = maybeUrlFunction.arguments.positional.first;
if (arg is sass.StringExpression && arg.text.isPlain) {
target = Uri.tryParse(arg.text.asPlain!);
}
}
}
}

const isSassLink = false;
unresolvedLinks.add((
StylesheetDocumentLink(
type: LinkType.import,
target: target,
range: lsp.Range(
end: lsp.Position(
line: staticImport.url.span.end.line,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,8 @@ class LanguageServicesCache {
void remove(Uri uri) {
_cache.remove(uri.toString());
}

void clear() {
_cache.clear();
}
}
18 changes: 9 additions & 9 deletions pkgs/sass_language_services/test/configuration_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@ void main() {
test('default configuration is as expected', () {
var result = LanguageServerConfiguration.create(null);

expect(result.editor.colorDecoratorsLimit, 500);
expect(result.editor.indentSize, 2);
expect(result.editor.insertSpaces, false);
expect(result.editor.colorDecoratorsLimit, equals(500));
expect(result.editor.indentSize, equals(2));
expect(result.editor.insertSpaces, isFalse);
});

test('can override default settings with user settings', () {
var result = LanguageServerConfiguration.create({
"editor": {"insertSpaces": true}
});

expect(result.editor.insertSpaces, true);
expect(result.editor.insertSpaces, isTrue);

// else defaults
expect(result.editor.colorDecoratorsLimit, 500);
expect(result.editor.indentSize, 2);
expect(result.editor.colorDecoratorsLimit, equals(500));
expect(result.editor.indentSize, equals(2));
});
});

Expand All @@ -32,8 +32,8 @@ void main() {
expect(result.workspace.exclude,
equals(["**/.git/**", "**/node_modules/**"]));

expect(result.workspace.loadPaths.isEmpty, true);
expect(result.workspace.importAliases.isEmpty, true);
expect(result.workspace.loadPaths, isEmpty);
expect(result.workspace.importAliases, isEmpty);
});

test('can override default settings with user settings', () {
Expand All @@ -51,7 +51,7 @@ void main() {

expect(result.workspace.exclude,
equals(["**/.git/**", "**/node_modules/**"]));
expect(result.workspace.importAliases.isEmpty, true);
expect(result.workspace.importAliases, isEmpty);
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ final ls = LanguageServices(fs: fs, clientCapabilities: getCapabilities());

void main() {
group('Document links', () {
setUp(() {
ls.cache.clear();
});

test('should resolve valid links', () async {
fs.createDocument('\$var: 1px;', uri: 'variables.scss');
fs.createDocument('\$tr: 2px;', uri: 'corners.scss');
Expand All @@ -22,29 +26,29 @@ void main() {
''');

var links = await ls.findDocumentLinks(document);
expect(links.length, 4);
expect(links.length, equals(4));

var use = links.where((link) => link.type == LinkType.use);
var forward = links.where((link) => link.type == LinkType.forward);

expect(use.length, 2);
expect(forward.length, 2);
expect(use.length, equals(2));
expect(forward.length, equals(2));

expect(use.last.namespace, 'vars');
expect(use.first.namespace, null,
expect(use.last.namespace, equals('vars'));
expect(use.first.namespace, isNull,
reason: 'Expected wildcard @use not to have a namespace');

expect(forward.last.shownVariables, {'public'});
expect(forward.first.hiddenVariables, {'foo'});
expect(forward.first.hiddenMixinsAndFunctions, {'barfunc'});
expect(forward.first.prefix, 'color-');
expect(forward.last.prefix, 'foo-');
expect(forward.last.shownVariables, equals({'public'}));
expect(forward.first.hiddenVariables, equals({'foo'}));
expect(forward.first.hiddenMixinsAndFunctions, equals({'barfunc'}));
expect(forward.first.prefix, equals('color-'));
expect(forward.last.prefix, equals('foo-'));

expect(use.first.target != null, true);
expect(use.last.target != null, true);
expect(forward.first.target != null, true);
expect(use.first.target!.path, endsWith('corners.scss'));
expect(use.last.target!.path, endsWith('variables.scss'));
expect(forward.first.target!.path, endsWith('colors.scss'));

expect(forward.last.target != null, true,
expect(forward.last.target!.path, endsWith('does-not-exist'),
reason:
'Expected to have a target even though the file does not exist in our file system.');
});
Expand All @@ -62,7 +66,7 @@ void main() {

var links = await ls.findDocumentLinks(document);

equals(links.length, 3);
expect(links.length, equals(3));
});

test('should not break on circular references', () async {
Expand All @@ -78,11 +82,62 @@ void main() {

var links = await ls.findDocumentLinks(document);

expect(links.length, 1);
expect(links.length, equals(1));
});

test('handles various forms of partials', () async {
fs.createDocument('''
\$foo: blue;
''', uri: '_foo.scss');

fs.createDocument('''
\$bar: red
''', uri: 'bar/_index.sass');

var document = fs.createDocument('''
@use "foo";
@use "bar";
''');

var links = await ls.findDocumentLinks(document);

expect(links.length, equals(2));

expect(links.first.target!.path, endsWith('_foo.scss'));
expect(links.last.target!.path, endsWith('bar/_index.sass'));
});

test('handles CSS imports', () async {
var links = await ls.findDocumentLinks(fs.createDocument('''
@import "string.css";
'''));
expect(links.first.target!.path, endsWith('string.css'));
});

test('handles remote CSS imports', () async {
var links = await ls.findDocumentLinks(fs.createDocument('''
@import 'http://foo.com/foo.css';
'''));
expect(links.first.target!.toString(), equals('http://foo.com/foo.css'));
});

// TODO: tests for partials
// TODO: test for CSS imports (@import 'foo.css')
// TODO: test for Sass imports (with and without string quotes)
test('handles CSS url function imports', () async {
var links = await ls.findDocumentLinks(fs.createDocument('''
@import url("func.css") print;
'''));
expect(links.first.target!.path, endsWith('func.css'));
});

test('handles Sass imports without string quotes', () async {
fs.createDocument('''
\$foo: blue;
''', uri: '_foo.scss');

var links = await ls.findDocumentLinks(fs.createDocument('''
@import foo
''', uri: 'index.sass'));

expect(links.first.target!.path, endsWith('_foo.scss'));
});
});
}
10 changes: 5 additions & 5 deletions pkgs/sass_language_services/test/node_utils_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,29 @@ void main() {
group('getModuleNameFromPath', () {
test('returns the input if there is no slash', () {
var result = getModuleNameFromPath('path');
expect(result, 'path');
expect(result, equals('path'));
});

test('returns the input up to the first slash', () {
var result = getModuleNameFromPath('path/to/foo');
expect(result, 'path');
expect(result, equals('path'));
});

test('returns an empty string if the input is an absolute path', () {
var result = getModuleNameFromPath('/path/to/foo');
expect(result, '');
expect(result, isEmpty);
});

test('handles scoped npm modules (ex. @foo/bar)', () {
var result = getModuleNameFromPath('@foo/bar');
expect(result, '@foo/bar');
expect(result, equals('@foo/bar'));
});

test(
'returns only the scoped module name in case of subpaths (ex. @foo/bar/baz)',
() {
var result = getModuleNameFromPath('@foo/bar/baz');
expect(result, '@foo/bar');
expect(result, equals('@foo/bar'));
});
});
}

0 comments on commit 1492d1c

Please sign in to comment.