+{:else}
+{/if}
\ No newline at end of file
diff --git a/test/parser/samples/error-else-if-before-closing-2/error.json b/test/parser/samples/error-else-if-before-closing-2/error.json
new file mode 100644
index 000000000000..e55f4f11e567
--- /dev/null
+++ b/test/parser/samples/error-else-if-before-closing-2/error.json
@@ -0,0 +1,6 @@
+{
+ "code": "invalid-elseif-placement",
+ "message": "Expected to close tag before seeing {:else if ...} block",
+ "start": { "line": 3, "column": 9, "character": 25 },
+ "pos": 25
+}
diff --git a/test/parser/samples/error-else-if-before-closing-2/input.svelte b/test/parser/samples/error-else-if-before-closing-2/input.svelte
new file mode 100644
index 000000000000..5ae36df4eb08
--- /dev/null
+++ b/test/parser/samples/error-else-if-before-closing-2/input.svelte
@@ -0,0 +1,4 @@
+{#if true}
+
+{:else if false}
+{/if}
\ No newline at end of file
diff --git a/test/parser/samples/error-else-if-before-closing/error.json b/test/parser/samples/error-else-if-before-closing/error.json
new file mode 100644
index 000000000000..21d16c72a4d6
--- /dev/null
+++ b/test/parser/samples/error-else-if-before-closing/error.json
@@ -0,0 +1,6 @@
+{
+ "code": "invalid-elseif-placement",
+ "message": "Expected to close {#await} block before seeing {:else if ...} block",
+ "start": { "line": 3, "column": 9, "character": 34 },
+ "pos": 34
+}
diff --git a/test/parser/samples/error-else-if-before-closing/input.svelte b/test/parser/samples/error-else-if-before-closing/input.svelte
new file mode 100644
index 000000000000..486a921a9a49
--- /dev/null
+++ b/test/parser/samples/error-else-if-before-closing/input.svelte
@@ -0,0 +1,4 @@
+{#if true}
+ {#await foo}
+{:else if false}
+{/if}
\ No newline at end of file
diff --git a/test/parser/samples/error-else-if-without-if/error.json b/test/parser/samples/error-else-if-without-if/error.json
new file mode 100644
index 000000000000..dd69df677236
--- /dev/null
+++ b/test/parser/samples/error-else-if-without-if/error.json
@@ -0,0 +1,6 @@
+{
+ "code": "invalid-elseif-placement",
+ "message": "Cannot have an {:else if ...} block outside an {#if ...} block",
+ "start": { "line": 3, "column": 10, "character": 35 },
+ "pos": 35
+}
diff --git a/test/parser/samples/error-else-if-without-if/input.svelte b/test/parser/samples/error-else-if-without-if/input.svelte
new file mode 100644
index 000000000000..06baf335111b
--- /dev/null
+++ b/test/parser/samples/error-else-if-without-if/input.svelte
@@ -0,0 +1,4 @@
+{#await foo}
+{:then bar}
+ {:else if}
+{/await}
\ No newline at end of file
diff --git a/test/parser/samples/error-then-before-closing/error.json b/test/parser/samples/error-then-before-closing/error.json
new file mode 100644
index 000000000000..07310c93fae9
--- /dev/null
+++ b/test/parser/samples/error-then-before-closing/error.json
@@ -0,0 +1,6 @@
+{
+ "code": "invalid-then-placement",
+ "message": "Expected to close
+{:then f}
+{/await}
\ No newline at end of file
diff --git a/test/parser/samples/event-handler/output.json b/test/parser/samples/event-handler/output.json
index 44bb83de7dfa..95db9998f470 100644
--- a/test/parser/samples/event-handler/output.json
+++ b/test/parser/samples/event-handler/output.json
@@ -128,6 +128,16 @@
"type": "Identifier",
"start": 68,
"end": 75,
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 5
+ },
+ "end": {
+ "line": 3,
+ "column": 12
+ }
+ },
"name": "visible"
},
"children": [
diff --git a/test/parser/samples/if-block-else/output.json b/test/parser/samples/if-block-else/output.json
index 8b22cfa26b3a..1f2cff3ff9e6 100644
--- a/test/parser/samples/if-block-else/output.json
+++ b/test/parser/samples/if-block-else/output.json
@@ -12,6 +12,16 @@
"type": "Identifier",
"start": 5,
"end": 8,
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 5
+ },
+ "end": {
+ "line": 1,
+ "column": 8
+ }
+ },
"name": "foo"
},
"children": [
diff --git a/test/parser/samples/if-block/output.json b/test/parser/samples/if-block/output.json
index 1714bb7141c3..ef895a366abf 100644
--- a/test/parser/samples/if-block/output.json
+++ b/test/parser/samples/if-block/output.json
@@ -12,6 +12,16 @@
"type": "Identifier",
"start": 5,
"end": 8,
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 5
+ },
+ "end": {
+ "line": 1,
+ "column": 8
+ }
+ },
"name": "foo"
},
"children": [
diff --git a/test/parser/samples/implicitly-closed-li-block/output.json b/test/parser/samples/implicitly-closed-li-block/output.json
index 4a75a34223db..767f64053cd1 100644
--- a/test/parser/samples/implicitly-closed-li-block/output.json
+++ b/test/parser/samples/implicitly-closed-li-block/output.json
@@ -40,6 +40,16 @@
"type": "Literal",
"start": 18,
"end": 22,
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 6
+ },
+ "end": {
+ "line": 3,
+ "column": 10
+ }
+ },
"value": true,
"raw": "true"
},
diff --git a/test/parser/samples/no-error-if-before-closing/input.svelte b/test/parser/samples/no-error-if-before-closing/input.svelte
new file mode 100644
index 000000000000..4059e0d4d108
--- /dev/null
+++ b/test/parser/samples/no-error-if-before-closing/input.svelte
@@ -0,0 +1,19 @@
+{#if true}
+
+{:else}
+{/if}
+
+{#if true}
+
+{:else}
+{/if}
+
+{#await true}
+
+{:then f}
+{/await}
+
+{#await true}
+
+{:then f}
+{/await}
\ No newline at end of file
diff --git a/test/parser/samples/no-error-if-before-closing/output.json b/test/parser/samples/no-error-if-before-closing/output.json
new file mode 100644
index 000000000000..251cefc0ca81
--- /dev/null
+++ b/test/parser/samples/no-error-if-before-closing/output.json
@@ -0,0 +1,258 @@
+{
+ "html": {
+ "start": 0,
+ "end": 148,
+ "type": "Fragment",
+ "children": [
+ {
+ "start": 0,
+ "end": 33,
+ "type": "IfBlock",
+ "expression": {
+ "type": "Literal",
+ "start": 5,
+ "end": 9,
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 5
+ },
+ "end": {
+ "line": 1,
+ "column": 9
+ }
+ },
+ "value": true,
+ "raw": "true"
+ },
+ "children": [
+ {
+ "start": 12,
+ "end": 19,
+ "type": "Element",
+ "name": "input",
+ "attributes": [],
+ "children": []
+ }
+ ],
+ "else": {
+ "start": 27,
+ "end": 28,
+ "type": "ElseBlock",
+ "children": []
+ }
+ },
+ {
+ "start": 33,
+ "end": 35,
+ "type": "Text",
+ "raw": "\n\n",
+ "data": "\n\n"
+ },
+ {
+ "start": 35,
+ "end": 65,
+ "type": "IfBlock",
+ "expression": {
+ "type": "Literal",
+ "start": 40,
+ "end": 44,
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 5
+ },
+ "end": {
+ "line": 6,
+ "column": 9
+ }
+ },
+ "value": true,
+ "raw": "true"
+ },
+ "children": [
+ {
+ "start": 47,
+ "end": 51,
+ "type": "Element",
+ "name": "br",
+ "attributes": [],
+ "children": []
+ }
+ ],
+ "else": {
+ "start": 59,
+ "end": 60,
+ "type": "ElseBlock",
+ "children": []
+ }
+ },
+ {
+ "start": 65,
+ "end": 67,
+ "type": "Text",
+ "raw": "\n\n",
+ "data": "\n\n"
+ },
+ {
+ "start": 67,
+ "end": 108,
+ "type": "AwaitBlock",
+ "expression": {
+ "type": "Literal",
+ "start": 75,
+ "end": 79,
+ "loc": {
+ "start": {
+ "line": 11,
+ "column": 8
+ },
+ "end": {
+ "line": 11,
+ "column": 12
+ }
+ },
+ "value": true,
+ "raw": "true"
+ },
+ "value": "f",
+ "error": null,
+ "pending": {
+ "start": 80,
+ "end": 90,
+ "type": "PendingBlock",
+ "children": [
+ {
+ "start": 80,
+ "end": 82,
+ "type": "Text",
+ "raw": "\n\t",
+ "data": "\n\t"
+ },
+ {
+ "start": 82,
+ "end": 89,
+ "type": "Element",
+ "name": "input",
+ "attributes": [],
+ "children": []
+ },
+ {
+ "start": 89,
+ "end": 90,
+ "type": "Text",
+ "raw": "\n",
+ "data": "\n"
+ }
+ ],
+ "skip": false
+ },
+ "then": {
+ "start": 90,
+ "end": 100,
+ "type": "ThenBlock",
+ "children": [
+ {
+ "start": 99,
+ "end": 100,
+ "type": "Text",
+ "raw": "\n",
+ "data": "\n"
+ }
+ ],
+ "skip": false
+ },
+ "catch": {
+ "start": null,
+ "end": null,
+ "type": "CatchBlock",
+ "children": [],
+ "skip": true
+ }
+ },
+ {
+ "start": 108,
+ "end": 110,
+ "type": "Text",
+ "raw": "\n\n",
+ "data": "\n\n"
+ },
+ {
+ "start": 110,
+ "end": 148,
+ "type": "AwaitBlock",
+ "expression": {
+ "type": "Literal",
+ "start": 118,
+ "end": 122,
+ "loc": {
+ "start": {
+ "line": 16,
+ "column": 8
+ },
+ "end": {
+ "line": 16,
+ "column": 12
+ }
+ },
+ "value": true,
+ "raw": "true"
+ },
+ "value": "f",
+ "error": null,
+ "pending": {
+ "start": 123,
+ "end": 130,
+ "type": "PendingBlock",
+ "children": [
+ {
+ "start": 123,
+ "end": 125,
+ "type": "Text",
+ "raw": "\n\t",
+ "data": "\n\t"
+ },
+ {
+ "start": 125,
+ "end": 129,
+ "type": "Element",
+ "name": "br",
+ "attributes": [],
+ "children": []
+ },
+ {
+ "start": 129,
+ "end": 130,
+ "type": "Text",
+ "raw": "\n",
+ "data": "\n"
+ }
+ ],
+ "skip": false
+ },
+ "then": {
+ "start": 130,
+ "end": 140,
+ "type": "ThenBlock",
+ "children": [
+ {
+ "start": 139,
+ "end": 140,
+ "type": "Text",
+ "raw": "\n",
+ "data": "\n"
+ }
+ ],
+ "skip": false
+ },
+ "catch": {
+ "start": null,
+ "end": null,
+ "type": "CatchBlock",
+ "children": [],
+ "skip": true
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/test/parser/samples/refs/output.json b/test/parser/samples/refs/output.json
index 72a3d7689c4a..fb94ffd70156 100644
--- a/test/parser/samples/refs/output.json
+++ b/test/parser/samples/refs/output.json
@@ -27,6 +27,16 @@
"type": "Identifier",
"start": 49,
"end": 52,
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 19
+ },
+ "end": {
+ "line": 5,
+ "column": 22
+ }
+ },
"name": "foo"
}
}
diff --git a/test/parser/samples/script-comment-only/output.json b/test/parser/samples/script-comment-only/output.json
index 3441d8a7bb12..e090b30ae6a6 100644
--- a/test/parser/samples/script-comment-only/output.json
+++ b/test/parser/samples/script-comment-only/output.json
@@ -41,7 +41,15 @@
}
},
"body": [],
- "sourceType": "module"
+ "sourceType": "module",
+ "trailingComments": [
+ {
+ "type": "Line",
+ "value": " TODO write some code",
+ "start": 10,
+ "end": 33
+ }
+ ]
}
}
}
\ No newline at end of file
diff --git a/test/parser/samples/script-comment-trailing-multiline/output.json b/test/parser/samples/script-comment-trailing-multiline/output.json
index 3c02b1fbde2d..184a29978d7d 100644
--- a/test/parser/samples/script-comment-trailing-multiline/output.json
+++ b/test/parser/samples/script-comment-trailing-multiline/output.json
@@ -33,6 +33,16 @@
"type": "Identifier",
"start": 90,
"end": 94,
+ "loc": {
+ "start": {
+ "line": 9,
+ "column": 11
+ },
+ "end": {
+ "line": 9,
+ "column": 15
+ }
+ },
"name": "name"
}
},
@@ -134,7 +144,15 @@
"kind": "let"
}
],
- "sourceType": "module"
+ "sourceType": "module",
+ "trailingComments": [
+ {
+ "type": "Block",
+ "value": "\n\ttrailing multiline comment\n",
+ "start": 32,
+ "end": 67
+ }
+ ]
}
}
}
\ No newline at end of file
diff --git a/test/parser/samples/script-comment-trailing/output.json b/test/parser/samples/script-comment-trailing/output.json
index beca0010426a..2aca23f667a8 100644
--- a/test/parser/samples/script-comment-trailing/output.json
+++ b/test/parser/samples/script-comment-trailing/output.json
@@ -33,6 +33,16 @@
"type": "Identifier",
"start": 79,
"end": 83,
+ "loc": {
+ "start": {
+ "line": 7,
+ "column": 11
+ },
+ "end": {
+ "line": 7,
+ "column": 15
+ }
+ },
"name": "name"
}
},
@@ -134,7 +144,15 @@
"kind": "let"
}
],
- "sourceType": "module"
+ "sourceType": "module",
+ "trailingComments": [
+ {
+ "type": "Line",
+ "value": " trailing line comment",
+ "start": 32,
+ "end": 56
+ }
+ ]
}
}
}
\ No newline at end of file
diff --git a/test/parser/samples/script/output.json b/test/parser/samples/script/output.json
index 00b7073a1940..4d0aa9cf3613 100644
--- a/test/parser/samples/script/output.json
+++ b/test/parser/samples/script/output.json
@@ -33,6 +33,16 @@
"type": "Identifier",
"start": 52,
"end": 56,
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 11
+ },
+ "end": {
+ "line": 5,
+ "column": 15
+ }
+ },
"name": "name"
}
},
diff --git a/test/parser/samples/space-between-mustaches/output.json b/test/parser/samples/space-between-mustaches/output.json
index 9a367bd2c1f3..b89f4d6c8327 100644
--- a/test/parser/samples/space-between-mustaches/output.json
+++ b/test/parser/samples/space-between-mustaches/output.json
@@ -26,6 +26,16 @@
"type": "Identifier",
"start": 5,
"end": 6,
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 5
+ },
+ "end": {
+ "line": 1,
+ "column": 6
+ }
+ },
"name": "a"
}
},
@@ -44,6 +54,16 @@
"type": "Identifier",
"start": 9,
"end": 10,
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 9
+ },
+ "end": {
+ "line": 1,
+ "column": 10
+ }
+ },
"name": "b"
}
},
@@ -62,6 +82,16 @@
"type": "Identifier",
"start": 15,
"end": 16,
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 15
+ },
+ "end": {
+ "line": 1,
+ "column": 16
+ }
+ },
"name": "c"
}
},
diff --git a/test/parser/samples/spread/output.json b/test/parser/samples/spread/output.json
index 73a0dc97778b..3a5c471905d3 100644
--- a/test/parser/samples/spread/output.json
+++ b/test/parser/samples/spread/output.json
@@ -18,6 +18,16 @@
"type": "Identifier",
"start": 9,
"end": 14,
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 9
+ },
+ "end": {
+ "line": 1,
+ "column": 14
+ }
+ },
"name": "props"
}
}
diff --git a/test/parser/samples/textarea-children/output.json b/test/parser/samples/textarea-children/output.json
index 90f31f3caff9..919fa33fde1e 100644
--- a/test/parser/samples/textarea-children/output.json
+++ b/test/parser/samples/textarea-children/output.json
@@ -29,6 +29,16 @@
"type": "Identifier",
"start": 41,
"end": 44,
+ "loc": {
+ "start": {
+ "line": 2,
+ "column": 30
+ },
+ "end": {
+ "line": 2,
+ "column": 33
+ }
+ },
"name": "foo"
}
},
diff --git a/test/parser/samples/whitespace-normal/output.json b/test/parser/samples/whitespace-normal/output.json
index acbae7ae17b6..61eca1329f0e 100644
--- a/test/parser/samples/whitespace-normal/output.json
+++ b/test/parser/samples/whitespace-normal/output.json
@@ -33,6 +33,16 @@
"type": "Identifier",
"start": 19,
"end": 23,
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 19
+ },
+ "end": {
+ "line": 1,
+ "column": 23
+ }
+ },
"name": "name"
}
},
diff --git a/test/parser/samples/yield/input.svelte b/test/parser/samples/yield/input.svelte
deleted file mode 100644
index f5e8aad05330..000000000000
--- a/test/parser/samples/yield/input.svelte
+++ /dev/null
@@ -1 +0,0 @@
-{yield}
\ No newline at end of file
diff --git a/test/parser/samples/yield/output.json b/test/parser/samples/yield/output.json
deleted file mode 100644
index b2e4b9430ff6..000000000000
--- a/test/parser/samples/yield/output.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "html": {
- "start": 0,
- "end": 7,
- "type": "Fragment",
- "children": [
- {
- "start": 0,
- "end": 7,
- "type": "MustacheTag",
- "expression": {
- "type": "Identifier",
- "start": 1,
- "end": 6,
- "name": "yield"
- }
- }
- ]
- }
-}
\ No newline at end of file
diff --git a/test/runtime/index.js b/test/runtime/index.js
index 408fda40f457..f070eb818551 100644
--- a/test/runtime/index.js
+++ b/test/runtime/index.js
@@ -2,7 +2,7 @@ import * as assert from "assert";
import * as path from "path";
import * as fs from "fs";
import { rollup } from 'rollup';
-import * as virtual from 'rollup-plugin-virtual';
+import * as virtual from '@rollup/plugin-virtual';
import * as glob from 'tiny-glob/sync.js';
import { clear_loops, flush, set_now, set_raf } from "../../internal";
@@ -10,6 +10,7 @@ import {
showOutput,
loadConfig,
loadSvelte,
+ cleanRequireCache,
env,
setupHtmlEqual,
mkdirp
@@ -79,11 +80,7 @@ describe("runtime", () => {
compileOptions.immutable = config.immutable;
compileOptions.accessors = 'accessors' in config ? config.accessors : true;
- Object.keys(require.cache)
- .filter(x => x.endsWith('.svelte'))
- .forEach(file => {
- delete require.cache[file];
- });
+ cleanRequireCache();
let mod;
let SvelteComponent;
diff --git a/test/runtime/samples/action-receives-element-mounted/_config.js b/test/runtime/samples/action-receives-element-mounted/_config.js
new file mode 100644
index 000000000000..0806d0fa909f
--- /dev/null
+++ b/test/runtime/samples/action-receives-element-mounted/_config.js
@@ -0,0 +1,8 @@
+const result = {};
+
+export default {
+ props: { result },
+ async test({ assert, component, target, window }) {
+ assert.notEqual(result.parentElement, null);
+ }
+};
diff --git a/test/runtime/samples/action-receives-element-mounted/main.svelte b/test/runtime/samples/action-receives-element-mounted/main.svelte
new file mode 100644
index 000000000000..a53ce81de0ac
--- /dev/null
+++ b/test/runtime/samples/action-receives-element-mounted/main.svelte
@@ -0,0 +1,8 @@
+
+
+Hello!
\ No newline at end of file
diff --git a/test/runtime/samples/apply-directives-in-order-2/_config.js b/test/runtime/samples/apply-directives-in-order-2/_config.js
new file mode 100644
index 000000000000..a74ce41cb66f
--- /dev/null
+++ b/test/runtime/samples/apply-directives-in-order-2/_config.js
@@ -0,0 +1,38 @@
+const value = [];
+export default {
+ props: {
+ value,
+ },
+
+ async test({ assert, component, target, window }) {
+ const inputs = target.querySelectorAll('input');
+
+ const event = new window.Event('input');
+
+ for (const input of inputs) {
+ input.value = 'h';
+ await input.dispatchEvent(event);
+ }
+
+ assert.deepEqual(value, [
+ '1',
+ '2',
+ '3',
+ '4',
+ '5',
+ '6',
+ '7',
+ '8',
+ '9',
+ '10',
+ '11',
+ '12',
+ '13',
+ '14',
+ '15',
+ '16',
+ '17',
+ '18',
+ ]);
+ },
+};
diff --git a/test/runtime/samples/apply-directives-in-order-2/main.svelte b/test/runtime/samples/apply-directives-in-order-2/main.svelte
new file mode 100644
index 000000000000..e91c4b6a1497
--- /dev/null
+++ b/test/runtime/samples/apply-directives-in-order-2/main.svelte
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
diff --git a/test/runtime/samples/apply-directives-in-order/_config.js b/test/runtime/samples/apply-directives-in-order/_config.js
new file mode 100644
index 000000000000..e5e8980ed115
--- /dev/null
+++ b/test/runtime/samples/apply-directives-in-order/_config.js
@@ -0,0 +1,37 @@
+export default {
+ props: {
+ value: ''
+ },
+
+ html: `
+
+
+ `,
+
+ ssrHtml: `
+
+
+ `,
+
+ async test({ assert, component, target, window }) {
+ const input = target.querySelector('input');
+
+ const event = new window.Event('input');
+ input.value = 'h';
+ await input.dispatchEvent(event);
+
+ assert.equal(input.value, 'H');
+ assert.htmlEqual(target.innerHTML, `
+
+ H
+ `);
+
+ input.value = 'he';
+ await input.dispatchEvent(event);
+ assert.equal(input.value, 'HE');
+ assert.htmlEqual(target.innerHTML, `
+
+ HE
+ `);
+ },
+};
diff --git a/test/runtime/samples/apply-directives-in-order/main.svelte b/test/runtime/samples/apply-directives-in-order/main.svelte
new file mode 100644
index 000000000000..be652c7b7956
--- /dev/null
+++ b/test/runtime/samples/apply-directives-in-order/main.svelte
@@ -0,0 +1,10 @@
+
+
+
+{value}
diff --git a/test/runtime/samples/binding-indirect-spread/_config.js b/test/runtime/samples/binding-indirect-spread/_config.js
new file mode 100644
index 000000000000..1f24fcdbcb12
--- /dev/null
+++ b/test/runtime/samples/binding-indirect-spread/_config.js
@@ -0,0 +1,44 @@
+export default {
+ skip_if_ssr: true,
+ async test({ assert, component, target, window }) {
+ const event = new window.MouseEvent('click');
+
+ const [radio1, radio2, radio3] = target.querySelectorAll('input[type=radio]');
+
+ assert.ok(!radio1.checked);
+ assert.ok(radio2.checked);
+ assert.ok(!radio3.checked);
+
+ component.radio = 'radio1';
+
+ assert.ok(radio1.checked);
+ assert.ok(!radio2.checked);
+ assert.ok(!radio3.checked);
+
+ await radio3.dispatchEvent(event);
+
+ assert.equal(component.radio, 'radio3');
+ assert.ok(!radio1.checked);
+ assert.ok(!radio2.checked);
+ assert.ok(radio3.checked);
+
+ const [check1, check2, check3] = target.querySelectorAll('input[type=checkbox]');
+
+ assert.ok(!check1.checked);
+ assert.ok(check2.checked);
+ assert.ok(!check3.checked);
+
+ component.check = ['check1', 'check2'];
+
+ assert.ok(check1.checked);
+ assert.ok(check2.checked);
+ assert.ok(!check3.checked);
+
+ await check3.dispatchEvent(event);
+
+ assert.deepEqual(component.check, ['check1', 'check2', 'check3']);
+ assert.ok(check1.checked);
+ assert.ok(check2.checked);
+ assert.ok(check3.checked);
+ }
+};
diff --git a/test/runtime/samples/binding-indirect-spread/main.svelte b/test/runtime/samples/binding-indirect-spread/main.svelte
new file mode 100644
index 000000000000..43129b08b7d6
--- /dev/null
+++ b/test/runtime/samples/binding-indirect-spread/main.svelte
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
diff --git a/test/runtime/samples/bitmask-overflow-if/_config.js b/test/runtime/samples/bitmask-overflow-if/_config.js
new file mode 100644
index 000000000000..74bc70d4144f
--- /dev/null
+++ b/test/runtime/samples/bitmask-overflow-if/_config.js
@@ -0,0 +1,24 @@
+export default {
+ html: `
+ 012345678910111213141516171819202122232425262728293031323334353637383940
+ expected: true
+ if: true
+
+ `,
+
+ async test({ assert, component, target, window }) {
+ const button = target.querySelector("button");
+ await button.dispatchEvent(new window.MouseEvent("click"));
+
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ 112345678910111213141516171819202122232425262728293031323334353637383940
+ expected: false
+ if: false
+
+
+ `
+ );
+ }
+};
diff --git a/test/runtime/samples/bitmask-overflow-if/main.svelte b/test/runtime/samples/bitmask-overflow-if/main.svelte
new file mode 100644
index 000000000000..2c1c4530914f
--- /dev/null
+++ b/test/runtime/samples/bitmask-overflow-if/main.svelte
@@ -0,0 +1,62 @@
+
+
+
+{_0}{_1}{_2}{_3}{_4}{_5}{_6}{_7}{_8}{_9}{_10}{_11}{_12}{_13}{_14}{_15}{_16}{_17}{_18}{_19}{_20}{_21}{_22}{_23}{_24}{_25}{_26}{_27}{_28}{_29}{_30}{_31}{_32}{_33}{_34}{_35}{_36}{_37}{_38}{_39}{_40}
+
+expected: {_a.indexOf(_0) && _0 === '0' && _1 === '1'}
+{#if _a.indexOf(_0) && _0 === '0' && _1 === '1'}
+if: true
+{:else}
+if: false
+
+{/if}
+
+
\ No newline at end of file
diff --git a/test/runtime/samples/bitmask-overflow-slot-3/Echo.svelte b/test/runtime/samples/bitmask-overflow-slot-3/Echo.svelte
new file mode 100644
index 000000000000..d3ecf142c924
--- /dev/null
+++ b/test/runtime/samples/bitmask-overflow-slot-3/Echo.svelte
@@ -0,0 +1,9 @@
+
+
+
+
\ No newline at end of file
diff --git a/test/runtime/samples/bitmask-overflow-slot-3/_config.js b/test/runtime/samples/bitmask-overflow-slot-3/_config.js
new file mode 100644
index 000000000000..93e548e5f7ef
--- /dev/null
+++ b/test/runtime/samples/bitmask-overflow-slot-3/_config.js
@@ -0,0 +1,30 @@
+export default {
+
+ html: `
+ _0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40
+ 0
+
+ `,
+
+ async test({ assert, component, target, window }) {
+ // change from inside
+ const button = target.querySelector('button');
+ await button.dispatchEvent(new window.MouseEvent('click'));
+
+ assert.htmlEqual(target.innerHTML, `
+ _0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40
+ 1
+
+ `);
+
+ // change from outside
+ component._0 = 'a';
+ component._40 = 'b';
+
+ assert.htmlEqual(target.innerHTML, `
+ a_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39b
+ 1
+
+ `);
+ }
+};
\ No newline at end of file
diff --git a/test/runtime/samples/bitmask-overflow-slot-3/main.svelte b/test/runtime/samples/bitmask-overflow-slot-3/main.svelte
new file mode 100644
index 000000000000..ae798e4aeeb5
--- /dev/null
+++ b/test/runtime/samples/bitmask-overflow-slot-3/main.svelte
@@ -0,0 +1,11 @@
+
+
+
+ {_0}{_1}{_2}{_3}{_4}{_5}{_6}{_7}{_8}{_9}{_10}{_11}{_12}{_13}{_14}{_15}{_16}{_17}{_18}{_19}{_20}{_21}{_22}{_23}{_24}{_25}{_26}{_27}{_28}{_29}{_30}{_31}{_32}{_33}{_34}{_35}{_36}{_37}{_38}{_39}{_40}
+ {dummy}
+
+
diff --git a/test/runtime/samples/bitmask-overflow-slot-4/Echo.svelte b/test/runtime/samples/bitmask-overflow-slot-4/Echo.svelte
new file mode 100644
index 000000000000..2e1beda492d9
--- /dev/null
+++ b/test/runtime/samples/bitmask-overflow-slot-4/Echo.svelte
@@ -0,0 +1,11 @@
+
+
+{_0}{_1}{_2}{_3}{_4}{_5}{_6}{_7}{_8}{_9}{_10}{_11}{_12}{_13}{_14}{_15}{_16}{_17}{_18}{_19}{_20}{_21}{_22}{_23}{_24}{_25}{_26}{_27}{_28}{_29}{_30}{_31}{_32}{_33}{_34}{_35}{_36}{_37}{_38}{_39}{_40}
+
+
\ No newline at end of file
diff --git a/test/runtime/samples/bitmask-overflow-slot-4/_config.js b/test/runtime/samples/bitmask-overflow-slot-4/_config.js
new file mode 100644
index 000000000000..cdaa5de77fa6
--- /dev/null
+++ b/test/runtime/samples/bitmask-overflow-slot-4/_config.js
@@ -0,0 +1,41 @@
+export default {
+ html: `
+ _0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40
+ 0
+ 0
+
+ `,
+
+ async test({ assert, component, target, window }) {
+ // change from inside
+ const button = target.querySelector('button');
+ await button.dispatchEvent(new window.MouseEvent('click'));
+
+ assert.htmlEqual(target.innerHTML, `
+ _0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40
+ 0
+ 1
+
+ `);
+
+ // change from outside
+ component._0 = 'a';
+
+ assert.htmlEqual(target.innerHTML, `
+ _0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40
+ a
+ 1
+
+ `);
+
+ // change from outside through props
+ component._40 = 'b';
+
+ assert.htmlEqual(target.innerHTML, `
+ _0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39b
+ a
+ 1
+
+ `);
+ }
+};
\ No newline at end of file
diff --git a/test/runtime/samples/bitmask-overflow-slot-4/main.svelte b/test/runtime/samples/bitmask-overflow-slot-4/main.svelte
new file mode 100644
index 000000000000..7e02487a305d
--- /dev/null
+++ b/test/runtime/samples/bitmask-overflow-slot-4/main.svelte
@@ -0,0 +1,12 @@
+
+
+
+ {_0}
+ {dummy}
+
+
diff --git a/test/runtime/samples/bitmask-overflow-slot-5/Echo.svelte b/test/runtime/samples/bitmask-overflow-slot-5/Echo.svelte
new file mode 100644
index 000000000000..dddb3f76428f
--- /dev/null
+++ b/test/runtime/samples/bitmask-overflow-slot-5/Echo.svelte
@@ -0,0 +1,13 @@
+
+
+{_0}{_1}{_2}{_3}{_4}{_5}{_6}{_7}{_8}{_9}{_10}{_11}{_12}{_13}{_14}{_15}{_16}{_17}{_18}{_19}{_20}{_21}{_22}{_23}{_24}{_25}{_26}{_27}{_28}{_29}{_30}{_31}{_32}{_33}{_34}{_35}{_36}{_37}{_38}{_39}{_40}
+{b}
+
+
\ No newline at end of file
diff --git a/test/runtime/samples/bitmask-overflow-slot-5/_config.js b/test/runtime/samples/bitmask-overflow-slot-5/_config.js
new file mode 100644
index 000000000000..7dedb8f7ebde
--- /dev/null
+++ b/test/runtime/samples/bitmask-overflow-slot-5/_config.js
@@ -0,0 +1,49 @@
+export default {
+ html: `
+ _0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40
+ b
+ -0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-31-32-33-34-35-36-37-38-39-40
+ 0
+ 0
+
+ `,
+
+ async test({ assert, component, target, window }) {
+ // change from inside
+ const button = target.querySelector('button');
+ await button.dispatchEvent(new window.MouseEvent('click'));
+
+ assert.htmlEqual(target.innerHTML, `
+ _0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40
+ b
+ -0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-31-32-33-34-35-36-37-38-39-40
+ 0
+ 1
+
+ `);
+
+ // change from outside
+ component.a = 'AA';
+
+ assert.htmlEqual(target.innerHTML, `
+ _0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40
+ b
+ -0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-31-32-33-34-35-36-37-38-39-40
+ AA
+ 1
+
+ `);
+
+ // change from outside through props
+ component.b = 'BB';
+
+ assert.htmlEqual(target.innerHTML, `
+ _0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40
+ BB
+ -0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-31-32-33-34-35-36-37-38-39-40
+ AA
+ 1
+
+ `);
+ }
+};
\ No newline at end of file
diff --git a/test/runtime/samples/bitmask-overflow-slot-5/main.svelte b/test/runtime/samples/bitmask-overflow-slot-5/main.svelte
new file mode 100644
index 000000000000..b17d6f7baef8
--- /dev/null
+++ b/test/runtime/samples/bitmask-overflow-slot-5/main.svelte
@@ -0,0 +1,13 @@
+
+
+
+ {_0}{_1}{_2}{_3}{_4}{_5}{_6}{_7}{_8}{_9}{_10}{_11}{_12}{_13}{_14}{_15}{_16}{_17}{_18}{_19}{_20}{_21}{_22}{_23}{_24}{_25}{_26}{_27}{_28}{_29}{_30}{_31}{_32}{_33}{_34}{_35}{_36}{_37}{_38}{_39}{_40}
+ {a}
+ {dummy}
+
+
diff --git a/test/runtime/samples/component-binding-blowback-c/main.svelte b/test/runtime/samples/component-binding-blowback-c/main.svelte
index 4876af13a8a9..75552bf358d0 100644
--- a/test/runtime/samples/component-binding-blowback-c/main.svelte
+++ b/test/runtime/samples/component-binding-blowback-c/main.svelte
@@ -4,7 +4,7 @@
export let count;
export let idToValue = Object.create(null);
- function ids() {
+ function ids(count) {
return new Array(count)
.fill(null)
.map((_, i) => ({ id: 'id-' + i}))
@@ -15,7 +15,7 @@
- {#each ids() as object (object.id)}
+ {#each ids(count) as object (object.id)}
{object.id}: value is {idToValue[object.id]}
diff --git a/test/runtime/samples/component-slot-fallback-empty/Nested.svelte b/test/runtime/samples/component-slot-fallback-empty/Nested.svelte
new file mode 100644
index 000000000000..9e6683feb77a
--- /dev/null
+++ b/test/runtime/samples/component-slot-fallback-empty/Nested.svelte
@@ -0,0 +1,4 @@
+
+
default fallback content
+
bar fallback
+
\ No newline at end of file
diff --git a/test/runtime/samples/component-slot-fallback-empty/_config.js b/test/runtime/samples/component-slot-fallback-empty/_config.js
new file mode 100644
index 000000000000..2e153d24db01
--- /dev/null
+++ b/test/runtime/samples/component-slot-fallback-empty/_config.js
@@ -0,0 +1,13 @@
+export default {
+ html: `
+
+
default fallback content
+
+
+
+
+
default fallback content
+ bar fallback
+
+ `
+};
diff --git a/test/runtime/samples/component-slot-fallback-empty/main.svelte b/test/runtime/samples/component-slot-fallback-empty/main.svelte
new file mode 100644
index 000000000000..7ae5f4c5d778
--- /dev/null
+++ b/test/runtime/samples/component-slot-fallback-empty/main.svelte
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
diff --git a/test/runtime/samples/component-slot-let-destructured-2/Nested.svelte b/test/runtime/samples/component-slot-let-destructured-2/Nested.svelte
new file mode 100644
index 000000000000..5dfe32bc7ff6
--- /dev/null
+++ b/test/runtime/samples/component-slot-let-destructured-2/Nested.svelte
@@ -0,0 +1,5 @@
+
+
+
diff --git a/test/runtime/samples/component-slot-let-destructured-2/_config.js b/test/runtime/samples/component-slot-let-destructured-2/_config.js
new file mode 100644
index 000000000000..38b04b7b5e06
--- /dev/null
+++ b/test/runtime/samples/component-slot-let-destructured-2/_config.js
@@ -0,0 +1,68 @@
+export default {
+ html: `
+
+ hello world 0 hello
+ Increment
+
+
+ hello world 0 hello
+ Increment
+
+
+ hello world 0 hello
+ Increment
+
+ `,
+ async test({ assert, component, target, window }) {
+ const [button1, button2, button3] = target.querySelectorAll('button');
+ const event = new window.MouseEvent('click');
+
+ await button1.dispatchEvent(event);
+ assert.htmlEqual(target.innerHTML, `
+
+ hello world 1 hello
+ Increment
+
+
+ hello world 0 hello
+ Increment
+
+
+ hello world 0 hello
+ Increment
+
+ `);
+
+ await button2.dispatchEvent(event);
+ assert.htmlEqual(target.innerHTML, `
+
+ hello world 1 hello
+ Increment
+
+
+ hello world 1 hello
+ Increment
+
+
+ hello world 0 hello
+ Increment
+
+ `);
+
+ await button3.dispatchEvent(event);
+ assert.htmlEqual(target.innerHTML, `
+
+ hello world 1 hello
+ Increment
+
+
+ hello world 1 hello
+ Increment
+
+
+ hello world 1 hello
+ Increment
+
+ `);
+ }
+};
diff --git a/test/runtime/samples/component-slot-let-destructured-2/main.svelte b/test/runtime/samples/component-slot-let-destructured-2/main.svelte
new file mode 100644
index 000000000000..215a1390d90a
--- /dev/null
+++ b/test/runtime/samples/component-slot-let-destructured-2/main.svelte
@@ -0,0 +1,28 @@
+
+
+
+
+ {pair[0]} {pair[1]} {c} {foo}
+
+
+ { c += 1; }}>Increment
+
+
+
+
+ {a} {b} {d} {foo}
+
+
+ { d += 1; }}>Increment
+
+
+
+
+ {a} {b} {e} {foo}
+
+
+ { e += 1; }}>Increment
+
\ No newline at end of file
diff --git a/test/runtime/samples/component-slot-let-g/A.svelte b/test/runtime/samples/component-slot-let-g/A.svelte
new file mode 100644
index 000000000000..4f4ac95014bb
--- /dev/null
+++ b/test/runtime/samples/component-slot-let-g/A.svelte
@@ -0,0 +1,5 @@
+
+
+
\ No newline at end of file
diff --git a/test/runtime/samples/component-slot-let-g/_config.js b/test/runtime/samples/component-slot-let-g/_config.js
new file mode 100644
index 000000000000..aaa9895ea8a0
--- /dev/null
+++ b/test/runtime/samples/component-slot-let-g/_config.js
@@ -0,0 +1,22 @@
+export default {
+ html: `
+ 1
+ 0
+ `,
+ async test({ assert, target, component, window }) {
+ component.x = 2;
+
+ assert.htmlEqual(target.innerHTML, `
+ 2
+ 0
+ `);
+
+ const span = target.querySelector('span');
+ await span.dispatchEvent(new window.MouseEvent('click'));
+
+ assert.htmlEqual(target.innerHTML, `
+ 2
+ 2
+ `);
+ }
+};
diff --git a/test/runtime/samples/component-slot-let-g/main.svelte b/test/runtime/samples/component-slot-let-g/main.svelte
new file mode 100644
index 000000000000..e7d4890e6bf0
--- /dev/null
+++ b/test/runtime/samples/component-slot-let-g/main.svelte
@@ -0,0 +1,17 @@
+
+
+
+ y = reflected}
+ slot="foo"
+ let:reflected
+ class={reflected}
+ >
+ {reflected}
+
+
+{ y }
\ No newline at end of file
diff --git a/test/runtime/samples/component-slot-nested-if/Display.svelte b/test/runtime/samples/component-slot-nested-if/Display.svelte
new file mode 100644
index 000000000000..d9034e4be29a
--- /dev/null
+++ b/test/runtime/samples/component-slot-nested-if/Display.svelte
@@ -0,0 +1,2 @@
+Display:
+
\ No newline at end of file
diff --git a/test/runtime/samples/component-slot-nested-if/Input.svelte b/test/runtime/samples/component-slot-nested-if/Input.svelte
new file mode 100644
index 000000000000..fd8f22db004c
--- /dev/null
+++ b/test/runtime/samples/component-slot-nested-if/Input.svelte
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/test/runtime/samples/component-slot-nested-if/_config.js b/test/runtime/samples/component-slot-nested-if/_config.js
new file mode 100644
index 000000000000..89dfd006cc76
--- /dev/null
+++ b/test/runtime/samples/component-slot-nested-if/_config.js
@@ -0,0 +1,30 @@
+export default {
+ html: `
+
+ `,
+ async test({ assert, target, snapshot, component, window }) {
+ const input = target.querySelector('input');
+
+ input.value = 'a';
+ await input.dispatchEvent(new window.Event('input'));
+
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+ Display: a
+ `
+ );
+
+ input.value = 'abc';
+ await input.dispatchEvent(new window.Event('input'));
+
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+ Display: abc
+ `
+ );
+ },
+};
diff --git a/test/runtime/samples/component-slot-nested-if/main.svelte b/test/runtime/samples/component-slot-nested-if/main.svelte
new file mode 100644
index 000000000000..727927b15714
--- /dev/null
+++ b/test/runtime/samples/component-slot-nested-if/main.svelte
@@ -0,0 +1,10 @@
+
+
+
+ {#if foo}
+ {foo}
+ {/if}
+
diff --git a/test/runtime/samples/component-slot-warning/Nested.svelte b/test/runtime/samples/component-slot-warning/Nested.svelte
new file mode 100644
index 000000000000..c6f086d96c19
--- /dev/null
+++ b/test/runtime/samples/component-slot-warning/Nested.svelte
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/test/runtime/samples/component-slot-warning/_config.js b/test/runtime/samples/component-slot-warning/_config.js
new file mode 100644
index 000000000000..6ffe624782e0
--- /dev/null
+++ b/test/runtime/samples/component-slot-warning/_config.js
@@ -0,0 +1,9 @@
+export default {
+ compileOptions: {
+ dev: true
+ },
+ warnings: [
+ ' received an unexpected slot "default".',
+ ' received an unexpected slot "slot1".'
+ ]
+};
diff --git a/test/runtime/samples/component-slot-warning/main.svelte b/test/runtime/samples/component-slot-warning/main.svelte
new file mode 100644
index 000000000000..c29ef3e85be2
--- /dev/null
+++ b/test/runtime/samples/component-slot-warning/main.svelte
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/test/runtime/samples/deconflict-contextual-bind/Widget.svelte b/test/runtime/samples/deconflict-contextual-bind/Widget.svelte
new file mode 100644
index 000000000000..3aaa59b74757
--- /dev/null
+++ b/test/runtime/samples/deconflict-contextual-bind/Widget.svelte
@@ -0,0 +1,3 @@
+
diff --git a/test/runtime/samples/deconflict-contextual-bind/_config.js b/test/runtime/samples/deconflict-contextual-bind/_config.js
new file mode 100644
index 000000000000..7602cde02323
--- /dev/null
+++ b/test/runtime/samples/deconflict-contextual-bind/_config.js
@@ -0,0 +1,3 @@
+export default {
+ preserveIdentifiers: true
+};
diff --git a/test/runtime/samples/deconflict-contextual-bind/main.svelte b/test/runtime/samples/deconflict-contextual-bind/main.svelte
new file mode 100644
index 000000000000..fe91deca17f1
--- /dev/null
+++ b/test/runtime/samples/deconflict-contextual-bind/main.svelte
@@ -0,0 +1,8 @@
+
+
+{#each values as value}
+
+{/each}
diff --git a/test/runtime/samples/dev-warning-each-block-no-sets-maps/_config.js b/test/runtime/samples/dev-warning-each-block-no-sets-maps/_config.js
new file mode 100644
index 000000000000..83481d9ebebf
--- /dev/null
+++ b/test/runtime/samples/dev-warning-each-block-no-sets-maps/_config.js
@@ -0,0 +1,6 @@
+export default {
+ compileOptions: {
+ dev: true
+ },
+ error: `{#each} only iterates over array-like objects. You can use a spread to convert this iterable into an array.`
+};
diff --git a/test/runtime/samples/dev-warning-each-block-no-sets-maps/main.svelte b/test/runtime/samples/dev-warning-each-block-no-sets-maps/main.svelte
new file mode 100644
index 000000000000..e1aae26d129a
--- /dev/null
+++ b/test/runtime/samples/dev-warning-each-block-no-sets-maps/main.svelte
@@ -0,0 +1,7 @@
+
+
+{#each foo as item}
+ {item}
+{/each}
\ No newline at end of file
diff --git a/test/runtime/samples/dev-warning-each-block-require-arraylike/_config.js b/test/runtime/samples/dev-warning-each-block-require-arraylike/_config.js
new file mode 100644
index 000000000000..62e5fc209b54
--- /dev/null
+++ b/test/runtime/samples/dev-warning-each-block-require-arraylike/_config.js
@@ -0,0 +1,6 @@
+export default {
+ compileOptions: {
+ dev: true
+ },
+ error: `{#each} only iterates over array-like objects.`
+};
diff --git a/test/runtime/samples/dev-warning-each-block-require-arraylike/main.svelte b/test/runtime/samples/dev-warning-each-block-require-arraylike/main.svelte
new file mode 100644
index 000000000000..f85df8d84bd7
--- /dev/null
+++ b/test/runtime/samples/dev-warning-each-block-require-arraylike/main.svelte
@@ -0,0 +1,3 @@
+{#each {} as item}
+ {item}
+{/each}
\ No newline at end of file
diff --git a/test/runtime/samples/dev-warning-unknown-props-2/Foo.svelte b/test/runtime/samples/dev-warning-unknown-props-2/Foo.svelte
new file mode 100644
index 000000000000..bc56c4d89448
--- /dev/null
+++ b/test/runtime/samples/dev-warning-unknown-props-2/Foo.svelte
@@ -0,0 +1 @@
+Foo
diff --git a/test/runtime/samples/dev-warning-unknown-props-2/_config.js b/test/runtime/samples/dev-warning-unknown-props-2/_config.js
new file mode 100644
index 000000000000..9bff4a2a741b
--- /dev/null
+++ b/test/runtime/samples/dev-warning-unknown-props-2/_config.js
@@ -0,0 +1,9 @@
+export default {
+ compileOptions: {
+ dev: true
+ },
+
+ warnings: [
+ ` was created with unknown prop 'fo'`
+ ]
+};
diff --git a/test/runtime/samples/dev-warning-unknown-props-2/main.svelte b/test/runtime/samples/dev-warning-unknown-props-2/main.svelte
new file mode 100644
index 000000000000..1566cf3e41e7
--- /dev/null
+++ b/test/runtime/samples/dev-warning-unknown-props-2/main.svelte
@@ -0,0 +1,5 @@
+
+
+
diff --git a/test/runtime/samples/each-block-destructured-object-reserved-key/_config.js b/test/runtime/samples/each-block-destructured-object-reserved-key/_config.js
new file mode 100644
index 000000000000..c04e98469156
--- /dev/null
+++ b/test/runtime/samples/each-block-destructured-object-reserved-key/_config.js
@@ -0,0 +1,5 @@
+export default {
+ html: `
+ bar
+ `
+};
diff --git a/test/runtime/samples/each-block-destructured-object-reserved-key/main.svelte b/test/runtime/samples/each-block-destructured-object-reserved-key/main.svelte
new file mode 100644
index 000000000000..c3e11c3ea1ad
--- /dev/null
+++ b/test/runtime/samples/each-block-destructured-object-reserved-key/main.svelte
@@ -0,0 +1,7 @@
+
+
+{#each foo as { in: bar }}
+ {bar}
+{/each}
diff --git a/test/runtime/samples/each-block-keyed-dynamic-2/_config.js b/test/runtime/samples/each-block-keyed-dynamic-2/_config.js
new file mode 100644
index 000000000000..7eba75a5ff09
--- /dev/null
+++ b/test/runtime/samples/each-block-keyed-dynamic-2/_config.js
@@ -0,0 +1,23 @@
+export default {
+ html: `
+ Click Me
+ 0
+
+ `,
+
+ async test({ assert, component, target, window }) {
+ const button = target.querySelector("button");
+
+ const event = new window.MouseEvent("click");
+ await button.dispatchEvent(event);
+
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ Click Me
+ 1
+
+ `
+ );
+ }
+};
diff --git a/test/runtime/samples/each-block-keyed-dynamic-2/main.svelte b/test/runtime/samples/each-block-keyed-dynamic-2/main.svelte
new file mode 100644
index 000000000000..ab455a585e84
--- /dev/null
+++ b/test/runtime/samples/each-block-keyed-dynamic-2/main.svelte
@@ -0,0 +1,20 @@
+
+
+ Click Me
+
+
+{num}
+
+ {#each cards as c, i (i)}
+ {c}
+ {/each}
+
diff --git a/test/runtime/samples/each-block-string/_config.js b/test/runtime/samples/each-block-string/_config.js
new file mode 100644
index 000000000000..7366c964ebb1
--- /dev/null
+++ b/test/runtime/samples/each-block-string/_config.js
@@ -0,0 +1,10 @@
+export default {
+ compileOptions: {
+ dev: true
+ },
+ html: `
+ f
+ o
+ o
+ `
+};
diff --git a/test/runtime/samples/each-block-string/main.svelte b/test/runtime/samples/each-block-string/main.svelte
new file mode 100644
index 000000000000..ae60f0f6b32f
--- /dev/null
+++ b/test/runtime/samples/each-block-string/main.svelte
@@ -0,0 +1,3 @@
+{#each 'foo' as c}
+ {c}
+{/each}
diff --git a/test/runtime/samples/event-handler-dynamic-2/_config.js b/test/runtime/samples/event-handler-dynamic-2/_config.js
new file mode 100644
index 000000000000..c996d8f2aaec
--- /dev/null
+++ b/test/runtime/samples/event-handler-dynamic-2/_config.js
@@ -0,0 +1,33 @@
+export default {
+ html: `
+ toggle
+ 0
+ handler_a
+ handler_b
+ `,
+
+ async test({ assert, target, window }) {
+ const [toggle, handler_a, handler_b] = target.querySelectorAll('button');
+ const p = target.querySelector('p');
+
+ const event = new window.MouseEvent('click');
+
+ await handler_a.dispatchEvent(event);
+ assert.equal(p.innerHTML, '1');
+
+ await toggle.dispatchEvent(event);
+
+ await handler_a.dispatchEvent(event);
+ assert.equal(p.innerHTML, '2');
+
+ await toggle.dispatchEvent(event);
+
+ await handler_b.dispatchEvent(event);
+ assert.equal(p.innerHTML, '1');
+
+ await toggle.dispatchEvent(event);
+
+ await handler_b.dispatchEvent(event);
+ assert.equal(p.innerHTML, '2');
+ },
+};
diff --git a/test/runtime/samples/event-handler-dynamic-2/main.svelte b/test/runtime/samples/event-handler-dynamic-2/main.svelte
new file mode 100644
index 000000000000..1b2041d3b80f
--- /dev/null
+++ b/test/runtime/samples/event-handler-dynamic-2/main.svelte
@@ -0,0 +1,20 @@
+
+
+ flag = !flag}>toggle
+
+{number}
+
+handler_a
+handler_b
diff --git a/test/runtime/samples/event-handler-dynamic-bound-var/Nested.svelte b/test/runtime/samples/event-handler-dynamic-bound-var/Nested.svelte
new file mode 100644
index 000000000000..948fc308c0a3
--- /dev/null
+++ b/test/runtime/samples/event-handler-dynamic-bound-var/Nested.svelte
@@ -0,0 +1,7 @@
+
+{text}
\ No newline at end of file
diff --git a/test/runtime/samples/event-handler-dynamic-bound-var/_config.js b/test/runtime/samples/event-handler-dynamic-bound-var/_config.js
new file mode 100644
index 000000000000..c832127c092d
--- /dev/null
+++ b/test/runtime/samples/event-handler-dynamic-bound-var/_config.js
@@ -0,0 +1,20 @@
+export default {
+ html: `
+ Click Me
+ Hello World
+ `,
+ async test({ assert, component, target, window }) {
+ const button = target.querySelector('button');
+
+ const event = new window.MouseEvent('click');
+
+ await button.dispatchEvent(event);
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ Click Me
+ Bye World
+ `
+ );
+ },
+};
diff --git a/test/runtime/samples/event-handler-dynamic-bound-var/main.svelte b/test/runtime/samples/event-handler-dynamic-bound-var/main.svelte
new file mode 100644
index 000000000000..bb7d9befc409
--- /dev/null
+++ b/test/runtime/samples/event-handler-dynamic-bound-var/main.svelte
@@ -0,0 +1,8 @@
+
+
+Click Me
+
+
diff --git a/test/runtime/samples/event-handler-dynamic-hash/_config.js b/test/runtime/samples/event-handler-dynamic-hash/_config.js
new file mode 100644
index 000000000000..e60e5615245f
--- /dev/null
+++ b/test/runtime/samples/event-handler-dynamic-hash/_config.js
@@ -0,0 +1,56 @@
+export default {
+ html: `
+
+ set handler 1
+ set handler 2
+
+ 0
+ click
+ `,
+
+ async test({ assert, component, target, window }) {
+ const [updateButton1, updateButton2, button] = target.querySelectorAll(
+ 'button'
+ );
+
+ const event = new window.MouseEvent('click');
+ let err = "";
+ window.addEventListener('error', (e) => {
+ e.preventDefault();
+ err = e.message;
+ });
+
+ await button.dispatchEvent(event);
+ assert.equal(err, "", err);
+ assert.htmlEqual(target.innerHTML, `
+
+ set handler 1
+ set handler 2
+
+ 0
+ click
+ `);
+
+ await updateButton1.dispatchEvent(event);
+ await button.dispatchEvent(event);
+ assert.htmlEqual(target.innerHTML, `
+
+ set handler 1
+ set handler 2
+
+ 1
+ click
+ `);
+
+ await updateButton2.dispatchEvent(event);
+ await button.dispatchEvent(event);
+ assert.htmlEqual(target.innerHTML, `
+
+ set handler 1
+ set handler 2
+
+ 2
+ click
+ `);
+ },
+};
diff --git a/test/runtime/samples/event-handler-dynamic-hash/main.svelte b/test/runtime/samples/event-handler-dynamic-hash/main.svelte
new file mode 100644
index 000000000000..c81af02006c7
--- /dev/null
+++ b/test/runtime/samples/event-handler-dynamic-hash/main.svelte
@@ -0,0 +1,23 @@
+
+
+
+set handler 1
+set handler 2
+
+
+{ number }
+
+click
\ No newline at end of file
diff --git a/test/runtime/samples/event-handler-dynamic-invalid/_config.js b/test/runtime/samples/event-handler-dynamic-invalid/_config.js
new file mode 100644
index 000000000000..ba1777f94503
--- /dev/null
+++ b/test/runtime/samples/event-handler-dynamic-invalid/_config.js
@@ -0,0 +1,28 @@
+export default {
+ html: `undef
+ null
+ invalid `,
+
+ async test({ assert, component, target, window }) {
+ const [buttonUndef, buttonNull, buttonInvalid] = target.querySelectorAll(
+ 'button'
+ );
+
+ const event = new window.MouseEvent('click');
+ let err = "";
+ window.addEventListener('error', (e) => {
+ e.preventDefault();
+ err = e.message;
+ });
+
+ // All three should not throw if proper checking is done in runtime code
+ await buttonUndef.dispatchEvent(event);
+ assert.equal(err, "", err);
+
+ await buttonNull.dispatchEvent(event);
+ assert.equal(err, "", err);
+
+ await buttonInvalid.dispatchEvent(event);
+ assert.equal(err, "", err);
+ },
+};
diff --git a/test/runtime/samples/event-handler-dynamic-invalid/main.svelte b/test/runtime/samples/event-handler-dynamic-invalid/main.svelte
new file mode 100644
index 000000000000..f4e8c5fdb7f0
--- /dev/null
+++ b/test/runtime/samples/event-handler-dynamic-invalid/main.svelte
@@ -0,0 +1,13 @@
+
+
+undef
+null
+invalid
diff --git a/test/runtime/samples/event-handler-dynamic-modifier-once/_config.js b/test/runtime/samples/event-handler-dynamic-modifier-once/_config.js
new file mode 100644
index 000000000000..41daf374c82d
--- /dev/null
+++ b/test/runtime/samples/event-handler-dynamic-modifier-once/_config.js
@@ -0,0 +1,16 @@
+export default {
+ html: `
+ 0
+ `,
+
+ async test({ assert, component, target, window }) {
+ const button = target.querySelector('button');
+ const event = new window.MouseEvent('click');
+
+ await button.dispatchEvent(event);
+ assert.equal(component.count, 1);
+
+ await button.dispatchEvent(event);
+ assert.equal(component.count, 1);
+ }
+};
diff --git a/test/runtime/samples/event-handler-dynamic-modifier-once/main.svelte b/test/runtime/samples/event-handler-dynamic-modifier-once/main.svelte
new file mode 100644
index 000000000000..d363d708ba8f
--- /dev/null
+++ b/test/runtime/samples/event-handler-dynamic-modifier-once/main.svelte
@@ -0,0 +1,7 @@
+
+
+{count}
\ No newline at end of file
diff --git a/test/runtime/samples/event-handler-dynamic-modifier-prevent-default/_config.js b/test/runtime/samples/event-handler-dynamic-modifier-prevent-default/_config.js
new file mode 100644
index 000000000000..4fa032bf37ab
--- /dev/null
+++ b/test/runtime/samples/event-handler-dynamic-modifier-prevent-default/_config.js
@@ -0,0 +1,16 @@
+export default {
+ html: `
+ click me
+ `,
+
+ async test({ assert, component, target, window }) {
+ const button = target.querySelector('button');
+ const event = new window.MouseEvent('click', {
+ cancelable: true
+ });
+
+ await button.dispatchEvent(event);
+
+ assert.ok(component.default_was_prevented);
+ }
+};
diff --git a/test/runtime/samples/event-handler-dynamic-modifier-prevent-default/main.svelte b/test/runtime/samples/event-handler-dynamic-modifier-prevent-default/main.svelte
new file mode 100644
index 000000000000..49d42f330523
--- /dev/null
+++ b/test/runtime/samples/event-handler-dynamic-modifier-prevent-default/main.svelte
@@ -0,0 +1,11 @@
+
+
+click me
\ No newline at end of file
diff --git a/test/runtime/samples/event-handler-dynamic-modifier-self/_config.js b/test/runtime/samples/event-handler-dynamic-modifier-self/_config.js
new file mode 100644
index 000000000000..6d7d29e48288
--- /dev/null
+++ b/test/runtime/samples/event-handler-dynamic-modifier-self/_config.js
@@ -0,0 +1,16 @@
+export default {
+ html: `
+
+ click me
+
+ `,
+
+ async test({ assert, component, target, window }) {
+ const button = target.querySelector('button');
+ const event = new window.MouseEvent('click');
+
+ await button.dispatchEvent(event);
+
+ assert.ok(!component.inner_clicked);
+ },
+};
diff --git a/test/runtime/samples/event-handler-dynamic-modifier-self/main.svelte b/test/runtime/samples/event-handler-dynamic-modifier-self/main.svelte
new file mode 100644
index 000000000000..b57d88ec020f
--- /dev/null
+++ b/test/runtime/samples/event-handler-dynamic-modifier-self/main.svelte
@@ -0,0 +1,13 @@
+
+
+
+ click me
+
diff --git a/test/runtime/samples/event-handler-dynamic-modifier-stop-propagation/_config.js b/test/runtime/samples/event-handler-dynamic-modifier-stop-propagation/_config.js
new file mode 100644
index 000000000000..8517429e5ceb
--- /dev/null
+++ b/test/runtime/samples/event-handler-dynamic-modifier-stop-propagation/_config.js
@@ -0,0 +1,19 @@
+export default {
+ html: `
+
+ click me
+
+ `,
+
+ async test({ assert, component, target, window }) {
+ const button = target.querySelector('button');
+ const event = new window.MouseEvent('click', {
+ bubbles: true
+ });
+
+ await button.dispatchEvent(event);
+
+ assert.ok(component.inner_clicked);
+ assert.ok(!component.outer_clicked);
+ }
+};
diff --git a/test/runtime/samples/event-handler-dynamic-modifier-stop-propagation/main.svelte b/test/runtime/samples/event-handler-dynamic-modifier-stop-propagation/main.svelte
new file mode 100644
index 000000000000..bad73599276d
--- /dev/null
+++ b/test/runtime/samples/event-handler-dynamic-modifier-stop-propagation/main.svelte
@@ -0,0 +1,20 @@
+
+
+
+ click me
+
\ No newline at end of file
diff --git a/test/runtime/samples/event-handler-dynamic-multiple/_config.js b/test/runtime/samples/event-handler-dynamic-multiple/_config.js
new file mode 100644
index 000000000000..cf17c61f6055
--- /dev/null
+++ b/test/runtime/samples/event-handler-dynamic-multiple/_config.js
@@ -0,0 +1,14 @@
+export default {
+ html: `
+ click me
+ `,
+
+ async test({ assert, component, target, window }) {
+ const button = target.querySelector('button');
+ const event = new window.MouseEvent('click');
+
+ await button.dispatchEvent(event);
+ assert.equal(component.clickHandlerOne, 1);
+ assert.equal(component.clickHandlerTwo, 1);
+ }
+};
diff --git a/test/runtime/samples/event-handler-dynamic-multiple/main.svelte b/test/runtime/samples/event-handler-dynamic-multiple/main.svelte
new file mode 100644
index 000000000000..2dbbe61ea652
--- /dev/null
+++ b/test/runtime/samples/event-handler-dynamic-multiple/main.svelte
@@ -0,0 +1,11 @@
+
+
+click me
diff --git a/test/runtime/samples/event-handler-dynamic/_config.js b/test/runtime/samples/event-handler-dynamic/_config.js
index 41cfd6e72943..e60e5615245f 100644
--- a/test/runtime/samples/event-handler-dynamic/_config.js
+++ b/test/runtime/samples/event-handler-dynamic/_config.js
@@ -14,8 +14,14 @@ export default {
);
const event = new window.MouseEvent('click');
+ let err = "";
+ window.addEventListener('error', (e) => {
+ e.preventDefault();
+ err = e.message;
+ });
await button.dispatchEvent(event);
+ assert.equal(err, "", err);
assert.htmlEqual(target.innerHTML, `
set handler 1
@@ -24,7 +30,7 @@ export default {
0
click
`);
-
+
await updateButton1.dispatchEvent(event);
await button.dispatchEvent(event);
assert.htmlEqual(target.innerHTML, `
@@ -35,7 +41,7 @@ export default {
1
click
`);
-
+
await updateButton2.dispatchEvent(event);
await button.dispatchEvent(event);
assert.htmlEqual(target.innerHTML, `
diff --git a/test/runtime/samples/event-handler-modifier-body-once/_config.js b/test/runtime/samples/event-handler-modifier-body-once/_config.js
new file mode 100644
index 000000000000..412703401098
--- /dev/null
+++ b/test/runtime/samples/event-handler-modifier-body-once/_config.js
@@ -0,0 +1,11 @@
+export default {
+ async test({ assert, component, window }) {
+ const event = new window.MouseEvent('click');
+
+ await window.document.body.dispatchEvent(event);
+ assert.equal(component.count, 1);
+
+ await window.document.body.dispatchEvent(event);
+ assert.equal(component.count, 1);
+ }
+};
diff --git a/test/runtime/samples/event-handler-modifier-body-once/main.svelte b/test/runtime/samples/event-handler-modifier-body-once/main.svelte
new file mode 100644
index 000000000000..423a75d1f056
--- /dev/null
+++ b/test/runtime/samples/event-handler-modifier-body-once/main.svelte
@@ -0,0 +1,5 @@
+
+
+ count += 1}"/>
\ No newline at end of file
diff --git a/test/runtime/samples/instrumentation-update-expression/_config.js b/test/runtime/samples/instrumentation-update-expression/_config.js
new file mode 100644
index 000000000000..cc33422f6fb4
--- /dev/null
+++ b/test/runtime/samples/instrumentation-update-expression/_config.js
@@ -0,0 +1,31 @@
+export default {
+ html: `
+ 0
+ foo++
+ ++foo
+ 0
+ bar.bar++
+ ++bar.bar
+ `,
+ async test({ assert, target, window }) {
+ const [foo, bar] = target.querySelectorAll('p');
+ const [button1, button2, button3, button4] = target.querySelectorAll('button');
+ const event = new window.MouseEvent('click');
+
+ await button1.dispatchEvent(event);
+ assert.equal(foo.innerHTML, '1');
+ assert.equal(bar.innerHTML, '0');
+
+ await button2.dispatchEvent(event);
+ assert.equal(foo.innerHTML, '2');
+ assert.equal(bar.innerHTML, '0');
+
+ await button3.dispatchEvent(event);
+ assert.equal(foo.innerHTML, '2');
+ assert.equal(bar.innerHTML, '1');
+
+ await button4.dispatchEvent(event);
+ assert.equal(foo.innerHTML, '2');
+ assert.equal(bar.innerHTML, '2');
+ }
+};
diff --git a/test/runtime/samples/instrumentation-update-expression/main.svelte b/test/runtime/samples/instrumentation-update-expression/main.svelte
new file mode 100644
index 000000000000..0672f6330d83
--- /dev/null
+++ b/test/runtime/samples/instrumentation-update-expression/main.svelte
@@ -0,0 +1,14 @@
+
+
+{foo}
+
+ foo++}>foo++
+ ++foo}>++foo
+
+{bar.bar}
+
+ bar.bar++}>bar.bar++
+ ++bar.bar}>++bar.bar
diff --git a/test/runtime/samples/keyed-each-dev-unique/_config.js b/test/runtime/samples/keyed-each-dev-unique/_config.js
new file mode 100644
index 000000000000..8f46af9d5214
--- /dev/null
+++ b/test/runtime/samples/keyed-each-dev-unique/_config.js
@@ -0,0 +1,7 @@
+export default {
+ compileOptions: {
+ dev: true
+ },
+
+ error: `Cannot have duplicate keys in a keyed each`
+};
diff --git a/test/runtime/samples/keyed-each-dev-unique/main.svelte b/test/runtime/samples/keyed-each-dev-unique/main.svelte
new file mode 100644
index 000000000000..870e7beaa1c9
--- /dev/null
+++ b/test/runtime/samples/keyed-each-dev-unique/main.svelte
@@ -0,0 +1,7 @@
+
+
+{#each array as item (item)}
+ {item}
+{/each}
diff --git a/test/runtime/samples/lifecycle-onmount-infinite-loop/Child.svelte b/test/runtime/samples/lifecycle-onmount-infinite-loop/Child.svelte
new file mode 100644
index 000000000000..ef16875b6448
--- /dev/null
+++ b/test/runtime/samples/lifecycle-onmount-infinite-loop/Child.svelte
@@ -0,0 +1 @@
+Child
diff --git a/test/runtime/samples/lifecycle-onmount-infinite-loop/_config.js b/test/runtime/samples/lifecycle-onmount-infinite-loop/_config.js
new file mode 100644
index 000000000000..a76a2686ac27
--- /dev/null
+++ b/test/runtime/samples/lifecycle-onmount-infinite-loop/_config.js
@@ -0,0 +1,6 @@
+export default {
+ test({ assert, component }) {
+ const { count } = component;
+ assert.deepEqual(count, 1);
+ }
+};
diff --git a/test/runtime/samples/lifecycle-onmount-infinite-loop/main.svelte b/test/runtime/samples/lifecycle-onmount-infinite-loop/main.svelte
new file mode 100644
index 000000000000..1fa4263e39ea
--- /dev/null
+++ b/test/runtime/samples/lifecycle-onmount-infinite-loop/main.svelte
@@ -0,0 +1,16 @@
+
+
+
diff --git a/test/runtime/samples/module-context-bind/_config.js b/test/runtime/samples/module-context-bind/_config.js
new file mode 100644
index 000000000000..32bc9c4ce95d
--- /dev/null
+++ b/test/runtime/samples/module-context-bind/_config.js
@@ -0,0 +1,4 @@
+export default {
+ skip_if_ssr: true,
+ html: 'object
'
+};
diff --git a/test/runtime/samples/module-context-bind/main.svelte b/test/runtime/samples/module-context-bind/main.svelte
new file mode 100644
index 000000000000..1580102bd8fe
--- /dev/null
+++ b/test/runtime/samples/module-context-bind/main.svelte
@@ -0,0 +1,11 @@
+
+
+
+
+{typeof bar}
diff --git a/test/runtime/samples/reactive-values-no-implicit-member-expression/_config.js b/test/runtime/samples/reactive-values-no-implicit-member-expression/_config.js
new file mode 100644
index 000000000000..05a81595898f
--- /dev/null
+++ b/test/runtime/samples/reactive-values-no-implicit-member-expression/_config.js
@@ -0,0 +1,5 @@
+export default {
+ test({ assert, window }) {
+ assert.equal(window.document.title, 'foo');
+ }
+};
diff --git a/test/runtime/samples/reactive-values-no-implicit-member-expression/main.svelte b/test/runtime/samples/reactive-values-no-implicit-member-expression/main.svelte
new file mode 100644
index 000000000000..a631d4d9f88c
--- /dev/null
+++ b/test/runtime/samples/reactive-values-no-implicit-member-expression/main.svelte
@@ -0,0 +1,3 @@
+
diff --git a/test/runtime/samples/reactive-values-store-destructured-undefined/_config.js b/test/runtime/samples/reactive-values-store-destructured-undefined/_config.js
new file mode 100644
index 000000000000..5e3f15f5dcd6
--- /dev/null
+++ b/test/runtime/samples/reactive-values-store-destructured-undefined/_config.js
@@ -0,0 +1,6 @@
+export default {
+ html: `
+ undefined
+ undefined
+ `
+};
diff --git a/test/runtime/samples/reactive-values-store-destructured-undefined/main.svelte b/test/runtime/samples/reactive-values-store-destructured-undefined/main.svelte
new file mode 100644
index 000000000000..152e0e3e2e2a
--- /dev/null
+++ b/test/runtime/samples/reactive-values-store-destructured-undefined/main.svelte
@@ -0,0 +1,9 @@
+
+
+{foo1}
+{foo2}
diff --git a/test/runtime/samples/spread-component-2/Widget.svelte b/test/runtime/samples/spread-component-2/Widget.svelte
new file mode 100644
index 000000000000..ae27aeb5e531
--- /dev/null
+++ b/test/runtime/samples/spread-component-2/Widget.svelte
@@ -0,0 +1,13 @@
+
+
+foo: {foo}
+baz: {baz} ({typeof baz})
+qux: {qux}
+quux: {quux}
+selected: {selected}
diff --git a/test/runtime/samples/spread-component-2/_config.js b/test/runtime/samples/spread-component-2/_config.js
new file mode 100644
index 000000000000..6d36e8e60dfb
--- /dev/null
+++ b/test/runtime/samples/spread-component-2/_config.js
@@ -0,0 +1,76 @@
+export default {
+ props: {
+ list: [{
+ foo: 'lol',
+ baz: 40 + 2,
+ qux: 5,
+ quux: 'core'
+ }, {
+ foo: 'lolzz',
+ baz: 50 + 2,
+ qux: 1,
+ quux: 'quuxx'
+ }],
+ },
+
+ html: `
+
+
foo: lol
+
baz: 42 (number)
+
qux: 0
+
quux: core
+
selected: true
+
foo: lolzz
+
baz: 52 (number)
+
qux: 0
+
quux: quuxx
+
selected: false
+
+ `,
+
+ test({ assert, component, target }) {
+ component.list = [{
+ foo: 'lol',
+ baz: 40 + 3,
+ qux: 8,
+ quux: 'heart'
+ }, {
+ foo: 'lolzz',
+ baz: 50 + 3,
+ qux: 8,
+ quux: 'heartxx'
+ }];
+
+ assert.htmlEqual(target.innerHTML, `
+
+
foo: lol
+
baz: 43 (number)
+
qux: 0
+
quux: heart
+
selected: true
+
foo: lolzz
+
baz: 53 (number)
+
qux: 0
+
quux: heartxx
+
selected: false
+
+ `);
+
+ component.qux = 1;
+
+ assert.htmlEqual(target.innerHTML, `
+
+
foo: lol
+
baz: 43 (number)
+
qux: 1
+
quux: heart
+
selected: false
+
foo: lolzz
+
baz: 53 (number)
+
qux: 1
+
quux: heartxx
+
selected: true
+
+ `);
+ }
+};
diff --git a/test/runtime/samples/spread-component-2/main.svelte b/test/runtime/samples/spread-component-2/main.svelte
new file mode 100644
index 000000000000..436e11f9c50d
--- /dev/null
+++ b/test/runtime/samples/spread-component-2/main.svelte
@@ -0,0 +1,12 @@
+
+
+
+ {#each list as item, index (item.foo)}
+
+ {/each}
+
diff --git a/test/runtime/samples/store-auto-subscribe-nullish/_config.js b/test/runtime/samples/store-auto-subscribe-nullish/_config.js
new file mode 100644
index 000000000000..52e21cef05ed
--- /dev/null
+++ b/test/runtime/samples/store-auto-subscribe-nullish/_config.js
@@ -0,0 +1,13 @@
+import { writable } from '../../../../store';
+
+export default {
+ html: `
+ undefined
+ `,
+ async test({ assert, component, target }) {
+ component.store = writable('foo');
+ assert.htmlEqual(target.innerHTML, `
+ foo
+ `);
+ }
+};
diff --git a/test/runtime/samples/store-auto-subscribe-nullish/main.svelte b/test/runtime/samples/store-auto-subscribe-nullish/main.svelte
new file mode 100644
index 000000000000..9c1ed4a56094
--- /dev/null
+++ b/test/runtime/samples/store-auto-subscribe-nullish/main.svelte
@@ -0,0 +1,5 @@
+
+
+{$store}
diff --git a/test/runtime/samples/svg-tspan-preserve-space/_config.js b/test/runtime/samples/svg-tspan-preserve-space/_config.js
new file mode 100644
index 000000000000..283af0a2b0c2
--- /dev/null
+++ b/test/runtime/samples/svg-tspan-preserve-space/_config.js
@@ -0,0 +1,3 @@
+export default {
+ html: `foo barfoo bar `,
+};
diff --git a/test/runtime/samples/svg-tspan-preserve-space/main.svelte b/test/runtime/samples/svg-tspan-preserve-space/main.svelte
new file mode 100644
index 000000000000..df43d575a906
--- /dev/null
+++ b/test/runtime/samples/svg-tspan-preserve-space/main.svelte
@@ -0,0 +1 @@
+foo {"bar"}foo bar
\ No newline at end of file
diff --git a/test/server-side-rendering/index.js b/test/server-side-rendering/index.js
index 768917e83364..ee1319845dfe 100644
--- a/test/server-side-rendering/index.js
+++ b/test/server-side-rendering/index.js
@@ -1,13 +1,17 @@
import * as assert from "assert";
import * as fs from "fs";
import * as path from "path";
+import * as glob from 'tiny-glob/sync.js';
import {
showOutput,
loadConfig,
+ loadSvelte,
setupHtmlEqual,
tryToLoadJson,
- shouldUpdateExpected
+ cleanRequireCache,
+ shouldUpdateExpected,
+ mkdirp
} from "../helpers.js";
function tryToReadFile(file) {
@@ -20,13 +24,11 @@ function tryToReadFile(file) {
}
const sveltePath = process.cwd().split('\\').join('/');
+let compile = null;
describe("ssr", () => {
before(() => {
- require("../../register")({
- extensions: ['.svelte', '.html'],
- sveltePath
- });
+ compile = loadSvelte(true).compile;
return setupHtmlEqual();
});
@@ -34,9 +36,11 @@ describe("ssr", () => {
fs.readdirSync(`${__dirname}/samples`).forEach(dir => {
if (dir[0] === ".") return;
+ const config = loadConfig(`${__dirname}/samples/${dir}/_config.js`);
+
// add .solo to a sample directory name to only run that test, or
// .show to always show the output. or both
- const solo = /\.solo/.test(dir);
+ const solo = config.solo || /\.solo/.test(dir);
const show = /\.show/.test(dir);
if (solo && process.env.CI) {
@@ -45,6 +49,18 @@ describe("ssr", () => {
(solo ? it.only : it)(dir, () => {
dir = path.resolve(`${__dirname}/samples`, dir);
+
+ cleanRequireCache();
+
+ const compileOptions = {
+ sveltePath,
+ ...config.compileOptions,
+ generate: 'ssr',
+ format: 'cjs'
+ };
+
+ require("../../register")(compileOptions);
+
try {
const Component = require(`${dir}/main.svelte`).default;
@@ -127,21 +143,46 @@ describe("ssr", () => {
(config.skip ? it.skip : solo ? it.only : it)(dir, () => {
const cwd = path.resolve("test/runtime/samples", dir);
- Object.keys(require.cache)
- .filter(x => x.endsWith('.svelte'))
- .forEach(file => {
- delete require.cache[file];
- });
+ cleanRequireCache();
delete global.window;
- const compileOptions = Object.assign({ sveltePath }, config.compileOptions, {
+ const compileOptions = {
+ sveltePath,
+ ...config.compileOptions,
generate: 'ssr',
format: 'cjs'
- });
+ };
require("../../register")(compileOptions);
+ glob('**/*.svelte', { cwd }).forEach(file => {
+ if (file[0] === '_') return;
+
+ const dir = `${cwd}/_output/ssr`;
+ const out = `${dir}/${file.replace(/\.svelte$/, '.js')}`;
+
+ if (fs.existsSync(out)) {
+ fs.unlinkSync(out);
+ }
+
+ mkdirp(dir);
+
+ try {
+ const { js } = compile(
+ fs.readFileSync(`${cwd}/${file}`, 'utf-8'),
+ {
+ ...compileOptions,
+ filename: file
+ }
+ );
+
+ fs.writeFileSync(out, js.code);
+ } catch (err) {
+ // do nothing
+ }
+ });
+
try {
if (config.before_test) config.before_test();
diff --git a/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_config.js b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_config.js
new file mode 100644
index 000000000000..ae9b250f8657
--- /dev/null
+++ b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_config.js
@@ -0,0 +1,5 @@
+export default {
+ compileOptions: {
+ hydratable: true
+ }
+};
diff --git a/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected-head.html b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected-head.html
new file mode 100644
index 000000000000..107753cdd0e5
--- /dev/null
+++ b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected-head.html
@@ -0,0 +1,4 @@
+Some Title
+
+
+
\ No newline at end of file
diff --git a/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected.html b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected.html
new file mode 100644
index 000000000000..a469e618fa94
--- /dev/null
+++ b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected.html
@@ -0,0 +1,3 @@
+
+
+Just a dummy page.
\ No newline at end of file
diff --git a/test/server-side-rendering/samples/head-meta-hydrate-duplicate/main.svelte b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/main.svelte
new file mode 100644
index 000000000000..1a8b125dd2cf
--- /dev/null
+++ b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/main.svelte
@@ -0,0 +1,8 @@
+
+ Some Title
+
+
+
+
+
+Just a dummy page.
\ No newline at end of file
diff --git a/test/server-side-rendering/samples/head-multiple-title/A.svelte b/test/server-side-rendering/samples/head-multiple-title/A.svelte
new file mode 100644
index 000000000000..b139b4ff7751
--- /dev/null
+++ b/test/server-side-rendering/samples/head-multiple-title/A.svelte
@@ -0,0 +1,3 @@
+
+ A
+
diff --git a/test/server-side-rendering/samples/head-multiple-title/B.svelte b/test/server-side-rendering/samples/head-multiple-title/B.svelte
new file mode 100644
index 000000000000..4a29ecb04cbc
--- /dev/null
+++ b/test/server-side-rendering/samples/head-multiple-title/B.svelte
@@ -0,0 +1,3 @@
+
+ B
+
diff --git a/test/server-side-rendering/samples/head-multiple-title/_expected-head.html b/test/server-side-rendering/samples/head-multiple-title/_expected-head.html
new file mode 100644
index 000000000000..af5c5feba460
--- /dev/null
+++ b/test/server-side-rendering/samples/head-multiple-title/_expected-head.html
@@ -0,0 +1 @@
+B
\ No newline at end of file
diff --git a/test/server-side-rendering/samples/head-multiple-title/_expected.html b/test/server-side-rendering/samples/head-multiple-title/_expected.html
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/test/server-side-rendering/samples/head-multiple-title/data.json b/test/server-side-rendering/samples/head-multiple-title/data.json
new file mode 100644
index 000000000000..eab238e81696
--- /dev/null
+++ b/test/server-side-rendering/samples/head-multiple-title/data.json
@@ -0,0 +1,3 @@
+{
+ "adjective": "custom"
+}
\ No newline at end of file
diff --git a/test/server-side-rendering/samples/head-multiple-title/main.svelte b/test/server-side-rendering/samples/head-multiple-title/main.svelte
new file mode 100644
index 000000000000..fb9a70b923dc
--- /dev/null
+++ b/test/server-side-rendering/samples/head-multiple-title/main.svelte
@@ -0,0 +1,10 @@
+
+
+
+ Main
+
+
+
diff --git a/test/server-side-rendering/samples/spread-attributes-white-space/_expected.html b/test/server-side-rendering/samples/spread-attributes-white-space/_expected.html
new file mode 100644
index 000000000000..a73bb17e8cb3
--- /dev/null
+++ b/test/server-side-rendering/samples/spread-attributes-white-space/_expected.html
@@ -0,0 +1,8 @@
+
+
+
\ No newline at end of file
diff --git a/test/server-side-rendering/samples/spread-attributes-white-space/main.svelte b/test/server-side-rendering/samples/spread-attributes-white-space/main.svelte
new file mode 100644
index 000000000000..6919d9ea54cc
--- /dev/null
+++ b/test/server-side-rendering/samples/spread-attributes-white-space/main.svelte
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/test/store/index.js b/test/store/index.js
index a39fab86e6e7..2af4a6f35d85 100644
--- a/test/store/index.js
+++ b/test/store/index.js
@@ -116,6 +116,15 @@ describe('store', () => {
});
});
+ const fake_observable = {
+ subscribe(fn) {
+ fn(42);
+ return {
+ unsubscribe: () => {}
+ };
+ }
+ };
+
describe('derived', () => {
it('maps a single store', () => {
const a = writable(1);
@@ -346,6 +355,11 @@ describe('store', () => {
b.set(2);
assert.deepEqual(get(c), 'two 2');
});
+
+ it('works with RxJS-style observables', () => {
+ const d = derived(fake_observable, _ => _);
+ assert.equal(get(d), 42);
+ });
});
describe('get', () => {
@@ -355,16 +369,7 @@ describe('store', () => {
});
it('works with RxJS-style observables', () => {
- const observable = {
- subscribe(fn) {
- fn(42);
- return {
- unsubscribe: () => {}
- };
- }
- };
-
- assert.equal(get(observable), 42);
+ assert.equal(get(fake_observable), 42);
});
});
});
diff --git a/test/validator/index.js b/test/validator/index.js
index 9f991df4f207..9bce5e149b4a 100644
--- a/test/validator/index.js
+++ b/test/validator/index.js
@@ -20,6 +20,7 @@ describe("validate", () => {
const input = fs.readFileSync(`${__dirname}/samples/${dir}/input.svelte`, "utf-8").replace(/\s+$/, "");
const expected_warnings = tryToLoadJson(`${__dirname}/samples/${dir}/warnings.json`) || [];
const expected_errors = tryToLoadJson(`${__dirname}/samples/${dir}/errors.json`);
+ const options = tryToLoadJson(`${__dirname}/samples/${dir}/options.json`);
let error;
@@ -27,7 +28,9 @@ describe("validate", () => {
const { warnings } = svelte.compile(input, {
dev: config.dev,
legacy: config.legacy,
- generate: false
+ generate: false,
+ customElement: config.customElement,
+ ...options,
});
assert.deepEqual(warnings.map(w => ({
diff --git a/test/validator/samples/binding-await-catch/errors.json b/test/validator/samples/binding-await-catch/errors.json
new file mode 100644
index 000000000000..00141686f385
--- /dev/null
+++ b/test/validator/samples/binding-await-catch/errors.json
@@ -0,0 +1,9 @@
+[
+ {
+ "code": "invalid-binding",
+ "message": "Cannot bind to a variable declared with {#await ... then} or {:catch} blocks",
+ "pos": 79,
+ "start": { "line": 6, "column": 9, "character": 79 },
+ "end": { "line": 6, "column": 27, "character": 97 }
+ }
+]
diff --git a/test/validator/samples/binding-await-catch/input.svelte b/test/validator/samples/binding-await-catch/input.svelte
new file mode 100644
index 000000000000..b640f6305bdd
--- /dev/null
+++ b/test/validator/samples/binding-await-catch/input.svelte
@@ -0,0 +1,7 @@
+
+{#await promise}
+{:catch error}
+
+{/await}
diff --git a/test/validator/samples/binding-await-then-2/errors.json b/test/validator/samples/binding-await-then-2/errors.json
new file mode 100644
index 000000000000..e734ed4717f7
--- /dev/null
+++ b/test/validator/samples/binding-await-then-2/errors.json
@@ -0,0 +1,9 @@
+[
+ {
+ "code": "invalid-binding",
+ "message": "Cannot bind to a variable declared with {#await ... then} or {:catch} blocks",
+ "pos": 78,
+ "start": { "line": 6, "column": 9, "character": 78 },
+ "end": { "line": 6, "column": 19, "character": 88 }
+ }
+]
diff --git a/test/validator/samples/binding-await-then-2/input.svelte b/test/validator/samples/binding-await-then-2/input.svelte
new file mode 100644
index 000000000000..e8c56c8e0b2c
--- /dev/null
+++ b/test/validator/samples/binding-await-then-2/input.svelte
@@ -0,0 +1,7 @@
+
+{#await promise}
+{:then value}
+
+{/await}
diff --git a/test/validator/samples/binding-await-then/errors.json b/test/validator/samples/binding-await-then/errors.json
new file mode 100644
index 000000000000..a611e7731f19
--- /dev/null
+++ b/test/validator/samples/binding-await-then/errors.json
@@ -0,0 +1,9 @@
+[
+ {
+ "code": "invalid-binding",
+ "message": "Cannot bind to a variable declared with {#await ... then} or {:catch} blocks",
+ "pos": 75,
+ "start": { "line": 5, "column": 9, "character": 75 },
+ "end": { "line": 5, "column": 19, "character": 85 }
+ }
+]
diff --git a/test/validator/samples/binding-await-then/input.svelte b/test/validator/samples/binding-await-then/input.svelte
new file mode 100644
index 000000000000..bc55ef97e464
--- /dev/null
+++ b/test/validator/samples/binding-await-then/input.svelte
@@ -0,0 +1,6 @@
+
+{#await promise then value}
+
+{/await}
diff --git a/test/validator/samples/component-dynamic/input.svelte b/test/validator/samples/component-dynamic/input.svelte
new file mode 100644
index 000000000000..f591a84fe14c
--- /dev/null
+++ b/test/validator/samples/component-dynamic/input.svelte
@@ -0,0 +1,18 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/validator/samples/component-dynamic/options.json b/test/validator/samples/component-dynamic/options.json
new file mode 100644
index 000000000000..3a50892ebab1
--- /dev/null
+++ b/test/validator/samples/component-dynamic/options.json
@@ -0,0 +1,3 @@
+{
+ "generate": true
+}
\ No newline at end of file
diff --git a/test/validator/samples/component-dynamic/warnings.json b/test/validator/samples/component-dynamic/warnings.json
new file mode 100644
index 000000000000..457ef11a1ed7
--- /dev/null
+++ b/test/validator/samples/component-dynamic/warnings.json
@@ -0,0 +1,47 @@
+[
+ {
+ "code": "reactive-component",
+ "message": " will not be reactive if Let changes. Use if you want this reactivity.",
+ "pos": 190,
+ "end": {
+ "character": 197,
+ "column": 7,
+ "line": 15
+ },
+ "start": {
+ "character": 190,
+ "column": 0,
+ "line": 15
+ }
+ },
+ {
+ "message": " will not be reactive if ExportLet changes. Use if you want this reactivity.",
+ "code": "reactive-component",
+ "pos": 198,
+ "end": {
+ "character": 211,
+ "column": 13,
+ "line": 16
+ },
+ "start": {
+ "character": 198,
+ "column": 0,
+ "line": 16
+ }
+ },
+ {
+ "message": " will not be reactive if Reactive changes. Use if you want this reactivity.",
+ "code": "reactive-component",
+ "pos": 212,
+ "end": {
+ "character": 224,
+ "column": 12,
+ "line": 17
+ },
+ "start": {
+ "character": 212,
+ "column": 0,
+ "line": 17
+ }
+ }
+]
diff --git a/test/validator/samples/each-block-invalid-context-destructured-object/errors.json b/test/validator/samples/each-block-invalid-context-destructured-object/errors.json
new file mode 100644
index 000000000000..085021ff5ac0
--- /dev/null
+++ b/test/validator/samples/each-block-invalid-context-destructured-object/errors.json
@@ -0,0 +1,15 @@
+[{
+ "code": "unexpected-reserved-word",
+ "message": "'case' is a reserved word in JavaScript and cannot be used here",
+ "start": {
+ "line": 1,
+ "column": 18,
+ "character": 18
+ },
+ "end": {
+ "line": 1,
+ "column": 18,
+ "character": 18
+ },
+ "pos": 18
+}]
diff --git a/test/validator/samples/each-block-invalid-context-destructured-object/input.svelte b/test/validator/samples/each-block-invalid-context-destructured-object/input.svelte
new file mode 100644
index 000000000000..a891f131a098
--- /dev/null
+++ b/test/validator/samples/each-block-invalid-context-destructured-object/input.svelte
@@ -0,0 +1,3 @@
+{#each cases as { case }}
+ {case.title}
+{/each}
diff --git a/test/validator/samples/tag-custom-element-options-missing/input.svelte b/test/validator/samples/tag-custom-element-options-missing/input.svelte
new file mode 100644
index 000000000000..f5f5d7427059
--- /dev/null
+++ b/test/validator/samples/tag-custom-element-options-missing/input.svelte
@@ -0,0 +1 @@
+
diff --git a/test/validator/samples/tag-custom-element-options-missing/warnings.json b/test/validator/samples/tag-custom-element-options-missing/warnings.json
new file mode 100644
index 000000000000..185c6c317998
--- /dev/null
+++ b/test/validator/samples/tag-custom-element-options-missing/warnings.json
@@ -0,0 +1,15 @@
+[{
+ "code": "missing-custom-element-compile-options",
+ "message": "The 'tag' option is used when generating a custom element. Did you forget the 'customElement: true' compile option?",
+ "start": {
+ "line": 1,
+ "column": 16,
+ "character": 16
+ },
+ "end": {
+ "line": 1,
+ "column": 36,
+ "character": 36
+ },
+ "pos": 16
+}]
diff --git a/test/validator/samples/tag-custom-element-options-true/_config.js b/test/validator/samples/tag-custom-element-options-true/_config.js
new file mode 100644
index 000000000000..ec3c350d4687
--- /dev/null
+++ b/test/validator/samples/tag-custom-element-options-true/_config.js
@@ -0,0 +1,3 @@
+export default {
+ customElement: true
+};
diff --git a/test/validator/samples/tag-custom-element-options-true/input.svelte b/test/validator/samples/tag-custom-element-options-true/input.svelte
new file mode 100644
index 000000000000..f5f5d7427059
--- /dev/null
+++ b/test/validator/samples/tag-custom-element-options-true/input.svelte
@@ -0,0 +1 @@
+
diff --git a/test/validator/samples/unreferenced-variables/warnings.json b/test/validator/samples/unreferenced-variables/warnings.json
index 7d9e0111bf08..dfac58ebdb13 100644
--- a/test/validator/samples/unreferenced-variables/warnings.json
+++ b/test/validator/samples/unreferenced-variables/warnings.json
@@ -6,7 +6,7 @@
"column": 12,
"line": 8
},
- "message": "Component has unused export property 'd'. If it is for external reference only, please consider using `export const 'd'`",
+ "message": "Component has unused export property 'd'. If it is for external reference only, please consider using `export const d`",
"pos": 102,
"start": {
"character": 102,
@@ -21,7 +21,7 @@
"column": 15,
"line": 8
},
- "message": "Component has unused export property 'e'. If it is for external reference only, please consider using `export const 'e'`",
+ "message": "Component has unused export property 'e'. If it is for external reference only, please consider using `export const e`",
"pos": 105,
"start": {
"character": 105,
@@ -36,7 +36,7 @@
"column": 18,
"line": 9
},
- "message": "Component has unused export property 'g'. If it is for external reference only, please consider using `export const 'g'`",
+ "message": "Component has unused export property 'g'. If it is for external reference only, please consider using `export const g`",
"pos": 125,
"start": {
"character": 125,
@@ -51,7 +51,7 @@
"column": 18,
"line": 10
},
- "message": "Component has unused export property 'h'. If it is for external reference only, please consider using `export const 'h'`",
+ "message": "Component has unused export property 'h'. If it is for external reference only, please consider using `export const h`",
"pos": 145,
"start": {
"character": 145,
@@ -66,7 +66,7 @@
"column": 25,
"line": 12
},
- "message": "Component has unused export property 'j'. If it is for external reference only, please consider using `export const 'j'`",
+ "message": "Component has unused export property 'j'. If it is for external reference only, please consider using `export const j`",
"pos": 187,
"start": {
"character": 187,
diff --git a/test/vars/samples/modules-vars/_config.js b/test/vars/samples/modules-vars/_config.js
new file mode 100644
index 000000000000..e178941db672
--- /dev/null
+++ b/test/vars/samples/modules-vars/_config.js
@@ -0,0 +1,72 @@
+export default {
+ test(assert, vars) {
+ assert.deepEqual(vars, [
+ {
+ name: "a",
+ export_name: null,
+ injected: false,
+ module: true,
+ mutated: false,
+ reassigned: true,
+ referenced: false,
+ referenced_from_script: false,
+ writable: true
+ },
+ {
+ name: "b",
+ export_name: null,
+ injected: false,
+ module: true,
+ mutated: true,
+ reassigned: false,
+ referenced: false,
+ referenced_from_script: false,
+ writable: true
+ },
+ {
+ name: "c",
+ export_name: null,
+ injected: false,
+ module: true,
+ mutated: false,
+ reassigned: false,
+ referenced: false,
+ referenced_from_script: false,
+ writable: true
+ },
+ {
+ name: "d",
+ export_name: null,
+ injected: false,
+ module: true,
+ mutated: false,
+ reassigned: false,
+ referenced: false,
+ referenced_from_script: false,
+ writable: true
+ },
+ {
+ name: "c",
+ export_name: null,
+ injected: false,
+ module: false,
+ mutated: false,
+ reassigned: true,
+ referenced: false,
+ referenced_from_script: true,
+ writable: true
+ },
+ {
+ name: "foo",
+ export_name: null,
+ injected: false,
+ module: false,
+ mutated: false,
+ reassigned: false,
+ referenced: false,
+ referenced_from_script: false,
+ writable: false
+ }
+ ]);
+ }
+};
diff --git a/test/vars/samples/modules-vars/input.svelte b/test/vars/samples/modules-vars/input.svelte
new file mode 100644
index 000000000000..8bbd5bdc5ea7
--- /dev/null
+++ b/test/vars/samples/modules-vars/input.svelte
@@ -0,0 +1,18 @@
+
+
\ No newline at end of file