diff --git a/test/sourcemaps/helpers.ts b/test/sourcemaps/helpers.ts
index d0bea310e6..af3b02f85e 100644
--- a/test/sourcemaps/helpers.ts
+++ b/test/sourcemaps/helpers.ts
@@ -1,4 +1,26 @@
-import MagicString from 'magic-string';
+import MagicString, { Bundle } from 'magic-string';
+
+export function magic_string_bundle(
+ inputs: Array<{ code: string | MagicString, filename: string }>,
+ filename = 'bundle.js',
+ separator = '\n'
+) {
+ const bundle = new Bundle({ separator });
+ inputs.forEach(({ code, filename }) => {
+ bundle.addSource({
+ filename,
+ content: typeof code === 'string' ? new MagicString(code) : code
+ });
+ });
+ return {
+ code: bundle.toString(),
+ map: bundle.generateMap({
+ source: filename,
+ hires: true,
+ includeContent: false
+ })
+ };
+}
export function magic_string_preprocessor_result(filename: string, src: MagicString) {
return {
diff --git a/test/sourcemaps/samples/external/_config.js b/test/sourcemaps/samples/external/_config.js
new file mode 100644
index 0000000000..349df3aeae
--- /dev/null
+++ b/test/sourcemaps/samples/external/_config.js
@@ -0,0 +1,23 @@
+import { magic_string_bundle } from '../../helpers';
+
+export const COMMON = ':global(html) { height: 100%; }\n';
+
+// TODO: removing '\n' breaks test
+// - _actual.svelte.map looks correct
+// - _actual.css.map adds reference to on input.svelte
+export const STYLES = '.awesome { color: orange; }\n';
+
+export default {
+ css_map_sources: ['common.scss', 'styles.scss'],
+ js_map_sources: [],
+ preprocess: [
+ {
+ style: () => {
+ return magic_string_bundle([
+ { filename: 'common.scss', code: COMMON },
+ { filename: 'styles.scss', code: STYLES }
+ ]);
+ }
+ }
+ ]
+};
diff --git a/test/sourcemaps/samples/external/input.svelte b/test/sourcemaps/samples/external/input.svelte
new file mode 100644
index 0000000000..94d895e4a7
--- /dev/null
+++ b/test/sourcemaps/samples/external/input.svelte
@@ -0,0 +1,3 @@
+
+
+
Divs ftw!
\ No newline at end of file
diff --git a/test/sourcemaps/samples/external/test.js b/test/sourcemaps/samples/external/test.js
new file mode 100644
index 0000000000..c11f40d758
--- /dev/null
+++ b/test/sourcemaps/samples/external/test.js
@@ -0,0 +1,27 @@
+import { getLocator } from 'locate-character';
+import { COMMON, STYLES } from './_config';
+
+export function test({ assert, input, preprocessed }) {
+
+ const assertMapped = (locateInput, code, filename) => {
+ const sourceLoc = locateInput(code);
+ const transformedLoc = preprocessed.locate_1(code);
+ assert.deepEqual(
+ preprocessed.mapConsumer.originalPositionFor(transformedLoc),
+ {
+ source: filename,
+ name: null,
+ line: sourceLoc.line + 1,
+ column: sourceLoc.column
+ },
+ `failed to locate "${code}"`
+ );
+ };
+
+ // Transformed script, main file
+ assertMapped(input.locate, 'Divs ftw!', 'input.svelte');
+
+ // External files
+ assertMapped(getLocator(COMMON), 'height: 100%;', 'common.scss');
+ assertMapped(getLocator(STYLES), 'color: orange;', 'styles.scss');
+}
diff --git a/test/sourcemaps/samples/guess-source/_config.js b/test/sourcemaps/samples/guess-source/_config.js
new file mode 100644
index 0000000000..4cc5d9d7b7
--- /dev/null
+++ b/test/sourcemaps/samples/guess-source/_config.js
@@ -0,0 +1,19 @@
+import { magic_string_bundle } from '../../helpers';
+
+export const PREPEND = 'console.log("COUNTER_START")';
+export const APPEND = 'console.log("COUNTER_END")';
+
+export default {
+ js_map_sources: ['input.svelte', 'src/prepend.js', 'src/append.js'],
+ preprocess: [
+ {
+ script: ({ content }) => {
+ return magic_string_bundle([
+ { filename: 'src/prepend.js', code: PREPEND },
+ { filename: 'src/input.svelte', code: content },
+ { filename: 'src/append.js', code: APPEND }
+ ]);
+ }
+ }
+ ]
+};
diff --git a/test/sourcemaps/samples/guess-source/input.svelte b/test/sourcemaps/samples/guess-source/input.svelte
new file mode 100644
index 0000000000..da111701ef
--- /dev/null
+++ b/test/sourcemaps/samples/guess-source/input.svelte
@@ -0,0 +1,6 @@
+
+
+Hello world!
+Counter value: {count}
diff --git a/test/sourcemaps/samples/guess-source/test.js b/test/sourcemaps/samples/guess-source/test.js
new file mode 100644
index 0000000000..6ef7fb1829
--- /dev/null
+++ b/test/sourcemaps/samples/guess-source/test.js
@@ -0,0 +1,30 @@
+import { getLocator } from 'locate-character';
+import { APPEND, PREPEND } from './_config';
+
+export function test({ assert, input, preprocessed }) {
+
+ const assertMapped = (locateInput, code, filename) => {
+ const sourceLoc = locateInput(code);
+ const transformedLoc = preprocessed.locate_1(code);
+ assert.deepEqual(
+ preprocessed.mapConsumer.originalPositionFor(transformedLoc),
+ {
+ source: filename,
+ name: null,
+ line: sourceLoc.line + 1,
+ column: sourceLoc.column
+ },
+ `failed to locate "${code}"`
+ );
+ };
+
+ // Transformed script, main file
+ assertMapped(input.locate, 'let count = 3;', 'input.svelte');
+
+ // Untouched markup, main file
+ assertMapped(input.locate, 'Hello world!
', 'input.svelte');
+
+ // External files
+ assertMapped(getLocator(PREPEND), '"COUNTER_START"', 'src/prepend.js');
+ assertMapped(getLocator(APPEND), '"COUNTER_END"', 'src/append.js');
+}
diff --git a/test/sourcemaps/samples/typescript/input.svelte b/test/sourcemaps/samples/typescript/input.svelte
index 718336f346..93639544b6 100644
--- a/test/sourcemaps/samples/typescript/input.svelte
+++ b/test/sourcemaps/samples/typescript/input.svelte
@@ -1,12 +1,17 @@
Hello world!
diff --git a/test/sourcemaps/samples/typescript/test.js b/test/sourcemaps/samples/typescript/test.js
index 473d7aaa1b..73e2c8a66b 100644
--- a/test/sourcemaps/samples/typescript/test.js
+++ b/test/sourcemaps/samples/typescript/test.js
@@ -1,17 +1,30 @@
export function test({ assert, input, preprocessed }) {
- const content = 'Hello world!
';
+ const assertMapped = (source, transformed) => {
+ const sourceLoc = input.locate(source);
+ const transformedLoc = preprocessed.locate_1(transformed);
+ assert.deepEqual(
+ preprocessed.mapConsumer.originalPositionFor(transformedLoc),
+ {
+ source: 'input.svelte',
+ name: null,
+ line: sourceLoc.line + 1,
+ column: sourceLoc.column
+ },
+ `failed to locate "${transformed}"`
+ );
+ };
- const original = input.locate(content);
- const transformed = preprocessed.locate_1('Hello world!
');
+ const assertNotMapped = (code) => {
+ const transformedLoc = preprocessed.locate_1(code);
+ assert.strictEqual(transformedLoc, undefined, `failed to remove "${code}"`);
+ };
- assert.deepEqual(
- preprocessed.mapConsumer.originalPositionFor(transformed),
- {
- source: 'input.svelte',
- name: null,
- line: original.line + 1,
- column: original.column
- },
- `failed to locate "${content}"`
- );
+ // TS => JS code
+ assertMapped('let count: number = 0;', 'let count = 0;');
+
+ // Markup, not touched
+ assertMapped('Hello world!
', 'Hello world!
');
+
+ // TS types, removed
+ assertNotMapped('ITimeoutDestroyer');
}