From 4c5fe236d54bf91a5da5cf8ef723994ebd040bdf Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 11 Apr 2022 17:09:29 -0700 Subject: [PATCH] Fix and add specs for relative imports with `compileString()` (#1785) The newly-tested behavior matches the specification as updated by sass/sass#3278. --- js-api-spec/compile.test.ts | 22 +++++++++++++++++++--- js-api-spec/sandbox.ts | 12 ++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/js-api-spec/compile.test.ts b/js-api-spec/compile.test.ts index 51c4735e70..0db7a6ffae 100644 --- a/js-api-spec/compile.test.ts +++ b/js-api-spec/compile.test.ts @@ -121,7 +121,7 @@ describe('compileString', () => { }); }); - it('url is used to resolve relative loads', () => + it('file: url is used to resolve relative loads', () => sandbox(dir => { dir.write({'foo/bar/_other.scss': 'a {b: c}'}); @@ -244,14 +244,30 @@ describe('compileString', () => { it('relative loads fail without a URL', () => sandbox(dir => { - dir.write({'other.scss': 'a {b: c}'}); + dir.write({'_other.scss': 'a {b: c}'}); - expect(() => compileString('@use "other";')).toThrowSassException({ + expect(() => + compileString(`@use "${dir.relativeUrl('other')}";`) + ).toThrowSassException({ line: 0, noUrl: true, }); })); + it('relative loads fail with a non-file: URL', () => + sandbox(dir => { + dir.write({'_other.scss': 'a {b: c}'}); + + expect(() => + compileString(`@use "${dir.relativeUrl('other')}";`, { + url: new URL('unknown:style.scss'), + }) + ).toThrowSassException({ + line: 0, + url: 'unknown:style.scss', + }); + })); + describe('includes source span information', () => { it('in syntax errors', () => sandbox(dir => { diff --git a/js-api-spec/sandbox.ts b/js-api-spec/sandbox.ts index 8b7390fd84..64a198fc11 100644 --- a/js-api-spec/sandbox.ts +++ b/js-api-spec/sandbox.ts @@ -36,6 +36,12 @@ export async function sandbox( Object.assign((...paths: string[]) => p.join(testDir, ...paths), { root: testDir, url: (...paths: string[]) => pathToFileURL(p.join(testDir, ...paths)), + relativeUrl: (...paths: string[]) => { + const path = p.relative(process.cwd(), p.join(testDir, ...paths)); + const components = + p.sep === '\\' ? path.split(/[/\\]/) : path.split('/'); + return components.map(encodeURIComponent).join('/'); + }, write: (paths: {[path: string]: string}) => { for (const [path, contents] of Object.entries(paths)) { const fullPath = p.join(testDir, path); @@ -74,6 +80,12 @@ interface SandboxDirectory { */ url(...paths: string[]): URL; + /** + * Joins `paths` underneath `root` and converts the result to a relative + * `file:`-style URL. + */ + relativeUrl(...paths: string[]): string; + /** * Writes `paths` to disk within this directory. *