diff --git a/.eslintignore b/.eslintignore index b5cb03ae6e..d123c10530 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,7 +2,6 @@ **/expected.js _output test/*/samples/*/output.js -node_modules # automatically generated internal_exports.ts diff --git a/.eslintrc.js b/.eslintrc.js index 946a157e40..a093de610b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,65 +1,6 @@ module.exports = { root: true, - rules: { - indent: 'off', - 'no-unused-vars': 'off', - semi: [2, 'always'], - 'keyword-spacing': [2, { before: true, after: true }], - 'space-before-blocks': [2, 'always'], - 'no-mixed-spaces-and-tabs': [2, 'smart-tabs'], - 'no-cond-assign': 0, - 'object-shorthand': [2, 'always'], - 'no-const-assign': 2, - 'no-class-assign': 2, - 'no-this-before-super': 2, - 'no-var': 2, - 'no-unreachable': 2, - 'valid-typeof': 2, - 'quote-props': [2, 'as-needed'], - 'one-var': [2, 'never'], - 'prefer-arrow-callback': 2, - 'prefer-const': [2, { destructuring: 'all' }], - 'arrow-spacing': 2, - 'no-inner-declarations': 0, - 'require-atomic-updates': 'off', - '@typescript-eslint/indent': 'off', - '@typescript-eslint/camelcase': 'off', - '@typescript-eslint/no-use-before-define': 'off', - '@typescript-eslint/array-type': ['error', 'array-simple'], - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/explicit-member-accessibility': 'off', - '@typescript-eslint/no-unused-vars': [ - 'error', - { - argsIgnorePattern: '^_' - } - ], - '@typescript-eslint/no-object-literal-type-assertion': 'off', - '@typescript-eslint/no-unused-vars': 'off', - '@typescript-eslint/prefer-interface': 'off' - }, - globals: { - globalThis: false - }, - env: { - es6: true, - browser: true, - node: true, - mocha: true - }, - extends: [ - 'eslint:recommended', - 'plugin:import/errors', - 'plugin:import/warnings', - 'plugin:import/typescript', - 'plugin:@typescript-eslint/recommended' - ], - parserOptions: { - ecmaVersion: 9, - sourceType: 'module' - }, - plugins: ['svelte3'], + extends: '@sveltejs', settings: { 'import/core-modules': [ 'svelte', @@ -69,20 +10,5 @@ module.exports = { 'estree' ], 'svelte3/compiler': require('./compiler') - }, - overrides: [ - { - files: ['*.js'], - rules: { - '@typescript-eslint/no-var-requires': 'off' - } - }, - { - files: ['*.svelte'], - processor: 'svelte3/svelte3', - rules: { - '@typescript-eslint/indent': 'off' - } - } - ] + } }; diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 6871094f5c..7daff3f1ab 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -8,10 +8,13 @@ the issue. One way we prioritize issues is by the number of :+1: reactions on their descriptions. Please DO NOT add `+1` or :+1: comments. ### Feature requests and proposals + We're excited to hear how we can make Svelte better. Please add as much detail -as you can on your use case. +as you can on your use case. To propose an implementation of a large feature or +change, please create an [RFC](https://github.com/sveltejs/rfcs). ### Bugs + If you're filing an issue about a bug please include as much information as you can including the following. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index e533c21c96..923bfdb50c 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -7,6 +7,11 @@ assignees: '' --- + + **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. For example: I'm always frustrated when [...] diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1e77e0337a..d14a0f9fe4 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,8 +1,7 @@ - - ### Before submitting the PR, please make sure you do the following -- [ ] It's really useful if your PR relates to an outstanding issue, so please reference it in your PR, or create an explanatory one for discussion. In many cases features are absent for a reason. -- [ ] This message body should clearly illustrate what problems it solves. If there are related issues, remember to reference them. -- [ ] Ideally, include a test that fails without this PR but passes with it. PRs will only be merged once they pass CI. (Remember to `npm run lint`!) +- [ ] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs +- [ ] This message body should clearly illustrate what problems it solves. +- [ ] Ideally, include a test that fails without this PR but passes with it. + ### Tests -- [ ] Run the tests tests with `npm test` or `yarn test`) +- [ ] Run the tests with `npm test` and lint the project with `npm run lint` diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 457ddb3bab..4e04386fcc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,12 +3,12 @@ on: [push, pull_request] jobs: Tests: runs-on: ${{ matrix.os }} + timeout-minutes: 10 strategy: matrix: node-version: [8, 10, 12, 14] os: [ubuntu-latest, windows-latest, macOS-latest] steps: - - run: git config --global core.autocrlf false - uses: actions/checkout@v1 - uses: actions/setup-node@v1 with: @@ -19,12 +19,17 @@ jobs: CI: true Lint: runs-on: ubuntu-latest + timeout-minutes: 2 steps: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 - run: 'npm i && npm run lint' Unit: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + timeout-minutes: 5 + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macOS-latest] steps: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fd3d96fbe..0ccfeff273 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,72 @@ ## Unreleased +* Expose object of which slots have received content in `$$slots` ([#2106](https://github.com/sveltejs/svelte/issues/2106)) +* Re-throw an unhandled rejection when an `{#await}` block with no `{:catch}` gets a rejection ([#5129](https://github.com/sveltejs/svelte/issues/5129)) +* Add types to `createEventDispatcher` ([#5211](https://github.com/sveltejs/svelte/issues/5211)) +* In SSR mode, do not automatically declare variables for reactive assignments to member expressions ([#5247](https://github.com/sveltejs/svelte/issues/5247)) +* Include selector in message of `unused-css-selector` warning ([#5252](https://github.com/sveltejs/svelte/issues/5252)) +* Fix using ``s in child `{#await}`/`{#each}` contexts ([#5255](https://github.com/sveltejs/svelte/issues/5255)) +* Fix using `` in `{:catch}` ([#5259](https://github.com/sveltejs/svelte/issues/5259)) +* Fix setting one-way bound `` `value` to `undefined` when it has spread attributes ([#5270](https://github.com/sveltejs/svelte/issues/5270)) +* Fix deep two-way bindings inside an `{#each}` involving a store ([#5286](https://github.com/sveltejs/svelte/issues/5286)) + +## 3.24.1 + +* Prevent duplicate invalidation with certain two-way component bindings ([#3180](https://github.com/sveltejs/svelte/issues/3180), [#5117](https://github.com/sveltejs/svelte/issues/5117), [#5144](https://github.com/sveltejs/svelte/issues/5144)) +* Fix reactivity when passing `$$props` to a `` ([#3364](https://github.com/sveltejs/svelte/issues/3364)) +* Fix transitions on `{#each}` `{:else}` ([#4970](https://github.com/sveltejs/svelte/issues/4970)) +* Fix unneeded invalidation of `$$props` and `$$restProps` ([#4993](https://github.com/sveltejs/svelte/issues/4993), [#5118](https://github.com/sveltejs/svelte/issues/5118)) +* Provide better compiler error message when mismatched tags are due to autoclosing of tags ([#5049](https://github.com/sveltejs/svelte/issues/5049)) +* Add `a11y-label-has-associated-control` warning ([#5074](https://github.com/sveltejs/svelte/pull/5074)) +* Add `a11y-media-has-caption` warning ([#5075](https://github.com/sveltejs/svelte/pull/5075)) +* Fix `bind:group` when using contextual reference ([#5174](https://github.com/sveltejs/svelte/issues/5174)) + +## 3.24.0 + +* Support nullish coalescing (`??`) and optional chaining (`?.`) operators ([#1972](https://github.com/sveltejs/svelte/issues/1972)) +* Support `import.meta` ([#4379](https://github.com/sveltejs/svelte/issues/4379)) +* Fix only setting `` values when they're changed when there are spread attributes ([#4418](https://github.com/sveltejs/svelte/issues/4418)) +* Fix placement of `{@html}` when used at the root of a slot, at the root of a component, or in `` ([#5012](https://github.com/sveltejs/svelte/issues/5012), [#5071](https://github.com/sveltejs/svelte/pull/5071)) +* Fix certain handling of two-way bound `contenteditable` elements ([#5018](https://github.com/sveltejs/svelte/issues/5018)) +* Fix handling of `import`ed value that is used as a store and is also mutated ([#5019](https://github.com/sveltejs/svelte/issues/5019)) +* Do not display `a11y-missing-content` warning on elements with `contenteditable` bindings ([#5020](https://github.com/sveltejs/svelte/issues/5020)) +* Fix handling of `this` in inline function expressions in the template ([#5033](https://github.com/sveltejs/svelte/issues/5033)) +* Fix collapsing HTML with static content ([#5040](https://github.com/sveltejs/svelte/issues/5040)) +* Prevent use of `$store` at compile time when top-level `store` has been shadowed ([#5048](https://github.com/sveltejs/svelte/issues/5048)) +* Update ` + + + + +{#if files} +

Selected files:

+ {#each Array.from(files) as file} +

{file.name} ({file.size} bytes)

+ {/each} +{/if} diff --git a/site/content/examples/05-bindings/05-file-inputs/meta.json b/site/content/examples/05-bindings/05-file-inputs/meta.json new file mode 100644 index 0000000000..92d0587e87 --- /dev/null +++ b/site/content/examples/05-bindings/05-file-inputs/meta.json @@ -0,0 +1,3 @@ +{ + "title": "File inputs" +} diff --git a/site/content/examples/05-bindings/05-select-bindings/App.svelte b/site/content/examples/05-bindings/06-select-bindings/App.svelte similarity index 100% rename from site/content/examples/05-bindings/05-select-bindings/App.svelte rename to site/content/examples/05-bindings/06-select-bindings/App.svelte diff --git a/site/content/examples/05-bindings/05-select-bindings/meta.json b/site/content/examples/05-bindings/06-select-bindings/meta.json similarity index 100% rename from site/content/examples/05-bindings/05-select-bindings/meta.json rename to site/content/examples/05-bindings/06-select-bindings/meta.json diff --git a/site/content/examples/05-bindings/06-multiple-select-bindings/App.svelte b/site/content/examples/05-bindings/07-multiple-select-bindings/App.svelte similarity index 100% rename from site/content/examples/05-bindings/06-multiple-select-bindings/App.svelte rename to site/content/examples/05-bindings/07-multiple-select-bindings/App.svelte diff --git a/site/content/examples/05-bindings/06-multiple-select-bindings/meta.json b/site/content/examples/05-bindings/07-multiple-select-bindings/meta.json similarity index 100% rename from site/content/examples/05-bindings/06-multiple-select-bindings/meta.json rename to site/content/examples/05-bindings/07-multiple-select-bindings/meta.json diff --git a/site/content/examples/05-bindings/07-each-block-bindings/App.svelte b/site/content/examples/05-bindings/08-each-block-bindings/App.svelte similarity index 89% rename from site/content/examples/05-bindings/07-each-block-bindings/App.svelte rename to site/content/examples/05-bindings/08-each-block-bindings/App.svelte index ff91612ec5..4d3d75420c 100644 --- a/site/content/examples/05-bindings/07-each-block-bindings/App.svelte +++ b/site/content/examples/05-bindings/08-each-block-bindings/App.svelte @@ -16,16 +16,10 @@ $: remaining = todos.filter(t => !t.done).length; - -

Todos

{#each todos as todo} -
+
{/each} diff --git a/site/content/examples/05-bindings/07-each-block-bindings/meta.json b/site/content/examples/05-bindings/08-each-block-bindings/meta.json similarity index 100% rename from site/content/examples/05-bindings/07-each-block-bindings/meta.json rename to site/content/examples/05-bindings/08-each-block-bindings/meta.json diff --git a/site/content/examples/05-bindings/08-media-elements/App.svelte b/site/content/examples/05-bindings/09-media-elements/App.svelte similarity index 95% rename from site/content/examples/05-bindings/08-media-elements/App.svelte rename to site/content/examples/05-bindings/09-media-elements/App.svelte index 469e9e12eb..7a071dbe49 100644 --- a/site/content/examples/05-bindings/08-media-elements/App.svelte +++ b/site/content/examples/05-bindings/09-media-elements/App.svelte @@ -109,8 +109,8 @@
- + diff --git a/site/src/utils/highlight.js b/site/src/utils/highlight.js index d9e4fe5ec8..124af2e6be 100644 --- a/site/src/utils/highlight.js +++ b/site/src/utils/highlight.js @@ -1,6 +1,7 @@ import { langs } from '@sveltejs/site-kit/utils/markdown.js'; import PrismJS from 'prismjs'; import 'prismjs/components/prism-bash'; +import 'prismjs/components/prism-diff'; import 'prism-svelte'; export function highlight(source, lang) { diff --git a/site/static/examples/thumbnails/file-inputs.jpg b/site/static/examples/thumbnails/file-inputs.jpg new file mode 100644 index 0000000000..d302633f6b Binary files /dev/null and b/site/static/examples/thumbnails/file-inputs.jpg differ diff --git a/site/static/media/svelte-ts.png b/site/static/media/svelte-ts.png new file mode 100644 index 0000000000..ed562822c3 Binary files /dev/null and b/site/static/media/svelte-ts.png differ diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index a5a31c8070..ed2b10e404 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -8,7 +8,7 @@ import { create_scopes, extract_names, Scope, - extract_identifiers, + extract_identifiers } from './utils/scope'; import Stylesheet from './css/Stylesheet'; import { test } from '../config'; @@ -155,7 +155,7 @@ export default class Component { ) || { start: 0, end: 0 }; this.warn(svelteOptions, { code: 'custom-element-no-tag', - message: `No custom element 'tag' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. . To hide this warning, use `, + message: `No custom element 'tag' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. . To hide this warning, use ` }); } this.tag = this.component_options.tag || compile_options.tag; @@ -190,7 +190,7 @@ export default class Component { this.add_var({ name, injected: true, - referenced: true, + referenced: true }); } else if (name[0] === '$') { this.add_var({ @@ -198,7 +198,7 @@ export default class Component { injected: true, referenced: true, mutated: true, - writable: true, + writable: true }); const subscribable_name = name.slice(1); @@ -289,7 +289,7 @@ export default class Component { } const imported_helpers = Array.from(this.helpers, ([name, alias]) => ({ name, - alias, + alias })); create_module( @@ -305,7 +305,7 @@ export default class Component { .filter(variable => variable.module && variable.export_name) .map(variable => ({ name: variable.name, - as: variable.export_name, + as: variable.export_name })) ); @@ -342,9 +342,9 @@ export default class Component { reassigned: v.reassigned || false, referenced: v.referenced || false, writable: v.writable || false, - referenced_from_script: v.referenced_from_script || false, + referenced_from_script: v.referenced_from_script || false })), - stats: this.stats.render(), + stats: this.stats.render() }; } @@ -409,7 +409,7 @@ export default class Component { source: this.source, start: pos.start, end: pos.end, - filename: this.compile_options.filename, + filename: this.compile_options.filename }); } @@ -441,7 +441,7 @@ export default class Component { pos: pos.start, filename: this.compile_options.filename, toString: () => - `${warning.message} (${start.line}:${start.column})\n${frame}`, + `${warning.message} (${start.line}:${start.column})\n${frame}` }); } @@ -453,7 +453,7 @@ export default class Component { if (node.type === 'ExportDefaultDeclaration') { this.error(node, { code: `default-export`, - message: `A component cannot have a default export`, + message: `A component cannot have a default export` }); } @@ -461,7 +461,7 @@ export default class Component { if (node.source) { this.error(node, { code: `not-implemented`, - message: `A component currently cannot have an export ... from`, + message: `A component currently cannot have an export ... from` }); } if (node.declaration) { @@ -531,10 +531,10 @@ export default class Component { if (node.type === 'LabeledStatement' && node.label.name === '$') { component.warn(node as any, { code: 'module-script-reactive-declaration', - message: '$: has no effect in a module script', + message: '$: has no effect in a module script' }); } - }, + } }); const { scope, globals } = create_scopes(script.content); @@ -544,7 +544,7 @@ export default class Component { if (name[0] === '$') { this.error(node as any, { code: 'illegal-declaration', - message: `The $ prefix is reserved, and cannot be used for variable and import names`, + message: `The $ prefix is reserved, and cannot be used for variable and import names` }); } @@ -562,7 +562,7 @@ export default class Component { if (name[0] === '$') { this.error(node as any, { code: 'illegal-subscription', - message: `Cannot reference store value inside + \ No newline at end of file diff --git a/test/js/samples/inline-style-optimized-multiple/expected.js b/test/js/samples/inline-style-optimized-multiple/expected.js index 84a38abd7b..0a9d0a1e8e 100644 --- a/test/js/samples/inline-style-optimized-multiple/expected.js +++ b/test/js/samples/inline-style-optimized-multiple/expected.js @@ -44,7 +44,7 @@ function instance($$self, $$props, $$invalidate) { let { x } = $$props; let { y } = $$props; - $$self.$set = $$props => { + $$self.$$set = $$props => { if ("color" in $$props) $$invalidate(0, color = $$props.color); if ("x" in $$props) $$invalidate(1, x = $$props.x); if ("y" in $$props) $$invalidate(2, y = $$props.y); diff --git a/test/js/samples/inline-style-optimized-url/expected.js b/test/js/samples/inline-style-optimized-url/expected.js index 77870348a5..0debb03585 100644 --- a/test/js/samples/inline-style-optimized-url/expected.js +++ b/test/js/samples/inline-style-optimized-url/expected.js @@ -37,7 +37,7 @@ function create_fragment(ctx) { function instance($$self, $$props, $$invalidate) { let { data } = $$props; - $$self.$set = $$props => { + $$self.$$set = $$props => { if ("data" in $$props) $$invalidate(0, data = $$props.data); }; diff --git a/test/js/samples/inline-style-optimized/expected.js b/test/js/samples/inline-style-optimized/expected.js index 5bef284f09..b7db0f1cf3 100644 --- a/test/js/samples/inline-style-optimized/expected.js +++ b/test/js/samples/inline-style-optimized/expected.js @@ -37,7 +37,7 @@ function create_fragment(ctx) { function instance($$self, $$props, $$invalidate) { let { color } = $$props; - $$self.$set = $$props => { + $$self.$$set = $$props => { if ("color" in $$props) $$invalidate(0, color = $$props.color); }; diff --git a/test/js/samples/inline-style-unoptimized/expected.js b/test/js/samples/inline-style-unoptimized/expected.js index fdff685ead..0688f14b9b 100644 --- a/test/js/samples/inline-style-unoptimized/expected.js +++ b/test/js/samples/inline-style-unoptimized/expected.js @@ -54,7 +54,7 @@ function instance($$self, $$props, $$invalidate) { let { key } = $$props; let { value } = $$props; - $$self.$set = $$props => { + $$self.$$set = $$props => { if ("style" in $$props) $$invalidate(0, style = $$props.style); if ("key" in $$props) $$invalidate(1, key = $$props.key); if ("value" in $$props) $$invalidate(2, value = $$props.value); diff --git a/test/js/samples/input-files/expected.js b/test/js/samples/input-files/expected.js index 1c1e57fc9b..8adc7443f5 100644 --- a/test/js/samples/input-files/expected.js +++ b/test/js/samples/input-files/expected.js @@ -13,6 +13,7 @@ import { function create_fragment(ctx) { let input; + let mounted; let dispose; return { @@ -21,16 +22,20 @@ function create_fragment(ctx) { attr(input, "type", "file"); input.multiple = true; }, - m(target, anchor, remount) { + m(target, anchor) { insert(target, input, anchor); - if (remount) dispose(); - dispose = listen(input, "change", /*input_change_handler*/ ctx[1]); + + if (!mounted) { + dispose = listen(input, "change", /*input_change_handler*/ ctx[1]); + mounted = true; + } }, p: noop, i: noop, o: noop, d(detaching) { if (detaching) detach(input); + mounted = false; dispose(); } }; @@ -44,7 +49,7 @@ function instance($$self, $$props, $$invalidate) { $$invalidate(0, files); } - $$self.$set = $$props => { + $$self.$$set = $$props => { if ("files" in $$props) $$invalidate(0, files = $$props.files); }; diff --git a/test/js/samples/input-no-initial-value/expected.js b/test/js/samples/input-no-initial-value/expected.js index f72daa22a3..3354aa3111 100644 --- a/test/js/samples/input-no-initial-value/expected.js +++ b/test/js/samples/input-no-initial-value/expected.js @@ -20,6 +20,7 @@ function create_fragment(ctx) { let input; let t0; let button; + let mounted; let dispose; return { @@ -32,18 +33,21 @@ function create_fragment(ctx) { attr(input, "type", "text"); input.required = true; }, - m(target, anchor, remount) { + m(target, anchor) { insert(target, form, anchor); append(form, input); set_input_value(input, /*test*/ ctx[0]); append(form, t0); append(form, button); - if (remount) run_all(dispose); - dispose = [ - listen(input, "input", /*input_input_handler*/ ctx[2]), - listen(form, "submit", /*handleSubmit*/ ctx[1]) - ]; + if (!mounted) { + dispose = [ + listen(input, "input", /*input_input_handler*/ ctx[2]), + listen(form, "submit", /*handleSubmit*/ ctx[1]) + ]; + + mounted = true; + } }, p(ctx, [dirty]) { if (dirty & /*test*/ 1 && input.value !== /*test*/ ctx[0]) { @@ -54,6 +58,7 @@ function create_fragment(ctx) { o: noop, d(detaching) { if (detaching) detach(form); + mounted = false; run_all(dispose); } }; diff --git a/test/js/samples/input-range/expected.js b/test/js/samples/input-range/expected.js index 17a8065449..a855ca3653 100644 --- a/test/js/samples/input-range/expected.js +++ b/test/js/samples/input-range/expected.js @@ -16,6 +16,7 @@ import { function create_fragment(ctx) { let input; + let mounted; let dispose; return { @@ -23,15 +24,18 @@ function create_fragment(ctx) { input = element("input"); attr(input, "type", "range"); }, - m(target, anchor, remount) { + m(target, anchor) { insert(target, input, anchor); set_input_value(input, /*value*/ ctx[0]); - if (remount) run_all(dispose); - dispose = [ - listen(input, "change", /*input_change_input_handler*/ ctx[1]), - listen(input, "input", /*input_change_input_handler*/ ctx[1]) - ]; + if (!mounted) { + dispose = [ + listen(input, "change", /*input_change_input_handler*/ ctx[1]), + listen(input, "input", /*input_change_input_handler*/ ctx[1]) + ]; + + mounted = true; + } }, p(ctx, [dirty]) { if (dirty & /*value*/ 1) { @@ -42,6 +46,7 @@ function create_fragment(ctx) { o: noop, d(detaching) { if (detaching) detach(input); + mounted = false; run_all(dispose); } }; @@ -55,7 +60,7 @@ function instance($$self, $$props, $$invalidate) { $$invalidate(0, value); } - $$self.$set = $$props => { + $$self.$$set = $$props => { if ("value" in $$props) $$invalidate(0, value = $$props.value); }; diff --git a/test/js/samples/input-value/expected.js b/test/js/samples/input-value/expected.js index 31be2895ac..781a2ae603 100644 --- a/test/js/samples/input-value/expected.js +++ b/test/js/samples/input-value/expected.js @@ -20,6 +20,7 @@ function create_fragment(ctx) { let h1; let t1; let t2; + let mounted; let dispose; return { @@ -31,14 +32,17 @@ function create_fragment(ctx) { t2 = text("!"); input.value = /*name*/ ctx[0]; }, - m(target, anchor, remount) { + m(target, anchor) { insert(target, input, anchor); insert(target, t0, anchor); insert(target, h1, anchor); append(h1, t1); append(h1, t2); - if (remount) dispose(); - dispose = listen(input, "input", /*onInput*/ ctx[1]); + + if (!mounted) { + dispose = listen(input, "input", /*onInput*/ ctx[1]); + mounted = true; + } }, p(ctx, [dirty]) { if (dirty & /*name*/ 1 && input.value !== /*name*/ ctx[0]) { @@ -53,6 +57,7 @@ function create_fragment(ctx) { if (detaching) detach(input); if (detaching) detach(t0); if (detaching) detach(h1); + mounted = false; dispose(); } }; diff --git a/test/js/samples/input-without-blowback-guard/expected.js b/test/js/samples/input-without-blowback-guard/expected.js index 1e379032f3..6c5b215623 100644 --- a/test/js/samples/input-without-blowback-guard/expected.js +++ b/test/js/samples/input-without-blowback-guard/expected.js @@ -13,6 +13,7 @@ import { function create_fragment(ctx) { let input; + let mounted; let dispose; return { @@ -20,11 +21,14 @@ function create_fragment(ctx) { input = element("input"); attr(input, "type", "checkbox"); }, - m(target, anchor, remount) { + m(target, anchor) { insert(target, input, anchor); input.checked = /*foo*/ ctx[0]; - if (remount) dispose(); - dispose = listen(input, "change", /*input_change_handler*/ ctx[1]); + + if (!mounted) { + dispose = listen(input, "change", /*input_change_handler*/ ctx[1]); + mounted = true; + } }, p(ctx, [dirty]) { if (dirty & /*foo*/ 1) { @@ -35,6 +39,7 @@ function create_fragment(ctx) { o: noop, d(detaching) { if (detaching) detach(input); + mounted = false; dispose(); } }; @@ -48,7 +53,7 @@ function instance($$self, $$props, $$invalidate) { $$invalidate(0, foo); } - $$self.$set = $$props => { + $$self.$$set = $$props => { if ("foo" in $$props) $$invalidate(0, foo = $$props.foo); }; diff --git a/test/js/samples/instrumentation-script-if-no-block/expected.js b/test/js/samples/instrumentation-script-if-no-block/expected.js index f45e52aebd..7f51c64550 100644 --- a/test/js/samples/instrumentation-script-if-no-block/expected.js +++ b/test/js/samples/instrumentation-script-if-no-block/expected.js @@ -20,6 +20,7 @@ function create_fragment(ctx) { let p; let t2; let t3; + let mounted; let dispose; return { @@ -31,14 +32,17 @@ function create_fragment(ctx) { t2 = text("x: "); t3 = text(/*x*/ ctx[0]); }, - m(target, anchor, remount) { + m(target, anchor) { insert(target, button, anchor); insert(target, t1, anchor); insert(target, p, anchor); append(p, t2); append(p, t3); - if (remount) dispose(); - dispose = listen(button, "click", /*foo*/ ctx[1]); + + if (!mounted) { + dispose = listen(button, "click", /*foo*/ ctx[1]); + mounted = true; + } }, p(ctx, [dirty]) { if (dirty & /*x*/ 1) set_data(t3, /*x*/ ctx[0]); @@ -49,6 +53,7 @@ function create_fragment(ctx) { if (detaching) detach(button); if (detaching) detach(t1); if (detaching) detach(p); + mounted = false; dispose(); } }; diff --git a/test/js/samples/instrumentation-script-x-equals-x/expected.js b/test/js/samples/instrumentation-script-x-equals-x/expected.js index 9fe9640978..ea0d65acb9 100644 --- a/test/js/samples/instrumentation-script-x-equals-x/expected.js +++ b/test/js/samples/instrumentation-script-x-equals-x/expected.js @@ -21,6 +21,7 @@ function create_fragment(ctx) { let t2; let t3_value = /*things*/ ctx[0].length + ""; let t3; + let mounted; let dispose; return { @@ -32,14 +33,17 @@ function create_fragment(ctx) { t2 = text("number of things: "); t3 = text(t3_value); }, - m(target, anchor, remount) { + m(target, anchor) { insert(target, button, anchor); insert(target, t1, anchor); insert(target, p, anchor); append(p, t2); append(p, t3); - if (remount) dispose(); - dispose = listen(button, "click", /*foo*/ ctx[1]); + + if (!mounted) { + dispose = listen(button, "click", /*foo*/ ctx[1]); + mounted = true; + } }, p(ctx, [dirty]) { if (dirty & /*things*/ 1 && t3_value !== (t3_value = /*things*/ ctx[0].length + "")) set_data(t3, t3_value); @@ -50,6 +54,7 @@ function create_fragment(ctx) { if (detaching) detach(button); if (detaching) detach(t1); if (detaching) detach(p); + mounted = false; dispose(); } }; diff --git a/test/js/samples/instrumentation-template-if-no-block/expected.js b/test/js/samples/instrumentation-template-if-no-block/expected.js index 6f3bea4010..0c2713a9cc 100644 --- a/test/js/samples/instrumentation-template-if-no-block/expected.js +++ b/test/js/samples/instrumentation-template-if-no-block/expected.js @@ -20,6 +20,7 @@ function create_fragment(ctx) { let p; let t2; let t3; + let mounted; let dispose; return { @@ -31,14 +32,17 @@ function create_fragment(ctx) { t2 = text("x: "); t3 = text(/*x*/ ctx[0]); }, - m(target, anchor, remount) { + m(target, anchor) { insert(target, button, anchor); insert(target, t1, anchor); insert(target, p, anchor); append(p, t2); append(p, t3); - if (remount) dispose(); - dispose = listen(button, "click", /*click_handler*/ ctx[1]); + + if (!mounted) { + dispose = listen(button, "click", /*click_handler*/ ctx[1]); + mounted = true; + } }, p(ctx, [dirty]) { if (dirty & /*x*/ 1) set_data(t3, /*x*/ ctx[0]); @@ -49,6 +53,7 @@ function create_fragment(ctx) { if (detaching) detach(button); if (detaching) detach(t1); if (detaching) detach(p); + mounted = false; dispose(); } }; diff --git a/test/js/samples/instrumentation-template-x-equals-x/expected.js b/test/js/samples/instrumentation-template-x-equals-x/expected.js index ed095353bd..55cd310661 100644 --- a/test/js/samples/instrumentation-template-x-equals-x/expected.js +++ b/test/js/samples/instrumentation-template-x-equals-x/expected.js @@ -21,6 +21,7 @@ function create_fragment(ctx) { let t2; let t3_value = /*things*/ ctx[0].length + ""; let t3; + let mounted; let dispose; return { @@ -32,14 +33,17 @@ function create_fragment(ctx) { t2 = text("number of things: "); t3 = text(t3_value); }, - m(target, anchor, remount) { + m(target, anchor) { insert(target, button, anchor); insert(target, t1, anchor); insert(target, p, anchor); append(p, t2); append(p, t3); - if (remount) dispose(); - dispose = listen(button, "click", /*click_handler*/ ctx[1]); + + if (!mounted) { + dispose = listen(button, "click", /*click_handler*/ ctx[1]); + mounted = true; + } }, p(ctx, [dirty]) { if (dirty & /*things*/ 1 && t3_value !== (t3_value = /*things*/ ctx[0].length + "")) set_data(t3, t3_value); @@ -50,6 +54,7 @@ function create_fragment(ctx) { if (detaching) detach(button); if (detaching) detach(t1); if (detaching) detach(p); + mounted = false; dispose(); } }; diff --git a/test/js/samples/loop-protect/_config.js b/test/js/samples/loop-protect/_config.js index fcbf8be09b..1dc927b4da 100644 --- a/test/js/samples/loop-protect/_config.js +++ b/test/js/samples/loop-protect/_config.js @@ -1,6 +1,6 @@ export default { options: { dev: true, - loopGuardTimeout: 100, - }, + loopGuardTimeout: 100 + } }; diff --git a/test/js/samples/loop-protect/expected.js b/test/js/samples/loop-protect/expected.js index c52d9df437..1042b20823 100644 --- a/test/js/samples/loop-protect/expected.js +++ b/test/js/samples/loop-protect/expected.js @@ -67,6 +67,8 @@ function foo() { } function instance($$self, $$props, $$invalidate) { + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("Component", slots, []); let node; { @@ -111,12 +113,10 @@ function instance($$self, $$props, $$invalidate) { if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console_1.warn(` was created with unknown prop '${key}'`); }); - let { $$slots = {}, $$scope } = $$props; - validate_slots("Component", $$slots, []); - function div_binding($$value) { binding_callbacks[$$value ? "unshift" : "push"](() => { - $$invalidate(0, node = $$value); + node = $$value; + $$invalidate(0, node); }); } diff --git a/test/js/samples/media-bindings/expected.js b/test/js/samples/media-bindings/expected.js index 0849a38b51..867d4a7dad 100644 --- a/test/js/samples/media-bindings/expected.js +++ b/test/js/samples/media-bindings/expected.js @@ -19,6 +19,7 @@ function create_fragment(ctx) { let audio_updating = false; let audio_animationframe; let audio_is_paused = true; + let mounted; let dispose; function audio_timeupdate_handler() { @@ -42,7 +43,7 @@ function create_fragment(ctx) { if (/*seeking*/ ctx[9] === void 0) add_render_callback(() => /*audio_seeking_seeked_handler*/ ctx[18].call(audio)); if (/*ended*/ ctx[10] === void 0) add_render_callback(() => /*audio_ended_handler*/ ctx[19].call(audio)); }, - m(target, anchor, remount) { + m(target, anchor) { insert(target, audio, anchor); if (!isNaN(/*volume*/ ctx[6])) { @@ -55,21 +56,23 @@ function create_fragment(ctx) { audio.playbackRate = /*playbackRate*/ ctx[8]; } - if (remount) run_all(dispose); - - dispose = [ - listen(audio, "progress", /*audio_progress_handler*/ ctx[11]), - listen(audio, "loadedmetadata", /*audio_loadedmetadata_handler*/ ctx[12]), - listen(audio, "timeupdate", audio_timeupdate_handler), - listen(audio, "durationchange", /*audio_durationchange_handler*/ ctx[14]), - listen(audio, "play", /*audio_play_pause_handler*/ ctx[15]), - listen(audio, "pause", /*audio_play_pause_handler*/ ctx[15]), - listen(audio, "volumechange", /*audio_volumechange_handler*/ ctx[16]), - listen(audio, "ratechange", /*audio_ratechange_handler*/ ctx[17]), - listen(audio, "seeking", /*audio_seeking_seeked_handler*/ ctx[18]), - listen(audio, "seeked", /*audio_seeking_seeked_handler*/ ctx[18]), - listen(audio, "ended", /*audio_ended_handler*/ ctx[19]) - ]; + if (!mounted) { + dispose = [ + listen(audio, "progress", /*audio_progress_handler*/ ctx[11]), + listen(audio, "loadedmetadata", /*audio_loadedmetadata_handler*/ ctx[12]), + listen(audio, "timeupdate", audio_timeupdate_handler), + listen(audio, "durationchange", /*audio_durationchange_handler*/ ctx[14]), + listen(audio, "play", /*audio_play_pause_handler*/ ctx[15]), + listen(audio, "pause", /*audio_play_pause_handler*/ ctx[15]), + listen(audio, "volumechange", /*audio_volumechange_handler*/ ctx[16]), + listen(audio, "ratechange", /*audio_ratechange_handler*/ ctx[17]), + listen(audio, "seeking", /*audio_seeking_seeked_handler*/ ctx[18]), + listen(audio, "seeked", /*audio_seeking_seeked_handler*/ ctx[18]), + listen(audio, "ended", /*audio_ended_handler*/ ctx[19]) + ]; + + mounted = true; + } }, p(ctx, [dirty]) { if (!audio_updating && dirty & /*currentTime*/ 8 && !isNaN(/*currentTime*/ ctx[3])) { @@ -98,6 +101,7 @@ function create_fragment(ctx) { o: noop, d(detaching) { if (detaching) detach(audio); + mounted = false; run_all(dispose); } }; @@ -169,7 +173,7 @@ function instance($$self, $$props, $$invalidate) { $$invalidate(10, ended); } - $$self.$set = $$props => { + $$self.$$set = $$props => { if ("buffered" in $$props) $$invalidate(0, buffered = $$props.buffered); if ("seekable" in $$props) $$invalidate(1, seekable = $$props.seekable); if ("played" in $$props) $$invalidate(2, played = $$props.played); diff --git a/test/js/samples/non-imported-component/expected.js b/test/js/samples/non-imported-component/expected.js index 2784fd17ac..5a6b8e8bb7 100644 --- a/test/js/samples/non-imported-component/expected.js +++ b/test/js/samples/non-imported-component/expected.js @@ -17,10 +17,12 @@ import { import Imported from "Imported.svelte"; function create_fragment(ctx) { + let imported; let t; + let nonimported; let current; - const imported = new Imported({}); - const nonimported = new NonImported({}); + imported = new Imported({}); + nonimported = new NonImported({}); return { c() { diff --git a/test/js/samples/optional-chaining/expected.js b/test/js/samples/optional-chaining/expected.js new file mode 100644 index 0000000000..8aa94796c1 --- /dev/null +++ b/test/js/samples/optional-chaining/expected.js @@ -0,0 +1,189 @@ +/* generated by Svelte vX.Y.Z */ +import { + SvelteComponent, + attr, + create_component, + destroy_component, + detach, + element, + init, + insert, + mount_component, + safe_not_equal, + set_data, + space, + text, + transition_in, + transition_out +} from "svelte/internal"; + +function create_fragment(ctx) { + let t0_value = /*a*/ ctx[0].normal + ""; + let t0; + let t1_value = /*b*/ ctx[1]?.optional + ""; + let t1; + let t2; + let t3_value = /*c*/ ctx[2]["computed"] + ""; + let t3; + let t4_value = /*d*/ ctx[3]?.["computed_optional"] + ""; + let t4; + let t5; + let t6_value = /*e*/ ctx[4]() + ""; + let t6; + let t7_value = /*f*/ ctx[5]?.() + ""; + let t7; + let t8; + let div; + let div_a_value; + let div_b_value; + let div_c_value; + let div_d_value; + let div_e_value; + let div_f_value; + let t9; + let component; + let current; + + component = new /*Component*/ ctx[6]({ + props: { + a: /*a*/ ctx[0].normal, + b: /*b*/ ctx[1]?.optional, + c: /*c*/ ctx[2]["computed"], + d: /*d*/ ctx[3]?.["computed_optional"], + e: /*e*/ ctx[4](), + f: /*f*/ ctx[5]?.() + } + }); + + return { + c() { + t0 = text(t0_value); + t1 = text(t1_value); + t2 = space(); + t3 = text(t3_value); + t4 = text(t4_value); + t5 = space(); + t6 = text(t6_value); + t7 = text(t7_value); + t8 = space(); + div = element("div"); + t9 = space(); + create_component(component.$$.fragment); + attr(div, "a", div_a_value = /*a*/ ctx[0].normal); + attr(div, "b", div_b_value = /*b*/ ctx[1]?.optional); + attr(div, "c", div_c_value = /*c*/ ctx[2]["computed"]); + attr(div, "d", div_d_value = /*d*/ ctx[3]?.["computed_optional"]); + attr(div, "e", div_e_value = /*e*/ ctx[4]()); + attr(div, "f", div_f_value = /*f*/ ctx[5]?.()); + }, + m(target, anchor) { + insert(target, t0, anchor); + insert(target, t1, anchor); + insert(target, t2, anchor); + insert(target, t3, anchor); + insert(target, t4, anchor); + insert(target, t5, anchor); + insert(target, t6, anchor); + insert(target, t7, anchor); + insert(target, t8, anchor); + insert(target, div, anchor); + insert(target, t9, anchor); + mount_component(component, target, anchor); + current = true; + }, + p(ctx, [dirty]) { + if ((!current || dirty & /*a*/ 1) && t0_value !== (t0_value = /*a*/ ctx[0].normal + "")) set_data(t0, t0_value); + if ((!current || dirty & /*b*/ 2) && t1_value !== (t1_value = /*b*/ ctx[1]?.optional + "")) set_data(t1, t1_value); + if ((!current || dirty & /*c*/ 4) && t3_value !== (t3_value = /*c*/ ctx[2]["computed"] + "")) set_data(t3, t3_value); + if ((!current || dirty & /*d*/ 8) && t4_value !== (t4_value = /*d*/ ctx[3]?.["computed_optional"] + "")) set_data(t4, t4_value); + if ((!current || dirty & /*e*/ 16) && t6_value !== (t6_value = /*e*/ ctx[4]() + "")) set_data(t6, t6_value); + if ((!current || dirty & /*f*/ 32) && t7_value !== (t7_value = /*f*/ ctx[5]?.() + "")) set_data(t7, t7_value); + + if (!current || dirty & /*a*/ 1 && div_a_value !== (div_a_value = /*a*/ ctx[0].normal)) { + attr(div, "a", div_a_value); + } + + if (!current || dirty & /*b*/ 2 && div_b_value !== (div_b_value = /*b*/ ctx[1]?.optional)) { + attr(div, "b", div_b_value); + } + + if (!current || dirty & /*c*/ 4 && div_c_value !== (div_c_value = /*c*/ ctx[2]["computed"])) { + attr(div, "c", div_c_value); + } + + if (!current || dirty & /*d*/ 8 && div_d_value !== (div_d_value = /*d*/ ctx[3]?.["computed_optional"])) { + attr(div, "d", div_d_value); + } + + if (!current || dirty & /*e*/ 16 && div_e_value !== (div_e_value = /*e*/ ctx[4]())) { + attr(div, "e", div_e_value); + } + + if (!current || dirty & /*f*/ 32 && div_f_value !== (div_f_value = /*f*/ ctx[5]?.())) { + attr(div, "f", div_f_value); + } + + const component_changes = {}; + if (dirty & /*a*/ 1) component_changes.a = /*a*/ ctx[0].normal; + if (dirty & /*b*/ 2) component_changes.b = /*b*/ ctx[1]?.optional; + if (dirty & /*c*/ 4) component_changes.c = /*c*/ ctx[2]["computed"]; + if (dirty & /*d*/ 8) component_changes.d = /*d*/ ctx[3]?.["computed_optional"]; + if (dirty & /*e*/ 16) component_changes.e = /*e*/ ctx[4](); + if (dirty & /*f*/ 32) component_changes.f = /*f*/ ctx[5]?.(); + component.$set(component_changes); + }, + i(local) { + if (current) return; + transition_in(component.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(component.$$.fragment, local); + current = false; + }, + d(detaching) { + if (detaching) detach(t0); + if (detaching) detach(t1); + if (detaching) detach(t2); + if (detaching) detach(t3); + if (detaching) detach(t4); + if (detaching) detach(t5); + if (detaching) detach(t6); + if (detaching) detach(t7); + if (detaching) detach(t8); + if (detaching) detach(div); + if (detaching) detach(t9); + destroy_component(component, detaching); + } + }; +} + +function instance($$self, $$props, $$invalidate) { + let { a } = $$props; + let { b } = $$props; + let { c } = $$props; + let { d } = $$props; + let { e } = $$props; + let { f } = $$props; + let Component; + + $$self.$$set = $$props => { + if ("a" in $$props) $$invalidate(0, a = $$props.a); + if ("b" in $$props) $$invalidate(1, b = $$props.b); + if ("c" in $$props) $$invalidate(2, c = $$props.c); + if ("d" in $$props) $$invalidate(3, d = $$props.d); + if ("e" in $$props) $$invalidate(4, e = $$props.e); + if ("f" in $$props) $$invalidate(5, f = $$props.f); + }; + + return [a, b, c, d, e, f, Component]; +} + +class Component_1 extends SvelteComponent { + constructor(options) { + super(); + init(this, options, instance, create_fragment, safe_not_equal, { a: 0, b: 1, c: 2, d: 3, e: 4, f: 5 }); + } +} + +export default Component_1; \ No newline at end of file diff --git a/test/js/samples/optional-chaining/input.svelte b/test/js/samples/optional-chaining/input.svelte new file mode 100644 index 0000000000..78edf2ca85 --- /dev/null +++ b/test/js/samples/optional-chaining/input.svelte @@ -0,0 +1,31 @@ + + +{a.normal}{b?.optional} +{c['computed']}{d?.['computed_optional']} +{e()}{f?.()} + +
+ + diff --git a/test/js/samples/reactive-values-non-topologically-ordered/expected.js b/test/js/samples/reactive-values-non-topologically-ordered/expected.js index 3d266f10ac..15290496d5 100644 --- a/test/js/samples/reactive-values-non-topologically-ordered/expected.js +++ b/test/js/samples/reactive-values-non-topologically-ordered/expected.js @@ -6,7 +6,7 @@ function instance($$self, $$props, $$invalidate) { let a; let b; - $$self.$set = $$props => { + $$self.$$set = $$props => { if ("x" in $$props) $$invalidate(0, x = $$props.x); }; diff --git a/test/js/samples/reactive-values-non-writable-dependencies/expected.js b/test/js/samples/reactive-values-non-writable-dependencies/expected.js index 38bd356d85..5196a770d9 100644 --- a/test/js/samples/reactive-values-non-writable-dependencies/expected.js +++ b/test/js/samples/reactive-values-non-writable-dependencies/expected.js @@ -5,7 +5,7 @@ function instance($$self, $$props, $$invalidate) { let { a = 1 } = $$props; let { b = 2 } = $$props; - $$self.$set = $$props => { + $$self.$$set = $$props => { if ("a" in $$props) $$invalidate(0, a = $$props.a); if ("b" in $$props) $$invalidate(1, b = $$props.b); }; diff --git a/test/js/samples/select-dynamic-value/expected.js b/test/js/samples/select-dynamic-value/expected.js index a93a47bd3a..8777cd2600 100644 --- a/test/js/samples/select-dynamic-value/expected.js +++ b/test/js/samples/select-dynamic-value/expected.js @@ -7,14 +7,14 @@ import { init, insert, noop, - safe_not_equal + safe_not_equal, + select_option } from "svelte/internal"; function create_fragment(ctx) { let select; let option0; let option1; - let select_value_value; return { c() { @@ -32,27 +32,11 @@ function create_fragment(ctx) { insert(target, select, anchor); append(select, option0); append(select, option1); - select_value_value = /*current*/ ctx[0]; - - for (var i = 0; i < select.options.length; i += 1) { - var option = select.options[i]; - - if (option.__value === select_value_value) { - option.selected = true; - break; - } - } + select_option(select, /*current*/ ctx[0]); }, p(ctx, [dirty]) { - if (dirty & /*current*/ 1 && select_value_value !== (select_value_value = /*current*/ ctx[0])) { - for (var i = 0; i < select.options.length; i += 1) { - var option = select.options[i]; - - if (option.__value === select_value_value) { - option.selected = true; - break; - } - } + if (dirty & /*current*/ 1) { + select_option(select, /*current*/ ctx[0]); } }, i: noop, @@ -66,7 +50,7 @@ function create_fragment(ctx) { function instance($$self, $$props, $$invalidate) { let { current } = $$props; - $$self.$set = $$props => { + $$self.$$set = $$props => { if ("current" in $$props) $$invalidate(0, current = $$props.current); }; diff --git a/test/js/samples/src-attribute-check/expected.js b/test/js/samples/src-attribute-check/expected.js index e03b3a6ba7..93638edfb4 100644 --- a/test/js/samples/src-attribute-check/expected.js +++ b/test/js/samples/src-attribute-check/expected.js @@ -67,7 +67,7 @@ function instance($$self, $$props, $$invalidate) { let { url } = $$props; let { slug } = $$props; - $$self.$set = $$props => { + $$self.$$set = $$props => { if ("url" in $$props) $$invalidate(0, url = $$props.url); if ("slug" in $$props) $$invalidate(1, slug = $$props.slug); }; diff --git a/test/js/samples/ssr-no-oncreate-etc/expected.js b/test/js/samples/ssr-no-oncreate-etc/expected.js index 803f06a882..b91deb3e97 100644 --- a/test/js/samples/ssr-no-oncreate-etc/expected.js +++ b/test/js/samples/ssr-no-oncreate-etc/expected.js @@ -15,7 +15,7 @@ function swipe(node, callback) { } // TODO implement -const Component = create_ssr_component(($$result, $$props, $$bindings, $$slots) => { +const Component = create_ssr_component(($$result, $$props, $$bindings, slots) => { onMount(() => { console.log("onMount"); }); diff --git a/test/js/samples/ssr-preserve-comments/expected.js b/test/js/samples/ssr-preserve-comments/expected.js index 1dc12710c0..de9fa7582e 100644 --- a/test/js/samples/ssr-preserve-comments/expected.js +++ b/test/js/samples/ssr-preserve-comments/expected.js @@ -1,7 +1,7 @@ /* generated by Svelte vX.Y.Z */ import { create_ssr_component } from "svelte/internal"; -const Component = create_ssr_component(($$result, $$props, $$bindings, $$slots) => { +const Component = create_ssr_component(($$result, $$props, $$bindings, slots) => { return `
content
more content
`; diff --git a/test/js/samples/title/expected.js b/test/js/samples/title/expected.js index d4e7e1a584..b10f569759 100644 --- a/test/js/samples/title/expected.js +++ b/test/js/samples/title/expected.js @@ -22,7 +22,7 @@ function create_fragment(ctx) { function instance($$self, $$props, $$invalidate) { let { custom } = $$props; - $$self.$set = $$props => { + $$self.$$set = $$props => { if ("custom" in $$props) $$invalidate(0, custom = $$props.custom); }; diff --git a/test/js/samples/transition-local/expected.js b/test/js/samples/transition-local/expected.js index 25a03f026f..ea3d9db3d7 100644 --- a/test/js/samples/transition-local/expected.js +++ b/test/js/samples/transition-local/expected.js @@ -124,7 +124,7 @@ function instance($$self, $$props, $$invalidate) { let { x } = $$props; let { y } = $$props; - $$self.$set = $$props => { + $$self.$$set = $$props => { if ("x" in $$props) $$invalidate(0, x = $$props.x); if ("y" in $$props) $$invalidate(1, y = $$props.y); }; diff --git a/test/js/samples/transition-repeated-outro/expected.js b/test/js/samples/transition-repeated-outro/expected.js index 1f76a93666..12483ab91a 100644 --- a/test/js/samples/transition-repeated-outro/expected.js +++ b/test/js/samples/transition-repeated-outro/expected.js @@ -102,7 +102,7 @@ function create_fragment(ctx) { function instance($$self, $$props, $$invalidate) { let { num = 1 } = $$props; - $$self.$set = $$props => { + $$self.$$set = $$props => { if ("num" in $$props) $$invalidate(0, num = $$props.num); }; diff --git a/test/js/samples/use-elements-as-anchors/expected.js b/test/js/samples/use-elements-as-anchors/expected.js index 5be8808edb..d07411518e 100644 --- a/test/js/samples/use-elements-as-anchors/expected.js +++ b/test/js/samples/use-elements-as-anchors/expected.js @@ -243,7 +243,7 @@ function instance($$self, $$props, $$invalidate) { let { d } = $$props; let { e } = $$props; - $$self.$set = $$props => { + $$self.$$set = $$props => { if ("a" in $$props) $$invalidate(0, a = $$props.a); if ("b" in $$props) $$invalidate(1, b = $$props.b); if ("c" in $$props) $$invalidate(2, c = $$props.c); diff --git a/test/js/samples/video-bindings/expected.js b/test/js/samples/video-bindings/expected.js index 9c5467e1a0..8afa670bbb 100644 --- a/test/js/samples/video-bindings/expected.js +++ b/test/js/samples/video-bindings/expected.js @@ -19,6 +19,7 @@ function create_fragment(ctx) { let video_updating = false; let video_animationframe; let video_resize_listener; + let mounted; let dispose; function video_timeupdate_handler() { @@ -38,15 +39,18 @@ function create_fragment(ctx) { if (/*videoHeight*/ ctx[1] === void 0 || /*videoWidth*/ ctx[2] === void 0) add_render_callback(() => /*video_resize_handler*/ ctx[5].call(video)); add_render_callback(() => /*video_elementresize_handler*/ ctx[6].call(video)); }, - m(target, anchor, remount) { + m(target, anchor) { insert(target, video, anchor); video_resize_listener = add_resize_listener(video, /*video_elementresize_handler*/ ctx[6].bind(video)); - if (remount) run_all(dispose); - dispose = [ - listen(video, "timeupdate", video_timeupdate_handler), - listen(video, "resize", /*video_resize_handler*/ ctx[5]) - ]; + if (!mounted) { + dispose = [ + listen(video, "timeupdate", video_timeupdate_handler), + listen(video, "resize", /*video_resize_handler*/ ctx[5]) + ]; + + mounted = true; + } }, p(ctx, [dirty]) { if (!video_updating && dirty & /*currentTime*/ 1 && !isNaN(/*currentTime*/ ctx[0])) { @@ -60,6 +64,7 @@ function create_fragment(ctx) { d(detaching) { if (detaching) detach(video); video_resize_listener(); + mounted = false; run_all(dispose); } }; @@ -88,7 +93,7 @@ function instance($$self, $$props, $$invalidate) { $$invalidate(3, offsetWidth); } - $$self.$set = $$props => { + $$self.$$set = $$props => { if ("currentTime" in $$props) $$invalidate(0, currentTime = $$props.currentTime); if ("videoHeight" in $$props) $$invalidate(1, videoHeight = $$props.videoHeight); if ("videoWidth" in $$props) $$invalidate(2, videoWidth = $$props.videoWidth); diff --git a/test/js/samples/window-binding-online/expected.js b/test/js/samples/window-binding-online/expected.js index fa955e4fd5..887195bce1 100644 --- a/test/js/samples/window-binding-online/expected.js +++ b/test/js/samples/window-binding-online/expected.js @@ -10,23 +10,27 @@ import { } from "svelte/internal"; function create_fragment(ctx) { + let mounted; let dispose; add_render_callback(/*onlinestatuschanged*/ ctx[1]); return { c: noop, - m(target, anchor, remount) { - if (remount) run_all(dispose); - - dispose = [ - listen(window, "online", /*onlinestatuschanged*/ ctx[1]), - listen(window, "offline", /*onlinestatuschanged*/ ctx[1]) - ]; + m(target, anchor) { + if (!mounted) { + dispose = [ + listen(window, "online", /*onlinestatuschanged*/ ctx[1]), + listen(window, "offline", /*onlinestatuschanged*/ ctx[1]) + ]; + + mounted = true; + } }, p: noop, i: noop, o: noop, d(detaching) { + mounted = false; run_all(dispose); } }; diff --git a/test/js/samples/window-binding-scroll/expected.js b/test/js/samples/window-binding-scroll/expected.js index 30723cc142..09a4d3737d 100644 --- a/test/js/samples/window-binding-scroll/expected.js +++ b/test/js/samples/window-binding-scroll/expected.js @@ -25,6 +25,7 @@ function create_fragment(ctx) { let p; let t0; let t1; + let mounted; let dispose; add_render_callback(/*onwindowscroll*/ ctx[1]); @@ -34,18 +35,21 @@ function create_fragment(ctx) { t0 = text("scrolled to "); t1 = text(/*y*/ ctx[0]); }, - m(target, anchor, remount) { + m(target, anchor) { insert(target, p, anchor); append(p, t0); append(p, t1); - if (remount) dispose(); - dispose = listen(window, "scroll", () => { - scrolling = true; - clearTimeout(scrolling_timeout); - scrolling_timeout = setTimeout(clear_scrolling, 100); - /*onwindowscroll*/ ctx[1](); - }); + if (!mounted) { + dispose = listen(window, "scroll", () => { + scrolling = true; + clearTimeout(scrolling_timeout); + scrolling_timeout = setTimeout(clear_scrolling, 100); + /*onwindowscroll*/ ctx[1](); + }); + + mounted = true; + } }, p(ctx, [dirty]) { if (dirty & /*y*/ 1 && !scrolling) { @@ -61,6 +65,7 @@ function create_fragment(ctx) { o: noop, d(detaching) { if (detaching) detach(p); + mounted = false; dispose(); } }; @@ -73,7 +78,7 @@ function instance($$self, $$props, $$invalidate) { $$invalidate(0, y = window.pageYOffset) } - $$self.$set = $$props => { + $$self.$$set = $$props => { if ("y" in $$props) $$invalidate(0, y = $$props.y); }; diff --git a/test/parser/index.js b/test/parser/index.js index 27c5ec1563..2c8d516a7d 100644 --- a/test/parser/index.js +++ b/test/parser/index.js @@ -20,7 +20,7 @@ describe('parse', () => { (skip ? it.skip : solo ? it.only : it)(dir, () => { const options = tryToLoadJson(`${__dirname}/samples/${dir}/options.json`) || {}; - const input = fs.readFileSync(`${__dirname}/samples/${dir}/input.svelte`, 'utf-8').replace(/\s+$/, ''); + const input = fs.readFileSync(`${__dirname}/samples/${dir}/input.svelte`, 'utf-8').replace(/\s+$/, '').replace(/\r/g, ""); const expectedOutput = tryToLoadJson(`${__dirname}/samples/${dir}/output.json`); const expectedError = tryToLoadJson(`${__dirname}/samples/${dir}/error.json`); @@ -38,13 +38,9 @@ describe('parse', () => { } catch (err) { if (err.name !== 'ParseError') throw err; if (!expectedError) throw err; - + const { code, message, pos, start } = err try { - assert.equal(err.code, expectedError.code); - assert.equal(err.message, expectedError.message); - assert.deepEqual(err.start, expectedError.start); - assert.equal(err.pos, expectedError.pos); - assert.equal(err.toString().split('\n')[0], `${expectedError.message} (${expectedError.start.line}:${expectedError.start.column})`); + assert.deepEqual({ code, message, pos, start }, expectedError); } catch (err2) { const e = err2.code === 'MODULE_NOT_FOUND' ? err : err2; throw e; diff --git a/test/parser/samples/action-with-call/output.json b/test/parser/samples/action-with-call/output.json index ccb4011c67..66c569dc5a 100644 --- a/test/parser/samples/action-with-call/output.json +++ b/test/parser/samples/action-with-call/output.json @@ -64,7 +64,8 @@ "value": "tooltip msg", "raw": "'tooltip msg'" } - ] + ], + "optional": false } } ], diff --git a/test/parser/samples/animation/output.json b/test/parser/samples/animation/output.json index 1958ba2817..11195009c8 100644 --- a/test/parser/samples/animation/output.json +++ b/test/parser/samples/animation/output.json @@ -52,10 +52,10 @@ } ], "context": { - "start": 17, - "end": 22, "type": "Identifier", - "name": "thing" + "name": "thing", + "start": 17, + "end": 22 }, "key": { "type": "Identifier", diff --git a/test/parser/samples/await-catch/output.json b/test/parser/samples/await-catch/output.json index c543583018..91862b5366 100644 --- a/test/parser/samples/await-catch/output.json +++ b/test/parser/samples/await-catch/output.json @@ -26,10 +26,10 @@ }, "value": null, "error": { - "start": 47, - "end": 55, "type": "Identifier", - "name": "theError" + "name": "theError", + "start": 47, + "end": 55 }, "pending": { "start": 19, @@ -152,7 +152,8 @@ }, "name": "message" }, - "computed": false + "computed": false, + "optional": false } } ] diff --git a/test/parser/samples/await-then-catch/output.json b/test/parser/samples/await-then-catch/output.json index 8e4b7a4c32..e377d3fa3e 100644 --- a/test/parser/samples/await-then-catch/output.json +++ b/test/parser/samples/await-then-catch/output.json @@ -25,16 +25,16 @@ "name": "thePromise" }, "value": { - "start": 46, - "end": 54, "type": "Identifier", - "name": "theValue" + "name": "theValue", + "start": 46, + "end": 54 }, "error": { - "start": 96, - "end": 104, "type": "Identifier", - "name": "theError" + "name": "theError", + "start": 96, + "end": 104 }, "pending": { "start": 19, @@ -209,7 +209,8 @@ }, "name": "message" }, - "computed": false + "computed": false, + "optional": false } } ] diff --git a/test/parser/samples/dynamic-import/output.json b/test/parser/samples/dynamic-import/output.json index 1e41252afa..ed3d58782d 100644 --- a/test/parser/samples/dynamic-import/output.json +++ b/test/parser/samples/dynamic-import/output.json @@ -275,7 +275,8 @@ }, "name": "then" }, - "computed": false + "computed": false, + "optional": false }, "arguments": [ { @@ -403,7 +404,8 @@ }, "name": "log" }, - "computed": false + "computed": false, + "optional": false }, "arguments": [ { @@ -452,21 +454,25 @@ }, "name": "default" }, - "computed": false + "computed": false, + "optional": false } - ] + ], + "optional": false } } ] } } - ] + ], + "optional": false } } ] } } - ] + ], + "optional": false } } ], diff --git a/test/parser/samples/each-block-else/output.json b/test/parser/samples/each-block-else/output.json index 2720ce5292..622789d177 100644 --- a/test/parser/samples/each-block-else/output.json +++ b/test/parser/samples/each-block-else/output.json @@ -57,10 +57,10 @@ } ], "context": { - "start": 18, - "end": 24, "type": "Identifier", - "name": "animal" + "name": "animal", + "start": 18, + "end": 24 }, "else": { "start": 50, diff --git a/test/parser/samples/each-block-indexed/output.json b/test/parser/samples/each-block-indexed/output.json index 50f2000a36..01b97ffcb4 100644 --- a/test/parser/samples/each-block-indexed/output.json +++ b/test/parser/samples/each-block-indexed/output.json @@ -85,10 +85,10 @@ } ], "context": { - "start": 18, - "end": 24, "type": "Identifier", - "name": "animal" + "name": "animal", + "start": 18, + "end": 24 }, "index": "i" } diff --git a/test/parser/samples/each-block-keyed/output.json b/test/parser/samples/each-block-keyed/output.json index 7dc8681453..6eaf19a82d 100644 --- a/test/parser/samples/each-block-keyed/output.json +++ b/test/parser/samples/each-block-keyed/output.json @@ -57,10 +57,10 @@ } ], "context": { - "start": 16, - "end": 20, "type": "Identifier", - "name": "todo" + "name": "todo", + "start": 16, + "end": 20 }, "key": { "type": "MemberExpression", @@ -108,7 +108,8 @@ }, "name": "id" }, - "computed": false + "computed": false, + "optional": false } } ] diff --git a/test/parser/samples/each-block/output.json b/test/parser/samples/each-block/output.json index 6594fb50a6..82d4455d19 100644 --- a/test/parser/samples/each-block/output.json +++ b/test/parser/samples/each-block/output.json @@ -57,10 +57,10 @@ } ], "context": { - "start": 18, - "end": 24, "type": "Identifier", - "name": "animal" + "name": "animal", + "start": 18, + "end": 24 } } ] diff --git a/test/parser/samples/error-css-global-without-selector/error.json b/test/parser/samples/error-css-global-without-selector/error.json new file mode 100644 index 0000000000..f4237c65d3 --- /dev/null +++ b/test/parser/samples/error-css-global-without-selector/error.json @@ -0,0 +1,10 @@ +{ + "code": "css-syntax-error", + "message": ":global() must contain a selector", + "start": { + "line": 2, + "column": 1, + "character": 9 + }, + "pos": 9 +} diff --git a/test/parser/samples/error-css-global-without-selector/input.svelte b/test/parser/samples/error-css-global-without-selector/input.svelte new file mode 100644 index 0000000000..a626136cfc --- /dev/null +++ b/test/parser/samples/error-css-global-without-selector/input.svelte @@ -0,0 +1,3 @@ + diff --git a/test/parser/samples/error-unmatched-closing-tag-autoclose-2/error.json b/test/parser/samples/error-unmatched-closing-tag-autoclose-2/error.json new file mode 100644 index 0000000000..d24296bd96 --- /dev/null +++ b/test/parser/samples/error-unmatched-closing-tag-autoclose-2/error.json @@ -0,0 +1,10 @@ +{ + "code": "invalid-closing-tag", + "message": "

attempted to close an element that was not open", + "pos": 38, + "start": { + "character": 38, + "column": 0, + "line": 5 + } +} diff --git a/test/parser/samples/error-unmatched-closing-tag-autoclose-2/input.svelte b/test/parser/samples/error-unmatched-closing-tag-autoclose-2/input.svelte new file mode 100644 index 0000000000..5182577921 --- /dev/null +++ b/test/parser/samples/error-unmatched-closing-tag-autoclose-2/input.svelte @@ -0,0 +1,5 @@ +
+

+

pre tag
+
+

\ No newline at end of file diff --git a/test/parser/samples/error-unmatched-closing-tag-autoclose/error.json b/test/parser/samples/error-unmatched-closing-tag-autoclose/error.json new file mode 100644 index 0000000000..e6532d747e --- /dev/null +++ b/test/parser/samples/error-unmatched-closing-tag-autoclose/error.json @@ -0,0 +1,10 @@ +{ + "code": "invalid-closing-tag", + "message": "

attempted to close

that was already automatically closed by

",
+	"pos": 24,
+	"start": {
+		"character": 24,
+		"column": 0,
+		"line": 3
+	}
+}
diff --git a/test/parser/samples/error-unmatched-closing-tag-autoclose/input.svelte b/test/parser/samples/error-unmatched-closing-tag-autoclose/input.svelte
new file mode 100644
index 0000000000..0bfd609736
--- /dev/null
+++ b/test/parser/samples/error-unmatched-closing-tag-autoclose/input.svelte
@@ -0,0 +1,3 @@
+

+

pre tag
+

\ 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 index 708128a42e..f22586b267 100644 --- a/test/parser/samples/no-error-if-before-closing/output.json +++ b/test/parser/samples/no-error-if-before-closing/output.json @@ -116,10 +116,10 @@ "raw": "true" }, "value": { - "start": 97, - "end": 98, "type": "Identifier", - "name": "f" + "name": "f", + "start": 97, + "end": 98 }, "error": null, "pending": { @@ -204,10 +204,10 @@ "raw": "true" }, "value": { - "start": 137, - "end": 138, "type": "Identifier", - "name": "f" + "name": "f", + "start": 137, + "end": 138 }, "error": null, "pending": { diff --git a/test/parser/samples/unusual-identifier/output.json b/test/parser/samples/unusual-identifier/output.json index 76cc82cfd6..3d209d35fe 100644 --- a/test/parser/samples/unusual-identifier/output.json +++ b/test/parser/samples/unusual-identifier/output.json @@ -57,10 +57,10 @@ } ], "context": { - "start": 17, - "end": 19, "type": "Identifier", - "name": "𐊧" + "name": "𐊧", + "start": 17, + "end": 19 } } ] diff --git a/test/preprocess/samples/comments/_config.js b/test/preprocess/samples/comments/_config.js index 4416d121d0..fdec377567 100644 --- a/test/preprocess/samples/comments/_config.js +++ b/test/preprocess/samples/comments/_config.js @@ -2,7 +2,7 @@ export default { preprocess: [ { script: ({ content }) => ({ code: content.replace(/one/g, 'two') }), - style: ({ content }) => ({ code: content.replace(/one/g, 'three') }), - }, - ], + style: ({ content }) => ({ code: content.replace(/one/g, 'three') }) + } + ] }; diff --git a/test/preprocess/samples/script-self-closing/_config.js b/test/preprocess/samples/script-self-closing/_config.js new file mode 100644 index 0000000000..4baab9730e --- /dev/null +++ b/test/preprocess/samples/script-self-closing/_config.js @@ -0,0 +1,12 @@ +import * as assert from "assert"; + +export default { + preprocess: { + script: ({ content, attributes }) => { + assert.equal(content, ""); + return { + code: `console.log("${attributes["the-answer"]}");` + }; + } + } +}; diff --git a/test/preprocess/samples/script-self-closing/input.svelte b/test/preprocess/samples/script-self-closing/input.svelte new file mode 100644 index 0000000000..c5816cb3ba --- /dev/null +++ b/test/preprocess/samples/script-self-closing/input.svelte @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/preprocess/samples/style-self-closing/_config.js b/test/preprocess/samples/style-self-closing/_config.js new file mode 100644 index 0000000000..0a05cd3d64 --- /dev/null +++ b/test/preprocess/samples/style-self-closing/_config.js @@ -0,0 +1,12 @@ +import * as assert from "assert"; + +export default { + preprocess: { + style: ({ content, attributes: { color } }) => { + assert.equal(content, ""); + return { + code: `div { color: ${color}; }` + }; + } + } +}; diff --git a/test/preprocess/samples/style-self-closing/input.svelte b/test/preprocess/samples/style-self-closing/input.svelte new file mode 100644 index 0000000000..07176c87e5 --- /dev/null +++ b/test/preprocess/samples/style-self-closing/input.svelte @@ -0,0 +1,3 @@ +
$brand
+ + \ No newline at end of file diff --git a/test/runtime/index.js b/test/runtime/index.js index f070eb8185..65157196c9 100644 --- a/test/runtime/index.js +++ b/test/runtime/index.js @@ -39,7 +39,7 @@ describe("runtime", () => { filename }, compileOptions); - const { js: { code } } = compile(fs.readFileSync(filename, "utf-8"), options); + const { js: { code } } = compile(fs.readFileSync(filename, "utf-8").replace(/\r/g, ""), options); return module._compile(code, filename); }; @@ -103,7 +103,7 @@ describe("runtime", () => { try { const { js } = compile( - fs.readFileSync(`${cwd}/${file}`, 'utf-8'), + fs.readFileSync(`${cwd}/${file}`, 'utf-8').replace(/\r/g, ""), { ...compileOptions, filename: file diff --git a/test/runtime/samples/$$rest-without-props/_config.js b/test/runtime/samples/$$rest-without-props/_config.js index 017f9df561..1fb8e85a6a 100644 --- a/test/runtime/samples/$$rest-without-props/_config.js +++ b/test/runtime/samples/$$rest-without-props/_config.js @@ -11,7 +11,7 @@ export default {
`, - async test({ assert, target, window, }) { + async test({ assert, target, window }) { const [btn1, btn2, btn3, btn4] = target.querySelectorAll('button'); const clickEvent = new window.MouseEvent('click'); diff --git a/test/runtime/samples/$$rest/_config.js b/test/runtime/samples/$$rest/_config.js index 255927f354..f00c26d712 100644 --- a/test/runtime/samples/$$rest/_config.js +++ b/test/runtime/samples/$$rest/_config.js @@ -13,7 +13,7 @@ export default { `, - async test({ assert, target, window, }) { + async test({ assert, target, window }) { const [btn1, btn2, btn3, btn4] = target.querySelectorAll('button'); const clickEvent = new window.MouseEvent('click'); diff --git a/test/runtime/samples/$$slot/A.svelte b/test/runtime/samples/$$slot/A.svelte new file mode 100644 index 0000000000..ffa166166c --- /dev/null +++ b/test/runtime/samples/$$slot/A.svelte @@ -0,0 +1,31 @@ + + + + + +$$slots: {toString($$slots)} + +{#if $$slots.b} +
+ +
+{:else} + Slot b is not available +{/if} \ No newline at end of file diff --git a/test/runtime/samples/$$slot/_config.js b/test/runtime/samples/$$slot/_config.js new file mode 100644 index 0000000000..13b2137cdb --- /dev/null +++ b/test/runtime/samples/$$slot/_config.js @@ -0,0 +1,18 @@ +export default { + html: ` + byeworld + hello world + $$slots: {"a":true,"default":true} + Slot b is not available + + bye world + hello world + $$slots: {"a":true,"b":true,"default":true} +
hello world
+ `, + + async test({ assert, target, component }) { + assert.equal(component.getA(), ''); + assert.equal(component.getB(), 'foo'); + } +}; diff --git a/test/runtime/samples/$$slot/main.svelte b/test/runtime/samples/$$slot/main.svelte new file mode 100644 index 0000000000..8b7efae573 --- /dev/null +++ b/test/runtime/samples/$$slot/main.svelte @@ -0,0 +1,23 @@ + + + + hello world + bye + world + + + + hello world + hello world + bye world + diff --git a/test/runtime/samples/action-custom-event-handler-this/_config.js b/test/runtime/samples/action-custom-event-handler-this/_config.js index 88a30232ab..754f813c7f 100644 --- a/test/runtime/samples/action-custom-event-handler-this/_config.js +++ b/test/runtime/samples/action-custom-event-handler-this/_config.js @@ -18,5 +18,5 @@ export default { input.dispatchEvent(event); assert.ok(blurred); - }, + } }; diff --git a/test/runtime/samples/action-ternary-template/_config.js b/test/runtime/samples/action-ternary-template/_config.js index adf23a9f68..ecb18dceec 100644 --- a/test/runtime/samples/action-ternary-template/_config.js +++ b/test/runtime/samples/action-ternary-template/_config.js @@ -1,7 +1,7 @@ export default { props: { target: 'World!', - display: true, + display: true }, html: ` @@ -16,5 +16,5 @@ export default { assert.htmlEqual(target.innerHTML, `

Hello World!

`); - }, + } }; diff --git a/test/runtime/samples/action-this/_config.js b/test/runtime/samples/action-this/_config.js index de7f834cdc..c59ff3b634 100644 --- a/test/runtime/samples/action-this/_config.js +++ b/test/runtime/samples/action-this/_config.js @@ -7,5 +7,5 @@ export default { await button.dispatchEvent(click); await Promise.resolve(); assert.htmlEqual(target.innerHTML, ``); - }, + } }; diff --git a/test/runtime/samples/apply-directives-in-order-2/_config.js b/test/runtime/samples/apply-directives-in-order-2/_config.js index a74ce41cb6..caff97a5b9 100644 --- a/test/runtime/samples/apply-directives-in-order-2/_config.js +++ b/test/runtime/samples/apply-directives-in-order-2/_config.js @@ -1,7 +1,7 @@ const value = []; export default { props: { - value, + value }, async test({ assert, component, target, window }) { @@ -32,7 +32,7 @@ export default { '15', '16', '17', - '18', + '18' ]); - }, + } }; diff --git a/test/runtime/samples/apply-directives-in-order/_config.js b/test/runtime/samples/apply-directives-in-order/_config.js index e5e8980ed1..7c8f87ef85 100644 --- a/test/runtime/samples/apply-directives-in-order/_config.js +++ b/test/runtime/samples/apply-directives-in-order/_config.js @@ -33,5 +33,5 @@ export default {

HE

`); - }, + } }; diff --git a/test/runtime/samples/attribute-boolean-false/_config.js b/test/runtime/samples/attribute-boolean-false/_config.js index 14fdeb9fdc..e47c5e7df1 100644 --- a/test/runtime/samples/attribute-boolean-false/_config.js +++ b/test/runtime/samples/attribute-boolean-false/_config.js @@ -3,5 +3,5 @@ export default { test({ assert, component, target }) { const textarea = target.querySelector('textarea'); assert.ok(textarea.readOnly === false); - }, + } }; diff --git a/test/runtime/samples/attribute-boolean-true/_config.js b/test/runtime/samples/attribute-boolean-true/_config.js index 0e402ed1e3..1f77e33027 100644 --- a/test/runtime/samples/attribute-boolean-true/_config.js +++ b/test/runtime/samples/attribute-boolean-true/_config.js @@ -3,5 +3,5 @@ export default { test({ assert, component, target }) { const textarea = target.querySelector('textarea'); assert.ok(textarea.readOnly); - }, + } }; diff --git a/test/runtime/samples/attribute-dataset-without-value/_config.js b/test/runtime/samples/attribute-dataset-without-value/_config.js index 934f44eb06..21e60b92aa 100644 --- a/test/runtime/samples/attribute-dataset-without-value/_config.js +++ b/test/runtime/samples/attribute-dataset-without-value/_config.js @@ -1,3 +1,3 @@ export default { - html: '
', + html: '
' }; diff --git a/test/runtime/samples/attribute-dynamic-no-dependencies/_config.js b/test/runtime/samples/attribute-dynamic-no-dependencies/_config.js index acf3c64bdd..f1088830af 100644 --- a/test/runtime/samples/attribute-dynamic-no-dependencies/_config.js +++ b/test/runtime/samples/attribute-dynamic-no-dependencies/_config.js @@ -1,5 +1,5 @@ export default { html: `
bar
- `, + ` }; diff --git a/test/runtime/samples/attribute-false/_config.js b/test/runtime/samples/attribute-false/_config.js index 9fd08a2a48..632d4ac1c2 100644 --- a/test/runtime/samples/attribute-false/_config.js +++ b/test/runtime/samples/attribute-false/_config.js @@ -1,3 +1,3 @@ export default { - html: `
`, + html: `
` }; diff --git a/test/runtime/samples/attribute-null-classnames-no-style/_config.js b/test/runtime/samples/attribute-null-classnames-no-style/_config.js index 917cf565c0..e90d81a60f 100644 --- a/test/runtime/samples/attribute-null-classnames-no-style/_config.js +++ b/test/runtime/samples/attribute-null-classnames-no-style/_config.js @@ -1,7 +1,7 @@ export default { props: { testName1: "test1", - testName2: "test2", + testName2: "test2" }, html: `
`, diff --git a/test/runtime/samples/attribute-null-classnames-with-style/_config.js b/test/runtime/samples/attribute-null-classnames-with-style/_config.js index 5762f628fb..20e6d4c7be 100644 --- a/test/runtime/samples/attribute-null-classnames-with-style/_config.js +++ b/test/runtime/samples/attribute-null-classnames-with-style/_config.js @@ -1,7 +1,7 @@ export default { props: { testName1: "test1", - testName2: "test2", + testName2: "test2" }, html: `
`, diff --git a/test/runtime/samples/attribute-null-func-classnames-no-style/_config.js b/test/runtime/samples/attribute-null-func-classnames-no-style/_config.js index 917cf565c0..e90d81a60f 100644 --- a/test/runtime/samples/attribute-null-func-classnames-no-style/_config.js +++ b/test/runtime/samples/attribute-null-func-classnames-no-style/_config.js @@ -1,7 +1,7 @@ export default { props: { testName1: "test1", - testName2: "test2", + testName2: "test2" }, html: `
`, diff --git a/test/runtime/samples/attribute-null-func-classnames-with-style/_config.js b/test/runtime/samples/attribute-null-func-classnames-with-style/_config.js index 5762f628fb..20e6d4c7be 100644 --- a/test/runtime/samples/attribute-null-func-classnames-with-style/_config.js +++ b/test/runtime/samples/attribute-null-func-classnames-with-style/_config.js @@ -1,7 +1,7 @@ export default { props: { testName1: "test1", - testName2: "test2", + testName2: "test2" }, html: `
`, diff --git a/test/runtime/samples/attribute-null/_config.js b/test/runtime/samples/attribute-null/_config.js index ae2f0a8af6..36955050a0 100644 --- a/test/runtime/samples/attribute-null/_config.js +++ b/test/runtime/samples/attribute-null/_config.js @@ -1,3 +1,3 @@ export default { - html: `
`, + html: `
` }; diff --git a/test/runtime/samples/attribute-prefer-expression/_config.js b/test/runtime/samples/attribute-prefer-expression/_config.js index 29fcbc7f13..2388ff35df 100644 --- a/test/runtime/samples/attribute-prefer-expression/_config.js +++ b/test/runtime/samples/attribute-prefer-expression/_config.js @@ -2,7 +2,7 @@ export default { skip_if_ssr: true, props: { - foo: false, + foo: false }, test({ assert, component, target }) { @@ -15,5 +15,5 @@ export default { assert.ok(!inputs[0].checked); assert.ok(inputs[1].checked); - }, + } }; diff --git a/test/runtime/samples/attribute-undefined/_config.js b/test/runtime/samples/attribute-undefined/_config.js index ae2f0a8af6..36955050a0 100644 --- a/test/runtime/samples/attribute-undefined/_config.js +++ b/test/runtime/samples/attribute-undefined/_config.js @@ -1,3 +1,3 @@ export default { - html: `
`, + html: `
` }; diff --git a/test/runtime/samples/await-with-update-2/Component.svelte b/test/runtime/samples/await-with-update-2/Component.svelte new file mode 100644 index 0000000000..1301db3f99 --- /dev/null +++ b/test/runtime/samples/await-with-update-2/Component.svelte @@ -0,0 +1,7 @@ + + +
count: {count}
+
value: {value}
\ No newline at end of file diff --git a/test/runtime/samples/await-with-update-2/_config.js b/test/runtime/samples/await-with-update-2/_config.js new file mode 100644 index 0000000000..613f2b3255 --- /dev/null +++ b/test/runtime/samples/await-with-update-2/_config.js @@ -0,0 +1,64 @@ +export default { + props: { + thePromise: new Promise((_) => {}), + count: 0 + }, + + html: ` +

loading...

+ `, + + async test({ assert, component, target }) { + await (component.thePromise = Promise.resolve({ value: "success", Component: component.Component })); + + assert.htmlEqual( + target.innerHTML, + ` +
Resolved: +
count: 0
+
value: success
+
+ ` + ); + + component.count = 5; + + assert.htmlEqual( + target.innerHTML, + ` +
Resolved: +
count: 5
+
value: success
+
+ ` + ); + + try { + await (component.thePromise = Promise.reject({ value: "failure", Component: component.Component })); + } catch (error) { + // ignore + } + + assert.htmlEqual( + target.innerHTML, + ` +
Rejected: +
count: 5
+
value: failure
+
+ ` + ); + + component.count = 10; + + assert.htmlEqual( + target.innerHTML, + ` +
Rejected: +
count: 10
+
value: failure
+
+ ` + ); + } +}; diff --git a/test/runtime/samples/await-with-update-2/main.svelte b/test/runtime/samples/await-with-update-2/main.svelte new file mode 100644 index 0000000000..b29c875f92 --- /dev/null +++ b/test/runtime/samples/await-with-update-2/main.svelte @@ -0,0 +1,16 @@ + + +
+ {#await thePromise} +

loading...

+ {:then { value: theValue, Component }} + Resolved: + {:catch { value: theError, Component } } + Rejected: + {/await} +
\ No newline at end of file diff --git a/test/runtime/samples/await-with-update/Component.svelte b/test/runtime/samples/await-with-update/Component.svelte new file mode 100644 index 0000000000..5f13c80e65 --- /dev/null +++ b/test/runtime/samples/await-with-update/Component.svelte @@ -0,0 +1,5 @@ + + +
count: {count}
\ No newline at end of file diff --git a/test/runtime/samples/await-with-update/_config.js b/test/runtime/samples/await-with-update/_config.js new file mode 100644 index 0000000000..08bf12b89e --- /dev/null +++ b/test/runtime/samples/await-with-update/_config.js @@ -0,0 +1,60 @@ +export default { + props: { + thePromise: new Promise((_) => {}), + count: 0 + }, + + html: ` +

loading...

+ `, + + async test({ assert, component, target }) { + await (component.thePromise = Promise.resolve(component.Component)); + + assert.htmlEqual( + target.innerHTML, + ` +
Resolved: +
count: 0
+
+ ` + ); + + component.count = 5; + + assert.htmlEqual( + target.innerHTML, + ` +
Resolved: +
count: 5
+
+ ` + ); + + try { + await (component.thePromise = Promise.reject(component.Component)); + } catch (error) { + // ignore + } + + assert.htmlEqual( + target.innerHTML, + ` +
Rejected: +
count: 5
+
+ ` + ); + + component.count = 10; + + assert.htmlEqual( + target.innerHTML, + ` +
Rejected: +
count: 10
+
+ ` + ); + } +}; diff --git a/test/runtime/samples/await-with-update/main.svelte b/test/runtime/samples/await-with-update/main.svelte new file mode 100644 index 0000000000..51c5b76a21 --- /dev/null +++ b/test/runtime/samples/await-with-update/main.svelte @@ -0,0 +1,16 @@ + + +
+ {#await thePromise} +

loading...

+ {:then theValue} + Resolved: + {:catch theError} + Rejected: + {/await} +
\ No newline at end of file diff --git a/test/runtime/samples/await-without-catch/_config.js b/test/runtime/samples/await-without-catch/_config.js new file mode 100644 index 0000000000..2030ed7949 --- /dev/null +++ b/test/runtime/samples/await-without-catch/_config.js @@ -0,0 +1,44 @@ +let fulfil; + +let promise = new Promise(f => { + fulfil = f; +}); + +export default { + props: { + promise + }, + + html: ` +

loading...

+ `, + + test({ assert, component, target }) { + fulfil(42); + + return promise + .then(() => { + assert.htmlEqual(target.innerHTML, ` +

loaded

+ `); + + let reject; + + promise = new Promise((f, r) => { + reject = r; + }); + + component.promise = promise; + + assert.htmlEqual(target.innerHTML, ` +

loading...

+ `); + + reject(new Error('this error should be thrown')); + return promise; + }) + .catch((err) => { + assert.equal(err.message, 'this error should be thrown'); + }); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/await-without-catch/main.svelte b/test/runtime/samples/await-without-catch/main.svelte new file mode 100644 index 0000000000..f528a8bf69 --- /dev/null +++ b/test/runtime/samples/await-without-catch/main.svelte @@ -0,0 +1,9 @@ + + +{#await promise} +

loading...

+{:then value} +

loaded

+{/await} \ No newline at end of file diff --git a/test/runtime/samples/binding-contenteditable-html-initial/_config.js b/test/runtime/samples/binding-contenteditable-html-initial/_config.js index 9eac2c9b17..4c30a3231a 100644 --- a/test/runtime/samples/binding-contenteditable-html-initial/_config.js +++ b/test/runtime/samples/binding-contenteditable-html-initial/_config.js @@ -36,5 +36,5 @@ export default { goodbye

hello goodbye

`); - }, + } }; diff --git a/test/runtime/samples/binding-contenteditable-html/_config.js b/test/runtime/samples/binding-contenteditable-html/_config.js index ceb6a75c70..639572faea 100644 --- a/test/runtime/samples/binding-contenteditable-html/_config.js +++ b/test/runtime/samples/binding-contenteditable-html/_config.js @@ -1,6 +1,6 @@ export default { props: { - name: 'world', + name: 'world' }, html: ` @@ -34,5 +34,5 @@ export default { goodbye

hello goodbye

`); - }, + } }; diff --git a/test/runtime/samples/binding-contenteditable-text-initial/_config.js b/test/runtime/samples/binding-contenteditable-text-initial/_config.js index 4899f30f12..d5f331bb7a 100644 --- a/test/runtime/samples/binding-contenteditable-text-initial/_config.js +++ b/test/runtime/samples/binding-contenteditable-text-initial/_config.js @@ -30,5 +30,5 @@ export default { goodbye

hello goodbye

`); - }, + } }; diff --git a/test/runtime/samples/binding-contenteditable-text/_config.js b/test/runtime/samples/binding-contenteditable-text/_config.js index 9f8645724d..89f3968258 100644 --- a/test/runtime/samples/binding-contenteditable-text/_config.js +++ b/test/runtime/samples/binding-contenteditable-text/_config.js @@ -1,6 +1,6 @@ export default { props: { - name: 'world', + name: 'world' }, html: ` @@ -28,5 +28,5 @@ export default { goodbye

hello goodbye

`); - }, + } }; diff --git a/test/runtime/samples/binding-input-checkbox-indeterminate/_config.js b/test/runtime/samples/binding-input-checkbox-indeterminate/_config.js index 2e3a1c296f..9d099feb0a 100644 --- a/test/runtime/samples/binding-input-checkbox-indeterminate/_config.js +++ b/test/runtime/samples/binding-input-checkbox-indeterminate/_config.js @@ -2,7 +2,7 @@ export default { skip_if_ssr: true, props: { - indeterminate: true, + indeterminate: true }, html: ` @@ -38,5 +38,5 @@ export default {

checked? true

indeterminate? true

`); - }, + } }; diff --git a/test/runtime/samples/binding-input-checkbox-with-event-in-each/_config.js b/test/runtime/samples/binding-input-checkbox-with-event-in-each/_config.js index b502ed40af..9e6f915dd0 100644 --- a/test/runtime/samples/binding-input-checkbox-with-event-in-each/_config.js +++ b/test/runtime/samples/binding-input-checkbox-with-event-in-each/_config.js @@ -3,13 +3,13 @@ export default { cats: [ { name: "cat 0", - checked: false, + checked: false }, { name: "cat 1", - checked: false, - }, - ], + checked: false + } + ] }, html: ` @@ -22,7 +22,7 @@ export default { const newCats = cats.slice(); newCats.push({ name: "cat " + cats.length, - checked: false, + checked: false }); component.cats = newCats; diff --git a/test/runtime/samples/binding-input-group-duplicate-value/_config.js b/test/runtime/samples/binding-input-group-duplicate-value/_config.js new file mode 100644 index 0000000000..7f50ad6dce --- /dev/null +++ b/test/runtime/samples/binding-input-group-duplicate-value/_config.js @@ -0,0 +1,81 @@ +export default { + html: ` +

Checked:

+ +
+ + a
+ b
+ c
+ d
+ +
+ + a
+ b
+ c
+ d
+ `, + + async test({ assert, component, target, window }) { + const inputs = target.querySelectorAll("input"); + const p = target.querySelector("p"); + + assert.equal(inputs[0].checked, false); + assert.equal(inputs[1].checked, false); + assert.equal(inputs[2].checked, false); + assert.equal(inputs[3].checked, false); + + assert.equal(inputs[4].checked, false); + assert.equal(inputs[5].checked, false); + assert.equal(inputs[6].checked, false); + assert.equal(inputs[7].checked, false); + + const event = new window.Event("change"); + + inputs[0].checked = true; + await inputs[0].dispatchEvent(event); + + assert.htmlEqual(p.innerHTML, `Checked: a`); + + assert.equal(inputs[0].checked, true); + assert.equal(inputs[1].checked, false); + assert.equal(inputs[2].checked, false); + assert.equal(inputs[3].checked, false); + + assert.equal(inputs[4].checked, true); + assert.equal(inputs[5].checked, false); + assert.equal(inputs[6].checked, false); + assert.equal(inputs[7].checked, false); + + inputs[3].checked = true; + await inputs[3].dispatchEvent(event); + + assert.htmlEqual(p.innerHTML, `Checked: a,d`); + + assert.equal(inputs[0].checked, true); + assert.equal(inputs[1].checked, false); + assert.equal(inputs[2].checked, false); + assert.equal(inputs[3].checked, true); + + assert.equal(inputs[4].checked, true); + assert.equal(inputs[5].checked, false); + assert.equal(inputs[6].checked, false); + assert.equal(inputs[7].checked, true); + + inputs[4].checked = false; + await inputs[4].dispatchEvent(event); + + assert.htmlEqual(p.innerHTML, `Checked: d`); + + assert.equal(inputs[0].checked, false); + assert.equal(inputs[1].checked, false); + assert.equal(inputs[2].checked, false); + assert.equal(inputs[3].checked, true); + + assert.equal(inputs[4].checked, false); + assert.equal(inputs[5].checked, false); + assert.equal(inputs[6].checked, false); + assert.equal(inputs[7].checked, true); + } +}; diff --git a/test/runtime/samples/binding-input-group-duplicate-value/main.svelte b/test/runtime/samples/binding-input-group-duplicate-value/main.svelte new file mode 100644 index 0000000000..153e559d23 --- /dev/null +++ b/test/runtime/samples/binding-input-group-duplicate-value/main.svelte @@ -0,0 +1,19 @@ + + +

Checked: {foo}

+ +
+ +a
+b
+c
+d
+ +
+ +a
+b
+c
+d
\ No newline at end of file diff --git a/test/runtime/samples/binding-input-group-each-1/_config.js b/test/runtime/samples/binding-input-group-each-1/_config.js new file mode 100644 index 0000000000..92010296dc --- /dev/null +++ b/test/runtime/samples/binding-input-group-each-1/_config.js @@ -0,0 +1,275 @@ +const values = [ + { name: 'Alpha' }, + { name: 'Beta' }, + { name: 'Gamma' } +]; + +const selected_array = [ + [values[1]], + [], + [values[2]] +]; + +export default { + props: { + values, + selected_array + }, + + html: ` +
+ + + + + + +

Beta

+
+
+ + + + + + +

+
+
+ + + + + + +

Gamma

+
+ `, + + async test({ assert, component, target, window }) { + const inputs = target.querySelectorAll('input'); + assert.equal(inputs[0].checked, false); + assert.equal(inputs[1].checked, true); + assert.equal(inputs[2].checked, false); + assert.equal(inputs[3].checked, false); + assert.equal(inputs[4].checked, false); + assert.equal(inputs[5].checked, false); + assert.equal(inputs[6].checked, false); + assert.equal(inputs[7].checked, false); + assert.equal(inputs[8].checked, true); + + const event = new window.Event('change'); + + inputs[0].checked = true; + await inputs[0].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` +
+ + + + + + +

Alpha, Beta

+
+
+ + + + + + +

+
+
+ + + + + + +

Gamma

+
+ `); + inputs[3].checked = true; + await inputs[3].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` +
+ + + + + + +

Alpha, Beta

+
+
+ + + + + + +

Alpha

+
+
+ + + + + + +

Gamma

+
+ `); + + inputs[8].checked = false; + await inputs[8].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` +
+ + + + + + +

Alpha, Beta

+
+
+ + + + + + +

Alpha

+
+
+ + + + + + +

+
+ `); + + component.selected_array = [[values[1], values[2]], [values[2]]]; + + assert.equal(inputs[0].checked, false); + assert.equal(inputs[1].checked, true); + assert.equal(inputs[2].checked, true); + assert.equal(inputs[3].checked, false); + assert.equal(inputs[4].checked, false); + assert.equal(inputs[5].checked, true); + + assert.htmlEqual(target.innerHTML, ` +
+ + + + + + +

Beta, Gamma

+
+
+ + + + + + +

Gamma

+
+ `); + } +}; diff --git a/test/runtime/samples/binding-input-group-each-1/main.svelte b/test/runtime/samples/binding-input-group-each-1/main.svelte new file mode 100644 index 0000000000..5ed255c83a --- /dev/null +++ b/test/runtime/samples/binding-input-group-each-1/main.svelte @@ -0,0 +1,15 @@ + + +{#each selected_array as selected} +
+ {#each values as value} + + {/each} +

{selected.map(v => v.name).join(', ')}

+
+{/each} diff --git a/test/runtime/samples/binding-input-group-each-2/_config.js b/test/runtime/samples/binding-input-group-each-2/_config.js new file mode 100644 index 0000000000..78d692d979 --- /dev/null +++ b/test/runtime/samples/binding-input-group-each-2/_config.js @@ -0,0 +1,59 @@ +export default { + html: ` + + + + +

1, 2, 3

`, + + async test({ assert, component, target, window }) { + const inputs = target.querySelectorAll('input'); + assert.equal(inputs[0].checked, true); + assert.equal(inputs[1].checked, true); + assert.equal(inputs[2].checked, true); + + const event = new window.Event('change'); + + inputs[0].checked = false; + await inputs[0].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` + + + + +

2, 3

+ `); + + component.selected = [[1, 3]]; + assert.equal(inputs[0].checked, true); + assert.equal(inputs[1].checked, false); + assert.equal(inputs[2].checked, true); + + assert.htmlEqual(target.innerHTML, ` + + + + +

1, 3

+ `); + } +}; diff --git a/test/runtime/samples/binding-input-group-each-2/main.svelte b/test/runtime/samples/binding-input-group-each-2/main.svelte new file mode 100644 index 0000000000..46f7e9e698 --- /dev/null +++ b/test/runtime/samples/binding-input-group-each-2/main.svelte @@ -0,0 +1,17 @@ + + +{#each options as value} + +{/each} + +

{selected[0].join(', ')}

\ No newline at end of file diff --git a/test/runtime/samples/binding-input-group-each-3/_config.js b/test/runtime/samples/binding-input-group-each-3/_config.js new file mode 100644 index 0000000000..92010296dc --- /dev/null +++ b/test/runtime/samples/binding-input-group-each-3/_config.js @@ -0,0 +1,275 @@ +const values = [ + { name: 'Alpha' }, + { name: 'Beta' }, + { name: 'Gamma' } +]; + +const selected_array = [ + [values[1]], + [], + [values[2]] +]; + +export default { + props: { + values, + selected_array + }, + + html: ` +
+ + + + + + +

Beta

+
+
+ + + + + + +

+
+
+ + + + + + +

Gamma

+
+ `, + + async test({ assert, component, target, window }) { + const inputs = target.querySelectorAll('input'); + assert.equal(inputs[0].checked, false); + assert.equal(inputs[1].checked, true); + assert.equal(inputs[2].checked, false); + assert.equal(inputs[3].checked, false); + assert.equal(inputs[4].checked, false); + assert.equal(inputs[5].checked, false); + assert.equal(inputs[6].checked, false); + assert.equal(inputs[7].checked, false); + assert.equal(inputs[8].checked, true); + + const event = new window.Event('change'); + + inputs[0].checked = true; + await inputs[0].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` +
+ + + + + + +

Alpha, Beta

+
+
+ + + + + + +

+
+
+ + + + + + +

Gamma

+
+ `); + inputs[3].checked = true; + await inputs[3].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` +
+ + + + + + +

Alpha, Beta

+
+
+ + + + + + +

Alpha

+
+
+ + + + + + +

Gamma

+
+ `); + + inputs[8].checked = false; + await inputs[8].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` +
+ + + + + + +

Alpha, Beta

+
+
+ + + + + + +

Alpha

+
+
+ + + + + + +

+
+ `); + + component.selected_array = [[values[1], values[2]], [values[2]]]; + + assert.equal(inputs[0].checked, false); + assert.equal(inputs[1].checked, true); + assert.equal(inputs[2].checked, true); + assert.equal(inputs[3].checked, false); + assert.equal(inputs[4].checked, false); + assert.equal(inputs[5].checked, true); + + assert.htmlEqual(target.innerHTML, ` +
+ + + + + + +

Beta, Gamma

+
+
+ + + + + + +

Gamma

+
+ `); + } +}; diff --git a/test/runtime/samples/binding-input-group-each-3/main.svelte b/test/runtime/samples/binding-input-group-each-3/main.svelte new file mode 100644 index 0000000000..42a7a1c4e9 --- /dev/null +++ b/test/runtime/samples/binding-input-group-each-3/main.svelte @@ -0,0 +1,15 @@ + + +{#each selected_array as _, index} +
+ {#each values as value} + + {/each} +

{selected_array[index].map(v => v.name).join(', ')}

+
+{/each} diff --git a/test/runtime/samples/binding-input-group-each-4/_config.js b/test/runtime/samples/binding-input-group-each-4/_config.js new file mode 100644 index 0000000000..f1168858b0 --- /dev/null +++ b/test/runtime/samples/binding-input-group-each-4/_config.js @@ -0,0 +1,153 @@ +export default { + html: ` + + + +

1

+ + + +

2

+ + + +

+ + + +

3

+ `, + + async test({ assert, component, target, window }) { + const inputs = target.querySelectorAll('input'); + assert.equal(inputs[0].checked, true); + assert.equal(inputs[1].checked, false); + assert.equal(inputs[2].checked, false); + + assert.equal(inputs[3].checked, false); + assert.equal(inputs[4].checked, true); + assert.equal(inputs[5].checked, false); + + assert.equal(inputs[6].checked, false); + assert.equal(inputs[7].checked, false); + assert.equal(inputs[8].checked, false); + + assert.equal(inputs[9].checked, false); + assert.equal(inputs[10].checked, false); + assert.equal(inputs[11].checked, true); + + const event = new window.Event('change'); + + inputs[2].checked = true; + await inputs[2].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` + + + +

1, 3

+ + + +

2

+ + + +

+ + + +

3

+ `); + + inputs[9].checked = true; + await inputs[9].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` + + + +

1, 3

+ + + +

2

+ + + +

+ + + +

1, 3

+ `); + + inputs[4].checked = false; + await inputs[4].dispatchEvent(event); + inputs[5].checked = true; + await inputs[5].dispatchEvent(event); + inputs[6].checked = true; + await inputs[6].dispatchEvent(event); + inputs[7].checked = true; + await inputs[7].dispatchEvent(event); + inputs[11].checked = false; + await inputs[11].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` + + + +

1, 3

+ + + +

3

+ + + +

1, 2

+ + + +

1

+ `); + + component.selected_array_1 = [[3], [1]]; + component.selected_array_2 = [[], [2]]; + + assert.equal(inputs[0].checked, false); + assert.equal(inputs[1].checked, false); + assert.equal(inputs[2].checked, true); + + assert.equal(inputs[3].checked, true); + assert.equal(inputs[4].checked, false); + assert.equal(inputs[5].checked, false); + + assert.equal(inputs[6].checked, false); + assert.equal(inputs[7].checked, false); + assert.equal(inputs[8].checked, false); + + assert.equal(inputs[9].checked, false); + assert.equal(inputs[10].checked, true); + assert.equal(inputs[11].checked, false); + + assert.htmlEqual(target.innerHTML, ` + + + +

3

+ + + +

1

+ + + +

+ + + +

2

+ `); + } +}; diff --git a/test/runtime/samples/binding-input-group-each-4/main.svelte b/test/runtime/samples/binding-input-group-each-4/main.svelte new file mode 100644 index 0000000000..0bbf5ea763 --- /dev/null +++ b/test/runtime/samples/binding-input-group-each-4/main.svelte @@ -0,0 +1,33 @@ + + +{#each selected_array_1 as selected} + {#each options as value} + + {/each} +

{selected.join(', ')}

+{/each} + +{#each selected_array_2 as selected} + {#each options as value} + + {/each} +

{selected.join(', ')}

+{/each} \ No newline at end of file diff --git a/test/runtime/samples/binding-input-group-each-5/_config.js b/test/runtime/samples/binding-input-group-each-5/_config.js new file mode 100644 index 0000000000..579225c627 --- /dev/null +++ b/test/runtime/samples/binding-input-group-each-5/_config.js @@ -0,0 +1,160 @@ +export default { + html: ` + + + +

1

+ + + +

1, 2, 3

+ + + +

2

+ + + +

1

+ `, + + async test({ assert, component, target, window }) { + const inputs = target.querySelectorAll('input'); + assert.equal(inputs[0].checked, true); + assert.equal(inputs[1].checked, false); + assert.equal(inputs[2].checked, false); + + assert.equal(inputs[3].checked, true); + assert.equal(inputs[4].checked, true); + assert.equal(inputs[5].checked, true); + + assert.equal(inputs[6].checked, false); + assert.equal(inputs[7].checked, true); + assert.equal(inputs[8].checked, false); + + assert.equal(inputs[9].checked, true); + assert.equal(inputs[10].checked, false); + assert.equal(inputs[11].checked, false); + + const event = new window.Event('change'); + + inputs[2].checked = true; + await inputs[2].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` + + + +

1, 3

+ + + +

1, 2, 3

+ + + +

2

+ + + +

1

+ `); + + inputs[8].checked = true; + await inputs[8].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` + + + +

1, 3

+ + + +

1, 2, 3

+ + + +

2, 3

+ + + +

1

+ `); + + component.selected_index = [1, 1]; + + assert.htmlEqual(target.innerHTML, ` + + + +

1, 2, 3

+ + + +

1, 2, 3

+ + + +

1

+ + + +

1

+ `); + + assert.equal(inputs[0].checked, true); + assert.equal(inputs[1].checked, true); + assert.equal(inputs[2].checked, true); + + assert.equal(inputs[3].checked, true); + assert.equal(inputs[4].checked, true); + assert.equal(inputs[5].checked, true); + + assert.equal(inputs[6].checked, true); + assert.equal(inputs[7].checked, false); + assert.equal(inputs[8].checked, false); + + assert.equal(inputs[9].checked, true); + assert.equal(inputs[10].checked, false); + assert.equal(inputs[11].checked, false); + + inputs[5].checked = false; + await inputs[5].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` + + + +

1, 2

+ + + +

1, 2

+ + + +

1

+ + + +

1

+ `); + + assert.equal(inputs[0].checked, true); + assert.equal(inputs[1].checked, true); + assert.equal(inputs[2].checked, false); + + assert.equal(inputs[3].checked, true); + assert.equal(inputs[4].checked, true); + assert.equal(inputs[5].checked, false); + + assert.equal(inputs[6].checked, true); + assert.equal(inputs[7].checked, false); + assert.equal(inputs[8].checked, false); + + assert.equal(inputs[9].checked, true); + assert.equal(inputs[10].checked, false); + assert.equal(inputs[11].checked, false); + } +}; diff --git a/test/runtime/samples/binding-input-group-each-5/main.svelte b/test/runtime/samples/binding-input-group-each-5/main.svelte new file mode 100644 index 0000000000..93bdce6510 --- /dev/null +++ b/test/runtime/samples/binding-input-group-each-5/main.svelte @@ -0,0 +1,24 @@ + + +{#each selected_array as selected} + {#each selected_index as index} + {#each options as value} + + {/each} +

{selected[index].join(', ')}

+ {/each} +{/each} diff --git a/test/runtime/samples/binding-input-group-each-6/_config.js b/test/runtime/samples/binding-input-group-each-6/_config.js new file mode 100644 index 0000000000..9eb251bf5d --- /dev/null +++ b/test/runtime/samples/binding-input-group-each-6/_config.js @@ -0,0 +1,87 @@ +export default { + html: ` + + + +

+ + + +

+ + + +

+ `, + + async test({ assert, component, target, window }) { + const inputs = target.querySelectorAll('input'); + assert.equal(inputs[0].checked, false); + assert.equal(inputs[1].checked, false); + assert.equal(inputs[2].checked, false); + + assert.equal(inputs[3].checked, false); + assert.equal(inputs[4].checked, false); + assert.equal(inputs[5].checked, false); + + assert.equal(inputs[6].checked, false); + assert.equal(inputs[7].checked, false); + assert.equal(inputs[8].checked, false); + + const event = new window.Event('change'); + + inputs[2].checked = true; + await inputs[2].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` + + + +

z

+ + + +

+ + + +

+ `); + + inputs[4].checked = true; + await inputs[4].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` + + + +

z

+ + + +

y

+ + + +

+ `); + + inputs[5].checked = true; + await inputs[5].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` + + + +

z

+ + + +

y, z

+ + + +

+ `); + } +}; diff --git a/test/runtime/samples/binding-input-group-each-6/main.svelte b/test/runtime/samples/binding-input-group-each-6/main.svelte new file mode 100644 index 0000000000..85be939e8a --- /dev/null +++ b/test/runtime/samples/binding-input-group-each-6/main.svelte @@ -0,0 +1,22 @@ + + +{#each Object.keys(list) as key} + {#each values as value} + + {/each} +

{list[key].join(', ')}

+{/each} diff --git a/test/runtime/samples/binding-input-number-2/_config.js b/test/runtime/samples/binding-input-number-2/_config.js index a3510eb757..5daf50fd04 100644 --- a/test/runtime/samples/binding-input-number-2/_config.js +++ b/test/runtime/samples/binding-input-number-2/_config.js @@ -27,5 +27,5 @@ export default { component.value = 1; assert.equal(component.value, 1); assert.equal(input.value, "1"); - }, + } }; diff --git a/test/runtime/samples/binding-input-number/_config.js b/test/runtime/samples/binding-input-number/_config.js index 869b9f9896..3c5919bc64 100644 --- a/test/runtime/samples/binding-input-number/_config.js +++ b/test/runtime/samples/binding-input-number/_config.js @@ -1,6 +1,6 @@ export default { props: { - count: 42, + count: 42 }, html: ` @@ -44,5 +44,5 @@ export default {

undefined undefined

`); - }, + } }; diff --git a/test/runtime/samples/binding-input-range-change-with-max/_config.js b/test/runtime/samples/binding-input-range-change-with-max/_config.js index 1fda90d83c..dc3cf4ce28 100644 --- a/test/runtime/samples/binding-input-range-change-with-max/_config.js +++ b/test/runtime/samples/binding-input-range-change-with-max/_config.js @@ -29,5 +29,5 @@ export default {

20 of 20

`); - }, + } }; diff --git a/test/runtime/samples/binding-input-range-change/_config.js b/test/runtime/samples/binding-input-range-change/_config.js index 62e9562770..f6ec2d9c53 100644 --- a/test/runtime/samples/binding-input-range-change/_config.js +++ b/test/runtime/samples/binding-input-range-change/_config.js @@ -1,6 +1,6 @@ export default { props: { - count: 42, + count: 42 }, html: ` @@ -34,5 +34,5 @@ export default {

number 44

`); - }, + } }; diff --git a/test/runtime/samples/binding-input-range/_config.js b/test/runtime/samples/binding-input-range/_config.js index 4c3d37a667..dc6178e088 100644 --- a/test/runtime/samples/binding-input-range/_config.js +++ b/test/runtime/samples/binding-input-range/_config.js @@ -1,6 +1,6 @@ export default { props: { - count: 42, + count: 42 }, html: ` @@ -34,5 +34,5 @@ export default {

number 44

`); - }, + } }; diff --git a/test/runtime/samples/binding-input-text-contextual-deconflicted/_config.js b/test/runtime/samples/binding-input-text-contextual-deconflicted/_config.js index 28cffdfa57..de4d6325b0 100644 --- a/test/runtime/samples/binding-input-text-contextual-deconflicted/_config.js +++ b/test/runtime/samples/binding-input-text-contextual-deconflicted/_config.js @@ -1,7 +1,7 @@ export default { props: { foo: 'a', - items: ['x'], + items: ['x'] }, html: ` @@ -32,5 +32,5 @@ export default {

b

y

`); - }, + } }; diff --git a/test/runtime/samples/binding-input-text-contextual-reactive/_config.js b/test/runtime/samples/binding-input-text-contextual-reactive/_config.js index 6fdfc4be52..a1584c18b8 100644 --- a/test/runtime/samples/binding-input-text-contextual-reactive/_config.js +++ b/test/runtime/samples/binding-input-text-contextual-reactive/_config.js @@ -121,5 +121,5 @@ export default {

done:one / done:two / remaining:four

`); - }, + } }; diff --git a/test/runtime/samples/binding-input-text-contextual/_config.js b/test/runtime/samples/binding-input-text-contextual/_config.js index bb7f16c8bb..1c66ea7ff5 100644 --- a/test/runtime/samples/binding-input-text-contextual/_config.js +++ b/test/runtime/samples/binding-input-text-contextual/_config.js @@ -1,6 +1,6 @@ export default { props: { - items: ['one', 'two', 'three'], + items: ['one', 'two', 'three'] }, html: ` @@ -65,5 +65,5 @@ export default {

five

`); - }, + } }; diff --git a/test/runtime/samples/binding-input-text-deconflicted/_config.js b/test/runtime/samples/binding-input-text-deconflicted/_config.js index 46fe3e2a38..48a7d2590a 100644 --- a/test/runtime/samples/binding-input-text-deconflicted/_config.js +++ b/test/runtime/samples/binding-input-text-deconflicted/_config.js @@ -1,8 +1,8 @@ export default { props: { component: { - name: 'world', - }, + name: 'world' + } }, html: ` @@ -36,5 +36,5 @@ export default {

Hello goodbye!

`); - }, + } }; diff --git a/test/runtime/samples/binding-input-text-deep-computed-dynamic/_config.js b/test/runtime/samples/binding-input-text-deep-computed-dynamic/_config.js index eeecdb0ef8..0afbb9d952 100644 --- a/test/runtime/samples/binding-input-text-deep-computed-dynamic/_config.js +++ b/test/runtime/samples/binding-input-text-deep-computed-dynamic/_config.js @@ -4,8 +4,8 @@ export default { obj: { foo: 'a', bar: 'b', - baz: 'c', - }, + baz: 'c' + } }, html: ` @@ -56,5 +56,5 @@ export default {
{"foo":"d","bar":"e","baz":"f"}
`); - }, + } }; diff --git a/test/runtime/samples/binding-input-text-deep-computed/_config.js b/test/runtime/samples/binding-input-text-deep-computed/_config.js index a1ea2c34ad..3a85d50d76 100644 --- a/test/runtime/samples/binding-input-text-deep-computed/_config.js +++ b/test/runtime/samples/binding-input-text-deep-computed/_config.js @@ -2,8 +2,8 @@ export default { props: { prop: 'name', user: { - name: 'alice', - }, + name: 'alice' + } }, html: ` @@ -40,5 +40,5 @@ export default {

hello carol

`); - }, + } }; diff --git a/test/runtime/samples/binding-input-text-deep-contextual-computed-dynamic/_config.js b/test/runtime/samples/binding-input-text-deep-contextual-computed-dynamic/_config.js index 364195233d..627ef5f15e 100644 --- a/test/runtime/samples/binding-input-text-deep-contextual-computed-dynamic/_config.js +++ b/test/runtime/samples/binding-input-text-deep-contextual-computed-dynamic/_config.js @@ -5,9 +5,9 @@ export default { { foo: 'a', bar: 'b', - baz: 'c', - }, - ], + baz: 'c' + } + ] }, html: ` @@ -58,5 +58,5 @@ export default {
{"foo":"d","bar":"e","baz":"f"}
`); - }, + } }; diff --git a/test/runtime/samples/binding-input-text-deep-contextual/_config.js b/test/runtime/samples/binding-input-text-deep-contextual/_config.js index 5b6b0d6577..cc80d38042 100644 --- a/test/runtime/samples/binding-input-text-deep-contextual/_config.js +++ b/test/runtime/samples/binding-input-text-deep-contextual/_config.js @@ -3,8 +3,8 @@ export default { items: [ { description: 'one' }, { description: 'two' }, - { description: 'three' }, - ], + { description: 'three' } + ] }, html: ` @@ -45,5 +45,5 @@ export default {

four

five

`); - }, + } }; diff --git a/test/runtime/samples/binding-input-text-deep/_config.js b/test/runtime/samples/binding-input-text-deep/_config.js index e6113510a7..35443e9073 100644 --- a/test/runtime/samples/binding-input-text-deep/_config.js +++ b/test/runtime/samples/binding-input-text-deep/_config.js @@ -1,8 +1,8 @@ export default { props: { user: { - name: 'alice', - }, + name: 'alice' + } }, html: ` @@ -39,5 +39,5 @@ export default {

hello carol

`); - }, + } }; diff --git a/test/runtime/samples/binding-input-text-undefined/_config.js b/test/runtime/samples/binding-input-text-undefined/_config.js index 009e1b37ba..fa59b1f796 100644 --- a/test/runtime/samples/binding-input-text-undefined/_config.js +++ b/test/runtime/samples/binding-input-text-undefined/_config.js @@ -26,5 +26,5 @@ export default { component.x = undefined; assert.equal(input.value, ''); - }, + } }; diff --git a/test/runtime/samples/binding-input-text/_config.js b/test/runtime/samples/binding-input-text/_config.js index e7162b6153..52d8e44902 100644 --- a/test/runtime/samples/binding-input-text/_config.js +++ b/test/runtime/samples/binding-input-text/_config.js @@ -1,6 +1,6 @@ export default { props: { - name: 'world', + name: 'world' }, html: ` @@ -33,5 +33,5 @@ export default {

hello goodbye

`); - }, + } }; diff --git a/test/runtime/samples/binding-select-initial-value/_config.js b/test/runtime/samples/binding-select-initial-value/_config.js index d98e5d2e1c..d34a987fa5 100644 --- a/test/runtime/samples/binding-select-initial-value/_config.js +++ b/test/runtime/samples/binding-select-initial-value/_config.js @@ -24,7 +24,7 @@ export default { `, props: { - selected: 'b', + selected: 'b' }, test({ assert, component, target }) { @@ -33,5 +33,5 @@ export default { assert.equal(select.value, 'b'); assert.ok(options[1].selected); - }, + } }; diff --git a/test/runtime/samples/binding-select-late-2/_config.js b/test/runtime/samples/binding-select-late-2/_config.js new file mode 100644 index 0000000000..42c45d1366 --- /dev/null +++ b/test/runtime/samples/binding-select-late-2/_config.js @@ -0,0 +1,34 @@ +export default { + props: { + items: [], + selected: 'two' + }, + + html: ` + +

selected: two

+ `, + + ssrHtml: ` + +

selected: two

+ `, + + test({ assert, component, target }) { + component.items = [ 'one', 'two', 'three' ]; + + const options = target.querySelectorAll('option'); + assert.ok(!options[0].selected); + assert.ok(options[1].selected); + assert.ok(!options[2].selected); + + assert.htmlEqual(target.innerHTML, ` + +

selected: two

+ `); + } +}; diff --git a/test/runtime/samples/binding-select-late-2/main.svelte b/test/runtime/samples/binding-select-late-2/main.svelte new file mode 100644 index 0000000000..52cc14528a --- /dev/null +++ b/test/runtime/samples/binding-select-late-2/main.svelte @@ -0,0 +1,12 @@ + + + + +

selected: {selected || 'nothing'}

\ No newline at end of file diff --git a/test/runtime/samples/binding-select-late-3/_config.js b/test/runtime/samples/binding-select-late-3/_config.js new file mode 100644 index 0000000000..42c45d1366 --- /dev/null +++ b/test/runtime/samples/binding-select-late-3/_config.js @@ -0,0 +1,34 @@ +export default { + props: { + items: [], + selected: 'two' + }, + + html: ` + +

selected: two

+ `, + + ssrHtml: ` + +

selected: two

+ `, + + test({ assert, component, target }) { + component.items = [ 'one', 'two', 'three' ]; + + const options = target.querySelectorAll('option'); + assert.ok(!options[0].selected); + assert.ok(options[1].selected); + assert.ok(!options[2].selected); + + assert.htmlEqual(target.innerHTML, ` + +

selected: two

+ `); + } +}; diff --git a/test/runtime/samples/binding-select-late-3/main.svelte b/test/runtime/samples/binding-select-late-3/main.svelte new file mode 100644 index 0000000000..ec9ac8d345 --- /dev/null +++ b/test/runtime/samples/binding-select-late-3/main.svelte @@ -0,0 +1,12 @@ + + + + +

selected: {selected || 'nothing'}

\ No newline at end of file diff --git a/test/runtime/samples/binding-select-optgroup/_config.js b/test/runtime/samples/binding-select-optgroup/_config.js index e8a1d40797..03ad3e3280 100644 --- a/test/runtime/samples/binding-select-optgroup/_config.js +++ b/test/runtime/samples/binding-select-optgroup/_config.js @@ -45,5 +45,5 @@ export default { `); - }, + } }; diff --git a/test/runtime/samples/binding-select/_config.js b/test/runtime/samples/binding-select/_config.js index a5995061a0..310315176b 100644 --- a/test/runtime/samples/binding-select/_config.js +++ b/test/runtime/samples/binding-select/_config.js @@ -24,7 +24,7 @@ export default { `, props: { - selected: 'one', + selected: 'one' }, async test({ assert, component, target, window }) { @@ -53,5 +53,5 @@ export default { `); component.selected = 'three'; - }, + } }; diff --git a/test/runtime/samples/binding-store-deep/_config.js b/test/runtime/samples/binding-store-deep/_config.js index 8bdd41818b..c0f4f63578 100644 --- a/test/runtime/samples/binding-store-deep/_config.js +++ b/test/runtime/samples/binding-store-deep/_config.js @@ -37,5 +37,5 @@ export default { assert.deepEqual(names, ['world', 'everybody', 'goodbye']); unsubscribe(); - }, + } }; diff --git a/test/runtime/samples/binding-store/_config.js b/test/runtime/samples/binding-store/_config.js index eb22d3e96c..6e7a70878a 100644 --- a/test/runtime/samples/binding-store/_config.js +++ b/test/runtime/samples/binding-store/_config.js @@ -37,5 +37,5 @@ export default { assert.deepEqual(names, ['world', 'everybody', 'goodbye']); unsubscribe(); - }, + } }; diff --git a/test/runtime/samples/binding-textarea/_config.js b/test/runtime/samples/binding-textarea/_config.js index ac092096e6..70646e5e4b 100644 --- a/test/runtime/samples/binding-textarea/_config.js +++ b/test/runtime/samples/binding-textarea/_config.js @@ -1,6 +1,6 @@ export default { props: { - value: 'some text', + value: 'some text' }, html: ` @@ -33,5 +33,5 @@ export default {

goodbye

`); - }, + } }; diff --git a/test/runtime/samples/binding-this-each-block-property-2/_config.js b/test/runtime/samples/binding-this-each-block-property-2/_config.js new file mode 100644 index 0000000000..5c288cd6d1 --- /dev/null +++ b/test/runtime/samples/binding-this-each-block-property-2/_config.js @@ -0,0 +1,53 @@ +let calls = []; +function callback(refs) { + calls.push(refs.map(({ ref }) => ({ ref }))); +} +export default { + html: ``, + props: { + callback + }, + after_test() { + calls = []; + }, + async test({ assert, component, target }) { + assert.equal(calls.length, 1); + assert.equal(calls[0].length, 0); + + await component.addItem(); + + let divs = target.querySelectorAll("div"); + + assert.equal(calls.length, 3); + assert.equal(calls[1].length, 1); + assert.equal(calls[1][0].ref, null); + assert.equal(calls[2].length, 1); + assert.equal(calls[2][0].ref, divs[0]); + + await component.addItem(); + + divs = target.querySelectorAll("div"); + + assert.equal(calls.length, 5); + assert.equal(calls[3].length, 2); + assert.equal(calls[3][0].ref, divs[0]); + assert.equal(calls[3][1].ref, null); + assert.equal(calls[4].length, 2); + assert.equal(calls[4][0].ref, divs[0]); + assert.equal(calls[4][1].ref, divs[1]); + + await component.addItem(); + + divs = target.querySelectorAll("div"); + + assert.equal(calls.length, 7); + assert.equal(calls[5].length, 3); + assert.equal(calls[5][0].ref, divs[0]); + assert.equal(calls[5][1].ref, divs[1]); + assert.equal(calls[5][2].ref, null); + assert.equal(calls[6].length, 3); + assert.equal(calls[6][0].ref, divs[0]); + assert.equal(calls[6][1].ref, divs[1]); + assert.equal(calls[6][2].ref, divs[2]); + } +}; diff --git a/test/runtime/samples/binding-this-each-block-property-2/main.svelte b/test/runtime/samples/binding-this-each-block-property-2/main.svelte new file mode 100644 index 0000000000..bc1efe725c --- /dev/null +++ b/test/runtime/samples/binding-this-each-block-property-2/main.svelte @@ -0,0 +1,17 @@ + + +{#each refs as xxx} +
+{/each} \ No newline at end of file diff --git a/test/runtime/samples/bitmask-overflow-2/_config.js b/test/runtime/samples/bitmask-overflow-2/_config.js index 0b63791292..7304f6fa68 100644 --- a/test/runtime/samples/bitmask-overflow-2/_config.js +++ b/test/runtime/samples/bitmask-overflow-2/_config.js @@ -1,3 +1,3 @@ export default { - error: `potato is not defined`, + error: `potato is not defined` }; \ No newline at end of file diff --git a/test/runtime/samples/bitmask-overflow-3/_config.js b/test/runtime/samples/bitmask-overflow-3/_config.js index aee7d3237e..a55a73af1d 100644 --- a/test/runtime/samples/bitmask-overflow-3/_config.js +++ b/test/runtime/samples/bitmask-overflow-3/_config.js @@ -1,3 +1,3 @@ export default { - error: `A is not defined`, + error: `A is not defined` }; \ No newline at end of file diff --git a/test/runtime/samples/bitmask-overflow-slot-2/_config.js b/test/runtime/samples/bitmask-overflow-slot-2/_config.js index b01bd81e00..08c0c2f902 100644 --- a/test/runtime/samples/bitmask-overflow-slot-2/_config.js +++ b/test/runtime/samples/bitmask-overflow-slot-2/_config.js @@ -90,7 +90,7 @@ export default { assert.deepEqual(component.reads, { _0: 2, - _1: 2, + _1: 2 }); } }; \ No newline at end of file diff --git a/test/runtime/samples/class-with-spread-and-bind/_config.js b/test/runtime/samples/class-with-spread-and-bind/_config.js index f3c54e8c52..cab46706ef 100644 --- a/test/runtime/samples/class-with-spread-and-bind/_config.js +++ b/test/runtime/samples/class-with-spread-and-bind/_config.js @@ -1,6 +1,6 @@ export default { props: { - primary: true, + primary: true }, html: `
`, @@ -14,5 +14,5 @@ export default {
` ); - }, + } }; diff --git a/test/runtime/samples/component-binding-deep/_config.js b/test/runtime/samples/component-binding-deep/_config.js index be5a2624ac..8a2f5a56cf 100644 --- a/test/runtime/samples/component-binding-deep/_config.js +++ b/test/runtime/samples/component-binding-deep/_config.js @@ -21,5 +21,5 @@ export default {

blah

`); - }, + } }; diff --git a/test/runtime/samples/component-binding-store/Input.svelte b/test/runtime/samples/component-binding-store/Input.svelte new file mode 100644 index 0000000000..792104bec8 --- /dev/null +++ b/test/runtime/samples/component-binding-store/Input.svelte @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/test/runtime/samples/component-binding-store/_config.js b/test/runtime/samples/component-binding-store/_config.js new file mode 100644 index 0000000000..8b8a7a170a --- /dev/null +++ b/test/runtime/samples/component-binding-store/_config.js @@ -0,0 +1,61 @@ +export default { + html: ` + + +
+ `, + + async test({ assert, component, target, window }) { + let count = 0; + component.callback = () => { + count++; + }; + + const [input1, input2] = target.querySelectorAll("input"); + + input1.value = "1"; + await input1.dispatchEvent(new window.Event("input")); + + assert.htmlEqual( + target.innerHTML, + ` + + +
1
+ ` + ); + assert.equal(input1.value, "1"); + assert.equal(input2.value, "1"); + assert.equal(count, 1); + + input2.value = "123"; + await input2.dispatchEvent(new window.Event("input")); + + assert.htmlEqual( + target.innerHTML, + ` + + +
123
+ ` + ); + assert.equal(input1.value, "123"); + assert.equal(input2.value, "123"); + assert.equal(count, 2); + + input1.value = "456"; + await input1.dispatchEvent(new window.Event("input")); + + assert.htmlEqual( + target.innerHTML, + ` + + +
456
+ ` + ); + assert.equal(input1.value, "456"); + assert.equal(input2.value, "456"); + assert.equal(count, 3); + } +}; diff --git a/test/runtime/samples/component-binding-store/main.svelte b/test/runtime/samples/component-binding-store/main.svelte new file mode 100644 index 0000000000..dba08e5276 --- /dev/null +++ b/test/runtime/samples/component-binding-store/main.svelte @@ -0,0 +1,18 @@ + + + + + + +
{$value.value}
\ No newline at end of file diff --git a/test/runtime/samples/component-event-handler-contenteditable/_config.js b/test/runtime/samples/component-event-handler-contenteditable/_config.js new file mode 100644 index 0000000000..3a85734975 --- /dev/null +++ b/test/runtime/samples/component-event-handler-contenteditable/_config.js @@ -0,0 +1,15 @@ +export default { + html: ` +
+ `, + + async test({ assert, component, target, window }) { + const div = target.querySelector('div'); + const text = window.document.createTextNode('a'); + div.insertBefore(text, null); + const event = new window.InputEvent('input'); + await div.dispatchEvent(event); + + assert.equal(div.textContent, 'a'); + } +}; diff --git a/test/runtime/samples/component-event-handler-contenteditable/main.svelte b/test/runtime/samples/component-event-handler-contenteditable/main.svelte new file mode 100644 index 0000000000..1eb5911df8 --- /dev/null +++ b/test/runtime/samples/component-event-handler-contenteditable/main.svelte @@ -0,0 +1,6 @@ + + +
{text}
diff --git a/test/runtime/samples/component-event-not-stale/_config.js b/test/runtime/samples/component-event-not-stale/_config.js index 912ea1f7d0..7951afb9d5 100644 --- a/test/runtime/samples/component-event-not-stale/_config.js +++ b/test/runtime/samples/component-event-not-stale/_config.js @@ -1,6 +1,6 @@ export default { props: { - value: 1, + value: 1 }, test({ assert, component, target, window }) { @@ -26,5 +26,5 @@ export default { { value: 2 }, { value: 2 } ]); - }, + } }; diff --git a/test/runtime/samples/component-events-console/_config.js b/test/runtime/samples/component-events-console/_config.js index b800749785..39ccbd719f 100644 --- a/test/runtime/samples/component-events-console/_config.js +++ b/test/runtime/samples/component-events-console/_config.js @@ -21,5 +21,5 @@ export default { } console.log = log; - }, + } }; diff --git a/test/runtime/samples/component-namespace/Tooltip.svelte b/test/runtime/samples/component-namespace/Tooltip.svelte new file mode 100644 index 0000000000..9b44ef57a8 --- /dev/null +++ b/test/runtime/samples/component-namespace/Tooltip.svelte @@ -0,0 +1 @@ +

i am a widget

\ No newline at end of file diff --git a/test/runtime/samples/component-namespace/Widget.svelte b/test/runtime/samples/component-namespace/Widget.svelte new file mode 100644 index 0000000000..b6aa45c6a8 --- /dev/null +++ b/test/runtime/samples/component-namespace/Widget.svelte @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/test/runtime/samples/component-namespace/_config.js b/test/runtime/samples/component-namespace/_config.js new file mode 100644 index 0000000000..5b96ac8df0 --- /dev/null +++ b/test/runtime/samples/component-namespace/_config.js @@ -0,0 +1,3 @@ +export default { + html: '

i am a widget

' +}; diff --git a/test/runtime/samples/component-namespace/main.svelte b/test/runtime/samples/component-namespace/main.svelte new file mode 100644 index 0000000000..3f53b2b1c8 --- /dev/null +++ b/test/runtime/samples/component-namespace/main.svelte @@ -0,0 +1,8 @@ + + +{#each widgets as LazyWidget} + +{/each} \ No newline at end of file diff --git a/test/runtime/samples/component-shorthand-import/_config.js b/test/runtime/samples/component-shorthand-import/_config.js index ceb8e19f68..c955224600 100644 --- a/test/runtime/samples/component-shorthand-import/_config.js +++ b/test/runtime/samples/component-shorthand-import/_config.js @@ -1,3 +1,3 @@ export default { - html: `

This is the widget.

`, + html: `

This is the widget.

` }; diff --git a/test/runtime/samples/component-slot-fallback-3/_config.js b/test/runtime/samples/component-slot-fallback-3/_config.js index b5591fb5e0..25cc65eb2d 100644 --- a/test/runtime/samples/component-slot-fallback-3/_config.js +++ b/test/runtime/samples/component-slot-fallback-3/_config.js @@ -2,5 +2,5 @@ export default { html: `
Hello World
Hello
world
Bye
World
- `, + ` }; diff --git a/test/runtime/samples/component-slot-fallback-4/_config.js b/test/runtime/samples/component-slot-fallback-4/_config.js index b7c2b63ed6..4ebe353513 100644 --- a/test/runtime/samples/component-slot-fallback-4/_config.js +++ b/test/runtime/samples/component-slot-fallback-4/_config.js @@ -1,5 +1,5 @@ export default { html: ` foobar - `, + ` }; diff --git a/test/runtime/samples/component-slot-let-in-slot/_config.js b/test/runtime/samples/component-slot-let-in-slot/_config.js index a86d869581..eb16c27fda 100644 --- a/test/runtime/samples/component-slot-let-in-slot/_config.js +++ b/test/runtime/samples/component-slot-let-in-slot/_config.js @@ -1,6 +1,6 @@ export default { props: { - prop: 'a', + prop: 'a' }, html: 'a', diff --git a/test/runtime/samples/component-slot-nested-if/_config.js b/test/runtime/samples/component-slot-nested-if/_config.js index 89dfd006cc..45c570fc22 100644 --- a/test/runtime/samples/component-slot-nested-if/_config.js +++ b/test/runtime/samples/component-slot-nested-if/_config.js @@ -26,5 +26,5 @@ export default { Display: abc ` ); - }, + } }; diff --git a/test/runtime/samples/deconflict-builtins-2/_config.js b/test/runtime/samples/deconflict-builtins-2/_config.js index 5870ff073b..1489f83dc4 100644 --- a/test/runtime/samples/deconflict-builtins-2/_config.js +++ b/test/runtime/samples/deconflict-builtins-2/_config.js @@ -1,4 +1,4 @@ export default { html: `hello world`, - preserveIdentifiers: true, + preserveIdentifiers: true }; \ No newline at end of file diff --git a/test/runtime/samples/dev-warning-missing-data-each/_config.js b/test/runtime/samples/dev-warning-missing-data-each/_config.js index 92cda48fce..7d7794eff4 100644 --- a/test/runtime/samples/dev-warning-missing-data-each/_config.js +++ b/test/runtime/samples/dev-warning-missing-data-each/_config.js @@ -7,18 +7,18 @@ export default { letters: [ { id: 1, - char: 'a', + char: 'a' }, { id: 2, - char: 'b', + char: 'b' }, { id: 3, - char: 'c', - }, - ], + char: 'c' + } + ] }, - warnings: [], + warnings: [] }; diff --git a/test/runtime/samples/document-event/_config.js b/test/runtime/samples/document-event/_config.js index f5e4b46f4f..d9a8866275 100644 --- a/test/runtime/samples/document-event/_config.js +++ b/test/runtime/samples/document-event/_config.js @@ -9,5 +9,5 @@ export default { const event2 = new window.Event('mouseleave'); window.document.body.dispatchEvent(event2); assert.deepEqual(component.events, ['enter', 'leave']); - }, + } }; diff --git a/test/runtime/samples/each-block-array-literal/_config.js b/test/runtime/samples/each-block-array-literal/_config.js index 288d1cd09f..164e4730bc 100644 --- a/test/runtime/samples/each-block-array-literal/_config.js +++ b/test/runtime/samples/each-block-array-literal/_config.js @@ -15,5 +15,5 @@ export default { button.dispatchEvent(event); assert.equal(component.clicked, 'racoon'); - }, + } }; diff --git a/test/runtime/samples/each-block-destructured-array-sparse/_config.js b/test/runtime/samples/each-block-destructured-array-sparse/_config.js index 9805276600..331c3aec1b 100644 --- a/test/runtime/samples/each-block-destructured-array-sparse/_config.js +++ b/test/runtime/samples/each-block-destructured-array-sparse/_config.js @@ -16,5 +16,5 @@ export default { assert.htmlEqual( target.innerHTML, `

bar

`); - }, + } }; diff --git a/test/runtime/samples/each-block-destructured-array/_config.js b/test/runtime/samples/each-block-destructured-array/_config.js index 432d8a3a78..e2924c8656 100644 --- a/test/runtime/samples/each-block-destructured-array/_config.js +++ b/test/runtime/samples/each-block-destructured-array/_config.js @@ -16,5 +16,5 @@ export default { assert.htmlEqual( target.innerHTML, `

foo: bar

`); - }, + } }; diff --git a/test/runtime/samples/each-block-destructured-default/_config.js b/test/runtime/samples/each-block-destructured-default/_config.js index 133fd68532..0e99fd589f 100644 --- a/test/runtime/samples/each-block-destructured-default/_config.js +++ b/test/runtime/samples/each-block-destructured-default/_config.js @@ -18,5 +18,5 @@ export default { assert.htmlEqual(target.innerHTML, `

cow - ‎B. taurus - 50kg

`); - }, + } }; diff --git a/test/runtime/samples/each-block-destructured-object-binding/_config.js b/test/runtime/samples/each-block-destructured-object-binding/_config.js index 8b59a97034..2ab3e24397 100644 --- a/test/runtime/samples/each-block-destructured-object-binding/_config.js +++ b/test/runtime/samples/each-block-destructured-object-binding/_config.js @@ -1,6 +1,6 @@ export default { props: { - people: [{ name: { first: 'Doctor', last: 'Who' } }], + people: [{ name: { first: 'Doctor', last: 'Who' } }] }, html: ` @@ -41,5 +41,5 @@ export default {

Frank Oz

`); - }, + } }; diff --git a/test/runtime/samples/each-block-destructured-object-rest/_config.js b/test/runtime/samples/each-block-destructured-object-rest/_config.js index 561d4e8442..be5d38b555 100644 --- a/test/runtime/samples/each-block-destructured-object-rest/_config.js +++ b/test/runtime/samples/each-block-destructured-object-rest/_config.js @@ -16,5 +16,5 @@ export default { assert.htmlEqual(target.innerHTML, `

cow

`); - }, + } }; diff --git a/test/runtime/samples/each-block-destructured-object/_config.js b/test/runtime/samples/each-block-destructured-object/_config.js index dc3943fffe..feec72f402 100644 --- a/test/runtime/samples/each-block-destructured-object/_config.js +++ b/test/runtime/samples/each-block-destructured-object/_config.js @@ -16,5 +16,5 @@ export default { assert.htmlEqual( target.innerHTML, `

cow: hooves

`); - }, + } }; diff --git a/test/runtime/samples/each-block-else-mount-or-intro/_config.js b/test/runtime/samples/each-block-else-mount-or-intro/_config.js index 8460a4b5e0..acf2bafd5f 100644 --- a/test/runtime/samples/each-block-else-mount-or-intro/_config.js +++ b/test/runtime/samples/each-block-else-mount-or-intro/_config.js @@ -1,4 +1,4 @@ export default { props: { items: [] }, - html: `No items.`, + html: `No items.` }; diff --git a/test/runtime/samples/each-block-in-if-block/_config.js b/test/runtime/samples/each-block-in-if-block/_config.js index eda3ca14a9..082b9b3033 100644 --- a/test/runtime/samples/each-block-in-if-block/_config.js +++ b/test/runtime/samples/each-block-in-if-block/_config.js @@ -1,7 +1,7 @@ export default { props: { dummy: false, - fruits: ['Apple', 'Banana', 'Tomato'], + fruits: ['Apple', 'Banana', 'Tomato'] }, html: '
Apple
Banana
Tomato
', diff --git a/test/runtime/samples/each-block-keyed-component-action/Component.svelte b/test/runtime/samples/each-block-keyed-component-action/Component.svelte new file mode 100644 index 0000000000..18a6c7452a --- /dev/null +++ b/test/runtime/samples/each-block-keyed-component-action/Component.svelte @@ -0,0 +1,5 @@ + + +
diff --git a/test/runtime/samples/each-block-keyed-component-action/_config.js b/test/runtime/samples/each-block-keyed-component-action/_config.js new file mode 100644 index 0000000000..66c609be01 --- /dev/null +++ b/test/runtime/samples/each-block-keyed-component-action/_config.js @@ -0,0 +1,21 @@ +export default { + test({ assert, component, raf }) { + assert.equal(component.count, 0); + + component.arr = ["2"]; + + assert.equal(component.count, 1); + + component.arr = ["1", "2"]; + + assert.equal(component.count, 2); + + component.arr = ["2", "1"]; + + assert.equal(component.count, 2); + + component.arr = []; + + assert.equal(component.count, 0); + } +}; diff --git a/test/runtime/samples/each-block-keyed-component-action/main.svelte b/test/runtime/samples/each-block-keyed-component-action/main.svelte new file mode 100644 index 0000000000..bfacdf402a --- /dev/null +++ b/test/runtime/samples/each-block-keyed-component-action/main.svelte @@ -0,0 +1,17 @@ + + +{#each arr as item (item)} + +{/each} diff --git a/test/runtime/samples/each-block-keyed-empty/_config.js b/test/runtime/samples/each-block-keyed-empty/_config.js index cf8f4d3219..2c9055ce44 100644 --- a/test/runtime/samples/each-block-keyed-empty/_config.js +++ b/test/runtime/samples/each-block-keyed-empty/_config.js @@ -1,6 +1,6 @@ export default { props: { - x: [{ z: 1 }, { z: 2 }], + x: [{ z: 1 }, { z: 2 }] }, html: `` diff --git a/test/runtime/samples/each-block-keyed-non-prop/_config.js b/test/runtime/samples/each-block-keyed-non-prop/_config.js index 90e9a7f9c8..2cccbedef0 100644 --- a/test/runtime/samples/each-block-keyed-non-prop/_config.js +++ b/test/runtime/samples/each-block-keyed-non-prop/_config.js @@ -25,5 +25,5 @@ export default { assert.equal(p1, p4, 'first

element should be retained'); assert.equal(p3, p5, 'last

element should be retained'); - }, + } }; diff --git a/test/runtime/samples/each-block-keyed-random-permute/_config.js b/test/runtime/samples/each-block-keyed-random-permute/_config.js index 80bf2d9115..4e6830a616 100644 --- a/test/runtime/samples/each-block-keyed-random-permute/_config.js +++ b/test/runtime/samples/each-block-keyed-random-permute/_config.js @@ -19,7 +19,7 @@ function permute() { export default { props: { - values: toObjects('abc'), + values: toObjects('abc') }, html: `(a)(b)(c)`, diff --git a/test/runtime/samples/each-block-keyed-shift/_config.js b/test/runtime/samples/each-block-keyed-shift/_config.js index 44ca8447f0..4e7809445c 100644 --- a/test/runtime/samples/each-block-keyed-shift/_config.js +++ b/test/runtime/samples/each-block-keyed-shift/_config.js @@ -1,6 +1,6 @@ export default { props: { - titles: [{ name: 'a', }, { name: 'b' }, { name: 'c' }] + titles: [{ name: 'a' }, { name: 'b' }, { name: 'c' }] }, html: ` diff --git a/test/runtime/samples/each-block-keyed-siblings/_config.js b/test/runtime/samples/each-block-keyed-siblings/_config.js index d87f8943da..a52b6c404d 100644 --- a/test/runtime/samples/each-block-keyed-siblings/_config.js +++ b/test/runtime/samples/each-block-keyed-siblings/_config.js @@ -1,7 +1,7 @@ export default { props: { ones: [{ text: '1' }], - twos: [{ text: '2' }], + twos: [{ text: '2' }] }, html: ` @@ -16,5 +16,5 @@ export default {

11
2
`); - }, + } }; diff --git a/test/runtime/samples/each-block-keyed-static/_config.js b/test/runtime/samples/each-block-keyed-static/_config.js index 629ea47ebb..57800c454f 100644 --- a/test/runtime/samples/each-block-keyed-static/_config.js +++ b/test/runtime/samples/each-block-keyed-static/_config.js @@ -1,6 +1,6 @@ export default { props: { - x: [{ z: 1 }, { z: 2 }], + x: [{ z: 1 }, { z: 2 }] }, html: ` diff --git a/test/runtime/samples/each-block-scope-shadow-bind-2/_config.js b/test/runtime/samples/each-block-scope-shadow-bind-2/_config.js new file mode 100644 index 0000000000..384c2dd2b4 --- /dev/null +++ b/test/runtime/samples/each-block-scope-shadow-bind-2/_config.js @@ -0,0 +1,23 @@ +export default { + html: ` + Hello + + `, + ssrHtml: ` + Hello + + `, + async test({ assert, target, window }) { + const input = target.querySelector("input"); + input.value = "abcd"; + await input.dispatchEvent(new window.Event("input")); + + assert.htmlEqual( + target.innerHTML, + ` + abcd + + ` + ); + } +}; diff --git a/test/runtime/samples/each-block-scope-shadow-bind-2/main.svelte b/test/runtime/samples/each-block-scope-shadow-bind-2/main.svelte new file mode 100644 index 0000000000..f5bff01e6c --- /dev/null +++ b/test/runtime/samples/each-block-scope-shadow-bind-2/main.svelte @@ -0,0 +1,10 @@ + + +{#each a as { a }} + {a} + +{/each} \ No newline at end of file diff --git a/test/runtime/samples/each-block-scope-shadow-bind-3/_config.js b/test/runtime/samples/each-block-scope-shadow-bind-3/_config.js new file mode 100644 index 0000000000..92230a735c --- /dev/null +++ b/test/runtime/samples/each-block-scope-shadow-bind-3/_config.js @@ -0,0 +1,105 @@ +export default { + html: ` +
+ Hello World + + +
+
+ Sapper App + + +
+ `, + + ssrHtml: ` +
+ Hello World + + +
+
+ Sapper App + + +
+ `, + async test({ assert, target, window }) { + const [input1, input2, input3, input4] = target.querySelectorAll("input"); + input1.value = "Awesome"; + await input1.dispatchEvent(new window.Event("input")); + + assert.htmlEqual( + target.innerHTML, + ` +
+ Awesome World + + +
+
+ Sapper App + + +
+ ` + ); + + input2.value = "Svelte"; + await input2.dispatchEvent(new window.Event("input")); + + assert.htmlEqual( + target.innerHTML, + ` +
+ Awesome Svelte + + +
+
+ Sapper App + + +
+ ` + ); + + input3.value = "Foo"; + await input3.dispatchEvent(new window.Event("input")); + + assert.htmlEqual( + target.innerHTML, + ` +
+ Awesome Svelte + + +
+
+ Foo App + + +
+ ` + ); + + input4.value = "Bar"; + await input4.dispatchEvent(new window.Event("input")); + + assert.htmlEqual( + target.innerHTML, + ` +
+ Awesome Svelte + + +
+
+ Foo Bar + + +
+ ` + ); + } +}; diff --git a/test/runtime/samples/each-block-scope-shadow-bind-3/main.svelte b/test/runtime/samples/each-block-scope-shadow-bind-3/main.svelte new file mode 100644 index 0000000000..2e8fe5e591 --- /dev/null +++ b/test/runtime/samples/each-block-scope-shadow-bind-3/main.svelte @@ -0,0 +1,14 @@ + + +{#each a as a} +
+ {a[0]} {a[1]} + + +
+{/each} \ No newline at end of file diff --git a/test/runtime/samples/each-block-scope-shadow-bind-4/_config.js b/test/runtime/samples/each-block-scope-shadow-bind-4/_config.js new file mode 100644 index 0000000000..418fcbea4a --- /dev/null +++ b/test/runtime/samples/each-block-scope-shadow-bind-4/_config.js @@ -0,0 +1,64 @@ +export default { + html: ` +
+ b: Hello + +
+ + `, + ssrHtml: ` +
+ b: Hello + +
+ + `, + async test({ assert, target, window }) { + const input = target.querySelector("input"); + const button = target.querySelector("button"); + + input.value = "Awesome"; + await input.dispatchEvent(new window.Event("input")); + + assert.htmlEqual( + target.innerHTML, + ` +
+ b: Awesome + +
+ + ` + ); + + + await button.dispatchEvent(new window.MouseEvent("click")); + + assert.htmlEqual( + target.innerHTML, + ` +
+ c: World + +
+ + ` + ); + + assert.equal(input.value, 'World'); + + input.value = "Svelte"; + await input.dispatchEvent(new window.Event("input")); + + assert.htmlEqual( + target.innerHTML, + ` +
+ c: Svelte + +
+ + ` + ); + } +}; diff --git a/test/runtime/samples/each-block-scope-shadow-bind-4/main.svelte b/test/runtime/samples/each-block-scope-shadow-bind-4/main.svelte new file mode 100644 index 0000000000..bc4f172dd0 --- /dev/null +++ b/test/runtime/samples/each-block-scope-shadow-bind-4/main.svelte @@ -0,0 +1,14 @@ + + +{#each a as { a, key }} +
+ {key}: {a[key]} + +
+{/each} + + \ No newline at end of file diff --git a/test/runtime/samples/each-block-scope-shadow-bind/_config.js b/test/runtime/samples/each-block-scope-shadow-bind/_config.js new file mode 100644 index 0000000000..384c2dd2b4 --- /dev/null +++ b/test/runtime/samples/each-block-scope-shadow-bind/_config.js @@ -0,0 +1,23 @@ +export default { + html: ` + Hello + + `, + ssrHtml: ` + Hello + + `, + async test({ assert, target, window }) { + const input = target.querySelector("input"); + input.value = "abcd"; + await input.dispatchEvent(new window.Event("input")); + + assert.htmlEqual( + target.innerHTML, + ` + abcd + + ` + ); + } +}; diff --git a/test/runtime/samples/each-block-scope-shadow-bind/main.svelte b/test/runtime/samples/each-block-scope-shadow-bind/main.svelte new file mode 100644 index 0000000000..f3471e179f --- /dev/null +++ b/test/runtime/samples/each-block-scope-shadow-bind/main.svelte @@ -0,0 +1,10 @@ + + +{#each a as a} + {a} + +{/each} \ No newline at end of file diff --git a/test/runtime/samples/each-block-scope-shadow-self/_config.js b/test/runtime/samples/each-block-scope-shadow-self/_config.js index 1669dc5b6e..867aadfab9 100644 --- a/test/runtime/samples/each-block-scope-shadow-self/_config.js +++ b/test/runtime/samples/each-block-scope-shadow-self/_config.js @@ -9,5 +9,5 @@ export default { assert.equal(target.querySelectorAll('input').length, 3); assert.deepEqual(component.data, { a: 'svelte', b: 'B', c: 'C' }); assert.deepEqual(component.x, ['a', 'b', 'c']); - }, + } }; diff --git a/test/runtime/samples/each-blocks-assignment-2/_config.js b/test/runtime/samples/each-blocks-assignment-2/_config.js new file mode 100644 index 0000000000..0831617261 --- /dev/null +++ b/test/runtime/samples/each-blocks-assignment-2/_config.js @@ -0,0 +1,20 @@ +export default { + html: ` + foo + + `, + async test({ assert, component, target, window }) { + const button = target.querySelector("button"); + + const clickEvent = new window.MouseEvent("click"); + await button.dispatchEvent(clickEvent); + + assert.htmlEqual( + target.innerHTML, + ` + bar + + ` + ); + } +}; diff --git a/test/runtime/samples/each-blocks-assignment-2/main.svelte b/test/runtime/samples/each-blocks-assignment-2/main.svelte new file mode 100644 index 0000000000..5ef3ae83ac --- /dev/null +++ b/test/runtime/samples/each-blocks-assignment-2/main.svelte @@ -0,0 +1,12 @@ + + +{#each arr as o} + {o.prop} + +{/each} \ No newline at end of file diff --git a/test/runtime/samples/each-blocks-assignment/_config.js b/test/runtime/samples/each-blocks-assignment/_config.js new file mode 100644 index 0000000000..2c95d486d6 --- /dev/null +++ b/test/runtime/samples/each-blocks-assignment/_config.js @@ -0,0 +1,97 @@ +export default { + html: ` + + 1 + + 2 + + 3 + + `, + async test({ assert, component, target, window }) { + let [incrementBtn, ...buttons] = target.querySelectorAll("button"); + + const clickEvent = new window.MouseEvent("click"); + await buttons[0].dispatchEvent(clickEvent); + + assert.htmlEqual( + target.innerHTML, + ` + + 2 + + 2 + + 3 + + ` + ); + + await buttons[0].dispatchEvent(clickEvent); + + assert.htmlEqual( + target.innerHTML, + ` + + 4 + + 2 + + 3 + + ` + ); + + await buttons[2].dispatchEvent(clickEvent); + await buttons[2].dispatchEvent(clickEvent); + + assert.htmlEqual( + target.innerHTML, + ` + + 4 + + 2 + + 12 + + ` + ); + + await incrementBtn.dispatchEvent(clickEvent); + + assert.htmlEqual( + target.innerHTML, + ` + + 4 + + 2 + + 12 + + 4 + + ` + ); + + [incrementBtn, ...buttons] = target.querySelectorAll("button"); + + await buttons[3].dispatchEvent(clickEvent); + + assert.htmlEqual( + target.innerHTML, + ` + + 4 + + 2 + + 12 + + 8 + + ` + ); + } +}; diff --git a/test/runtime/samples/each-blocks-assignment/main.svelte b/test/runtime/samples/each-blocks-assignment/main.svelte new file mode 100644 index 0000000000..f74bffbe04 --- /dev/null +++ b/test/runtime/samples/each-blocks-assignment/main.svelte @@ -0,0 +1,13 @@ + + + +{#each arr as o} + {o} + +{/each} \ No newline at end of file diff --git a/test/runtime/samples/empty-dom/_config.js b/test/runtime/samples/empty-dom/_config.js index e3e3d0ecd5..7da2831db4 100644 --- a/test/runtime/samples/empty-dom/_config.js +++ b/test/runtime/samples/empty-dom/_config.js @@ -1,3 +1,3 @@ export default { - html: '', + html: '' }; \ No newline at end of file diff --git a/test/runtime/samples/empty-style-block/_config.js b/test/runtime/samples/empty-style-block/_config.js index 0375bad029..22dc25b41e 100644 --- a/test/runtime/samples/empty-style-block/_config.js +++ b/test/runtime/samples/empty-style-block/_config.js @@ -1,3 +1,3 @@ export default { - html: '', + html: '' }; diff --git a/test/runtime/samples/escape-template-literals/_config.js b/test/runtime/samples/escape-template-literals/_config.js index 1419d65679..9e50f94764 100644 --- a/test/runtime/samples/escape-template-literals/_config.js +++ b/test/runtime/samples/escape-template-literals/_config.js @@ -1,3 +1,3 @@ export default { - html: '`${foo}\\n`\n
foo
\n
`${foo}\\n`
', + html: '`${foo}\\n`\n
foo
\n
`${foo}\\n`
' }; diff --git a/test/runtime/samples/event-handler-async/_config.js b/test/runtime/samples/event-handler-async/_config.js index fab4d998b6..b483d039ed 100644 --- a/test/runtime/samples/event-handler-async/_config.js +++ b/test/runtime/samples/event-handler-async/_config.js @@ -1,5 +1,5 @@ export default { html: ` - `, + ` }; diff --git a/test/runtime/samples/event-handler-dynamic-2/_config.js b/test/runtime/samples/event-handler-dynamic-2/_config.js index c996d8f2aa..5fded47855 100644 --- a/test/runtime/samples/event-handler-dynamic-2/_config.js +++ b/test/runtime/samples/event-handler-dynamic-2/_config.js @@ -29,5 +29,5 @@ export default { await handler_b.dispatchEvent(event); assert.equal(p.innerHTML, '2'); - }, + } }; diff --git a/test/runtime/samples/event-handler-dynamic-bound-var/_config.js b/test/runtime/samples/event-handler-dynamic-bound-var/_config.js index c832127c09..c490db000a 100644 --- a/test/runtime/samples/event-handler-dynamic-bound-var/_config.js +++ b/test/runtime/samples/event-handler-dynamic-bound-var/_config.js @@ -16,5 +16,5 @@ export default { Bye World ` ); - }, + } }; diff --git a/test/runtime/samples/event-handler-dynamic-expression/_config.js b/test/runtime/samples/event-handler-dynamic-expression/_config.js index c4d259a542..b202196ebf 100644 --- a/test/runtime/samples/event-handler-dynamic-expression/_config.js +++ b/test/runtime/samples/event-handler-dynamic-expression/_config.js @@ -16,5 +16,5 @@ export default { await button.dispatchEvent(event); assert.htmlEqual(target.innerHTML, ``); - }, + } }; diff --git a/test/runtime/samples/event-handler-dynamic-hash/_config.js b/test/runtime/samples/event-handler-dynamic-hash/_config.js index e60e561524..dcfebb7008 100644 --- a/test/runtime/samples/event-handler-dynamic-hash/_config.js +++ b/test/runtime/samples/event-handler-dynamic-hash/_config.js @@ -52,5 +52,5 @@ export default {

2

`); - }, + } }; diff --git a/test/runtime/samples/event-handler-dynamic-invalid/_config.js b/test/runtime/samples/event-handler-dynamic-invalid/_config.js index ba1777f945..ad9d8c8680 100644 --- a/test/runtime/samples/event-handler-dynamic-invalid/_config.js +++ b/test/runtime/samples/event-handler-dynamic-invalid/_config.js @@ -24,5 +24,5 @@ export default { await buttonInvalid.dispatchEvent(event); assert.equal(err, "", err); - }, + } }; diff --git a/test/runtime/samples/event-handler-dynamic-modifier-self/_config.js b/test/runtime/samples/event-handler-dynamic-modifier-self/_config.js index 6d7d29e482..6bd96ba8aa 100644 --- a/test/runtime/samples/event-handler-dynamic-modifier-self/_config.js +++ b/test/runtime/samples/event-handler-dynamic-modifier-self/_config.js @@ -12,5 +12,5 @@ export default { await button.dispatchEvent(event); assert.ok(!component.inner_clicked); - }, + } }; diff --git a/test/runtime/samples/event-handler-dynamic/_config.js b/test/runtime/samples/event-handler-dynamic/_config.js index e60e561524..dcfebb7008 100644 --- a/test/runtime/samples/event-handler-dynamic/_config.js +++ b/test/runtime/samples/event-handler-dynamic/_config.js @@ -52,5 +52,5 @@ export default {

2

`); - }, + } }; diff --git a/test/runtime/samples/event-handler-each-this/_config.js b/test/runtime/samples/event-handler-each-this/_config.js index 3ab2d5acdc..7f6528977c 100644 --- a/test/runtime/samples/event-handler-each-this/_config.js +++ b/test/runtime/samples/event-handler-each-this/_config.js @@ -1,6 +1,6 @@ export default { props: { - items: ['foo', 'bar', 'baz'], + items: ['foo', 'bar', 'baz'] }, html: ` diff --git a/test/runtime/samples/event-handler-modifier-self/_config.js b/test/runtime/samples/event-handler-modifier-self/_config.js index 6d7d29e482..6bd96ba8aa 100644 --- a/test/runtime/samples/event-handler-modifier-self/_config.js +++ b/test/runtime/samples/event-handler-modifier-self/_config.js @@ -12,5 +12,5 @@ export default { await button.dispatchEvent(event); assert.ok(!component.inner_clicked); - }, + } }; diff --git a/test/runtime/samples/globals-not-overwritten-by-bindings/_config.js b/test/runtime/samples/globals-not-overwritten-by-bindings/_config.js index d5f3def7f1..34cee8157c 100644 --- a/test/runtime/samples/globals-not-overwritten-by-bindings/_config.js +++ b/test/runtime/samples/globals-not-overwritten-by-bindings/_config.js @@ -37,17 +37,17 @@ export default { todos: { first: { description: 'Buy some milk', - done: true, + done: true }, second: { description: 'Do the laundry', - done: true, + done: true }, third: { description: "Find life's true purpose", - done: false, - }, - }, + done: false + } + } }, async test({ assert, component, target, window }) { @@ -74,5 +74,5 @@ export default {
`); - }, + } }; diff --git a/test/runtime/samples/globals-shadowed-by-each-binding/_config.js b/test/runtime/samples/globals-shadowed-by-each-binding/_config.js index f69e5e8b0e..50feb09bb6 100644 --- a/test/runtime/samples/globals-shadowed-by-each-binding/_config.js +++ b/test/runtime/samples/globals-shadowed-by-each-binding/_config.js @@ -1,3 +1,3 @@ export default { - html: '

Alert1

Alert2

', + html: '

Alert1

Alert2

' }; diff --git a/test/runtime/samples/if-block-component-store-function-conditionals/_config.js b/test/runtime/samples/if-block-component-store-function-conditionals/_config.js index db171f2fd1..609765d225 100644 --- a/test/runtime/samples/if-block-component-store-function-conditionals/_config.js +++ b/test/runtime/samples/if-block-component-store-function-conditionals/_config.js @@ -1,3 +1,3 @@ export default { - html: '

OK

', + html: '

OK

' }; diff --git a/test/runtime/samples/if-block-component-without-outro/_config.js b/test/runtime/samples/if-block-component-without-outro/_config.js index 8106081c7c..fbcc328fa3 100644 --- a/test/runtime/samples/if-block-component-without-outro/_config.js +++ b/test/runtime/samples/if-block-component-without-outro/_config.js @@ -1,6 +1,6 @@ export default { props: { - foo: true, + foo: true }, html: '
A wild component appears
', @@ -8,5 +8,5 @@ export default { test({ assert, component, target }) { component.foo = false; assert.htmlEqual(target.innerHTML, ''); - }, + } }; diff --git a/test/runtime/samples/if-block-else-in-each/_config.js b/test/runtime/samples/if-block-else-in-each/_config.js index 44268f32b9..e75dcb15ee 100644 --- a/test/runtime/samples/if-block-else-in-each/_config.js +++ b/test/runtime/samples/if-block-else-in-each/_config.js @@ -1,9 +1,9 @@ export default { props: { - array: [true, false], + array: [true, false] }, html: `
foo
bar
- `, + ` }; diff --git a/test/runtime/samples/if-block-else-partial-outro/_config.js b/test/runtime/samples/if-block-else-partial-outro/_config.js index a358680edf..ae58d25c23 100644 --- a/test/runtime/samples/if-block-else-partial-outro/_config.js +++ b/test/runtime/samples/if-block-else-partial-outro/_config.js @@ -1,7 +1,7 @@ export default { props: { x: 1, - y: false, + y: false }, html: ` @@ -13,5 +13,5 @@ export default { assert.htmlEqual(target.innerHTML, ` 2 `); - }, + } }; diff --git a/test/runtime/samples/if-block-no-outro-else-with-outro/_config.js b/test/runtime/samples/if-block-no-outro-else-with-outro/_config.js index b2e71ea01f..da80f5be12 100644 --- a/test/runtime/samples/if-block-no-outro-else-with-outro/_config.js +++ b/test/runtime/samples/if-block-no-outro-else-with-outro/_config.js @@ -18,5 +18,5 @@ export default {

y

`); - }, + } }; diff --git a/test/runtime/samples/if-block-outro-unique-select-block-type/_config.js b/test/runtime/samples/if-block-outro-unique-select-block-type/_config.js index b94da1a576..15213e19b3 100644 --- a/test/runtime/samples/if-block-outro-unique-select-block-type/_config.js +++ b/test/runtime/samples/if-block-outro-unique-select-block-type/_config.js @@ -2,5 +2,5 @@ export default { html: `
- `, + ` }; diff --git a/test/runtime/samples/initial-state-assign/_config.js b/test/runtime/samples/initial-state-assign/_config.js index b4067fef80..95a1a5e068 100644 --- a/test/runtime/samples/initial-state-assign/_config.js +++ b/test/runtime/samples/initial-state-assign/_config.js @@ -3,5 +3,5 @@ export default { html: ` "foo" "bar" - `, + ` }; diff --git a/test/runtime/samples/innerhtml-with-comments/_config.js b/test/runtime/samples/innerhtml-with-comments/_config.js new file mode 100644 index 0000000000..95d4a6fa96 --- /dev/null +++ b/test/runtime/samples/innerhtml-with-comments/_config.js @@ -0,0 +1,8 @@ +export default { + html: ` + + Style: + Bootstrap. + + ` +}; \ No newline at end of file diff --git a/test/runtime/samples/innerhtml-with-comments/main.svelte b/test/runtime/samples/innerhtml-with-comments/main.svelte new file mode 100644 index 0000000000..e00f755072 --- /dev/null +++ b/test/runtime/samples/innerhtml-with-comments/main.svelte @@ -0,0 +1,5 @@ + + Style: + + Bootstrap. + \ No newline at end of file diff --git a/test/runtime/samples/lifecycle-render-order-for-children/_config.js b/test/runtime/samples/lifecycle-render-order-for-children/_config.js index 033b593aea..d182d5a97e 100644 --- a/test/runtime/samples/lifecycle-render-order-for-children/_config.js +++ b/test/runtime/samples/lifecycle-render-order-for-children/_config.js @@ -21,7 +21,7 @@ export default { '3: onMount', '3: afterUpdate', '0: onMount', - '0: afterUpdate', + '0: afterUpdate' ]); } else { assert.deepEqual(order, [ @@ -40,10 +40,10 @@ export default { '3: onMount', '3: afterUpdate', '0: onMount', - '0: afterUpdate', + '0: afterUpdate' ]); } order.length = 0; - }, + } }; diff --git a/test/runtime/samples/loop-protect-generator-opt-out/_config.js b/test/runtime/samples/loop-protect-generator-opt-out/_config.js index 9b6a24b513..0fe83a36db 100644 --- a/test/runtime/samples/loop-protect-generator-opt-out/_config.js +++ b/test/runtime/samples/loop-protect-generator-opt-out/_config.js @@ -1,6 +1,6 @@ export default { compileOptions: { dev: true, - loopGuardTimeout: 1, - }, + loopGuardTimeout: 1 + } }; diff --git a/test/runtime/samples/loop-protect-inner-function/_config.js b/test/runtime/samples/loop-protect-inner-function/_config.js index 862d4f4c0f..1b553e2475 100644 --- a/test/runtime/samples/loop-protect-inner-function/_config.js +++ b/test/runtime/samples/loop-protect-inner-function/_config.js @@ -2,6 +2,6 @@ export default { html: '
', compileOptions: { dev: true, - loopGuardTimeout: 100, + loopGuardTimeout: 100 } }; diff --git a/test/runtime/samples/loop-protect/_config.js b/test/runtime/samples/loop-protect/_config.js index 75f75c003d..230bbeb53d 100644 --- a/test/runtime/samples/loop-protect/_config.js +++ b/test/runtime/samples/loop-protect/_config.js @@ -2,6 +2,6 @@ export default { error: 'Infinite loop detected', compileOptions: { dev: true, - loopGuardTimeout: 100, + loopGuardTimeout: 100 } }; diff --git a/test/runtime/samples/nested-transition-detach-each/_config.js b/test/runtime/samples/nested-transition-detach-each/_config.js index e17fe1bc4d..00c2d44048 100644 --- a/test/runtime/samples/nested-transition-detach-each/_config.js +++ b/test/runtime/samples/nested-transition-detach-each/_config.js @@ -35,5 +35,5 @@ export default { raf.tick(0); raf.tick(100); assert.htmlEqual(target.innerHTML, ``); - }, + } }; diff --git a/test/runtime/samples/nested-transition-detach-if-false/_config.js b/test/runtime/samples/nested-transition-detach-if-false/_config.js index d2ae78ffe3..1d42094192 100644 --- a/test/runtime/samples/nested-transition-detach-if-false/_config.js +++ b/test/runtime/samples/nested-transition-detach-if-false/_config.js @@ -20,5 +20,5 @@ export default { a `); - }, + } }; diff --git a/test/runtime/samples/nested-transition-if-block-not-remounted/_config.js b/test/runtime/samples/nested-transition-if-block-not-remounted/_config.js index 6696389e6e..30ff83b39f 100644 --- a/test/runtime/samples/nested-transition-if-block-not-remounted/_config.js +++ b/test/runtime/samples/nested-transition-if-block-not-remounted/_config.js @@ -20,5 +20,5 @@ export default { }; component.value = 'two'; - }, + } }; diff --git a/test/runtime/samples/noscript-removal/_config.js b/test/runtime/samples/noscript-removal/_config.js index 35bdcefd96..709792c14a 100644 --- a/test/runtime/samples/noscript-removal/_config.js +++ b/test/runtime/samples/noscript-removal/_config.js @@ -5,5 +5,5 @@ export default {
foo
foo
foo
-`, +` }; diff --git a/test/runtime/samples/paren-wrapped-expressions/_config.js b/test/runtime/samples/paren-wrapped-expressions/_config.js index 0c757dc854..972dc51cb0 100644 --- a/test/runtime/samples/paren-wrapped-expressions/_config.js +++ b/test/runtime/samples/paren-wrapped-expressions/_config.js @@ -2,7 +2,7 @@ export default { props: { a: 'foo', b: true, - c: [ 1, 2, 3 ], + c: [ 1, 2, 3 ] }, html: ` diff --git a/test/runtime/samples/prop-exports/_config.js b/test/runtime/samples/prop-exports/_config.js index e1620c015f..69a40c4fab 100644 --- a/test/runtime/samples/prop-exports/_config.js +++ b/test/runtime/samples/prop-exports/_config.js @@ -10,7 +10,7 @@ export default { a2: 4, a6: writable(29), for: 'loop', - continue: '...', + continue: '...' }, html: ` diff --git a/test/runtime/samples/props-reactive-only-with-change/Comp.svelte b/test/runtime/samples/props-reactive-only-with-change/Comp.svelte new file mode 100644 index 0000000000..0eaf8a40d4 --- /dev/null +++ b/test/runtime/samples/props-reactive-only-with-change/Comp.svelte @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/test/runtime/samples/props-reactive-only-with-change/_config.js b/test/runtime/samples/props-reactive-only-with-change/_config.js new file mode 100644 index 0000000000..d2e86e583d --- /dev/null +++ b/test/runtime/samples/props-reactive-only-with-change/_config.js @@ -0,0 +1,30 @@ +let callbacks = []; + +export default { + props: { + callback: (value) => callbacks.push(value), + val1: "1", + val2: "2" + }, + + before_test() { + callbacks = []; + }, + + async test({ assert, component, target }) { + assert.equal(callbacks.length, 2); + assert.equal(JSON.stringify(callbacks), '["1","2"]'); + + component.val1 = "3"; + assert.equal(callbacks.length, 3); + assert.equal(JSON.stringify(callbacks), '["1","2","1"]'); + + component.val1 = "4"; + assert.equal(callbacks.length, 4); + assert.equal(JSON.stringify(callbacks), '["1","2","1","1"]'); + + component.val2 = "5"; + assert.equal(callbacks.length, 5); + assert.equal(JSON.stringify(callbacks), '["1","2","1","1","2"]'); + } +}; diff --git a/test/runtime/samples/props-reactive-only-with-change/main.svelte b/test/runtime/samples/props-reactive-only-with-change/main.svelte new file mode 100644 index 0000000000..73ddd137f5 --- /dev/null +++ b/test/runtime/samples/props-reactive-only-with-change/main.svelte @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/test/runtime/samples/props-reactive-slot/Comp.svelte b/test/runtime/samples/props-reactive-slot/Comp.svelte new file mode 100644 index 0000000000..bf9e12a58a --- /dev/null +++ b/test/runtime/samples/props-reactive-slot/Comp.svelte @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/runtime/samples/props-reactive-slot/_config.js b/test/runtime/samples/props-reactive-slot/_config.js new file mode 100644 index 0000000000..8ee6ef69dc --- /dev/null +++ b/test/runtime/samples/props-reactive-slot/_config.js @@ -0,0 +1,21 @@ +export default { + html: ` +

hi

+ + `, + + async test({ assert, component, target, window }) { + const btn = target.querySelector("button"); + const clickEvent = new window.MouseEvent("click"); + + await btn.dispatchEvent(clickEvent); + + assert.htmlEqual( + target.innerHTML, + ` +

changed

+ + ` + ); + } +}; diff --git a/test/runtime/samples/props-reactive-slot/main.svelte b/test/runtime/samples/props-reactive-slot/main.svelte new file mode 100644 index 0000000000..84777bf8ab --- /dev/null +++ b/test/runtime/samples/props-reactive-slot/main.svelte @@ -0,0 +1,13 @@ + + + +

+ {props.someprop} +

+
+ + \ No newline at end of file diff --git a/test/runtime/samples/raw-mustache-as-root/RawMustache.svelte b/test/runtime/samples/raw-mustache-as-root/RawMustache.svelte new file mode 100644 index 0000000000..d94954f49b --- /dev/null +++ b/test/runtime/samples/raw-mustache-as-root/RawMustache.svelte @@ -0,0 +1,5 @@ + + +{@html content} \ No newline at end of file diff --git a/test/runtime/samples/raw-mustache-as-root/_config.js b/test/runtime/samples/raw-mustache-as-root/_config.js new file mode 100644 index 0000000000..e42fa7f517 --- /dev/null +++ b/test/runtime/samples/raw-mustache-as-root/_config.js @@ -0,0 +1,33 @@ +export default { + html: ` + +

Another first line

+

This line should be last.

+ `, + async test({ assert, target, window }) { + const btn = target.querySelector("button"); + const clickEvent = new window.MouseEvent("click"); + + await btn.dispatchEvent(clickEvent); + + assert.htmlEqual( + target.innerHTML, + ` + +

First line

+

This line should be last.

+ ` + ); + + await btn.dispatchEvent(clickEvent); + + assert.htmlEqual( + target.innerHTML, + ` + +

Another first line

+

This line should be last.

+ ` + ); + } +}; diff --git a/test/runtime/samples/raw-mustache-as-root/main.svelte b/test/runtime/samples/raw-mustache-as-root/main.svelte new file mode 100644 index 0000000000..7ccce0cd9b --- /dev/null +++ b/test/runtime/samples/raw-mustache-as-root/main.svelte @@ -0,0 +1,17 @@ + + + + + + +

This line should be last.

\ No newline at end of file diff --git a/test/runtime/samples/raw-mustache-inside-head/_config.js b/test/runtime/samples/raw-mustache-inside-head/_config.js new file mode 100644 index 0000000000..7923fc7238 --- /dev/null +++ b/test/runtime/samples/raw-mustache-inside-head/_config.js @@ -0,0 +1,16 @@ +export default { + async test({ assert, target, window }) { + const btn = target.querySelector("button"); + const clickEvent = new window.MouseEvent("click"); + + assert.equal(window.document.head.innerHTML.includes(''), true); + + await btn.dispatchEvent(clickEvent); + + assert.equal(window.document.head.innerHTML.includes(''), true); + + await btn.dispatchEvent(clickEvent); + + assert.equal(window.document.head.innerHTML.includes(''), true); + } +}; diff --git a/test/runtime/samples/raw-mustache-inside-head/main.svelte b/test/runtime/samples/raw-mustache-inside-head/main.svelte new file mode 100644 index 0000000000..25b9fdeee9 --- /dev/null +++ b/test/runtime/samples/raw-mustache-inside-head/main.svelte @@ -0,0 +1,16 @@ + + + + + + {@html content} + + diff --git a/test/runtime/samples/raw-mustache-inside-slot/Component.svelte b/test/runtime/samples/raw-mustache-inside-slot/Component.svelte new file mode 100644 index 0000000000..fcabccae48 --- /dev/null +++ b/test/runtime/samples/raw-mustache-inside-slot/Component.svelte @@ -0,0 +1,2 @@ + +

This line should be last.

\ No newline at end of file diff --git a/test/runtime/samples/raw-mustache-inside-slot/_config.js b/test/runtime/samples/raw-mustache-inside-slot/_config.js new file mode 100644 index 0000000000..e42fa7f517 --- /dev/null +++ b/test/runtime/samples/raw-mustache-inside-slot/_config.js @@ -0,0 +1,33 @@ +export default { + html: ` + +

Another first line

+

This line should be last.

+ `, + async test({ assert, target, window }) { + const btn = target.querySelector("button"); + const clickEvent = new window.MouseEvent("click"); + + await btn.dispatchEvent(clickEvent); + + assert.htmlEqual( + target.innerHTML, + ` + +

First line

+

This line should be last.

+ ` + ); + + await btn.dispatchEvent(clickEvent); + + assert.htmlEqual( + target.innerHTML, + ` + +

Another first line

+

This line should be last.

+ ` + ); + } +}; diff --git a/test/runtime/samples/raw-mustache-inside-slot/main.svelte b/test/runtime/samples/raw-mustache-inside-slot/main.svelte new file mode 100644 index 0000000000..a022a68e95 --- /dev/null +++ b/test/runtime/samples/raw-mustache-inside-slot/main.svelte @@ -0,0 +1,17 @@ + + + + + + {@html content} + \ No newline at end of file diff --git a/test/runtime/samples/raw-mustaches-td-tr/_config.js b/test/runtime/samples/raw-mustaches-td-tr/_config.js new file mode 100644 index 0000000000..1bcad157f3 --- /dev/null +++ b/test/runtime/samples/raw-mustaches-td-tr/_config.js @@ -0,0 +1,18 @@ +export default { + props: { + raw: "12" + }, + + html: ` + + + + + + + + + +
57
12
+ ` +}; diff --git a/test/runtime/samples/raw-mustaches-td-tr/main.svelte b/test/runtime/samples/raw-mustaches-td-tr/main.svelte new file mode 100644 index 0000000000..07d7299e43 --- /dev/null +++ b/test/runtime/samples/raw-mustaches-td-tr/main.svelte @@ -0,0 +1,12 @@ + + + + + + + + {@html raw} + +
57
\ No newline at end of file diff --git a/test/runtime/samples/reactive-function-called-reassigned/_config.js b/test/runtime/samples/reactive-function-called-reassigned/_config.js new file mode 100644 index 0000000000..7b2a8b72fe --- /dev/null +++ b/test/runtime/samples/reactive-function-called-reassigned/_config.js @@ -0,0 +1,27 @@ +let value; +let called = 0; +function callback(_value) { + called ++; + value = _value; +} + +export default { + props: { + callback + }, + async test({ assert, component, target, window }) { + assert.equal(called, 1); + + const input = target.querySelector('input'); + + const event = new window.Event('input'); + input.value = 'h'; + await input.dispatchEvent(event); + + assert.equal(called, 2); + assert.equal(value.length, 3); + assert.equal(value[0], 'h'); + assert.equal(value[1], '2'); + assert.equal(value[2], '3'); + } +}; diff --git a/test/runtime/samples/reactive-function-called-reassigned/main.svelte b/test/runtime/samples/reactive-function-called-reassigned/main.svelte new file mode 100644 index 0000000000..10a3c79d14 --- /dev/null +++ b/test/runtime/samples/reactive-function-called-reassigned/main.svelte @@ -0,0 +1,10 @@ + + +{#each refs as ref} + +{/each} \ No newline at end of file diff --git a/test/runtime/samples/reactive-import-statement/_config.js b/test/runtime/samples/reactive-import-statement/_config.js index 7fb8097ca5..45a844afa0 100644 --- a/test/runtime/samples/reactive-import-statement/_config.js +++ b/test/runtime/samples/reactive-import-statement/_config.js @@ -11,7 +11,7 @@ export default { before_test() { delete require.cache[path.resolve(__dirname, 'data.js')]; }, - async test({ assert, target, window, }) { + async test({ assert, target, window }) { const btn = target.querySelector('button'); const clickEvent = new window.MouseEvent('click'); diff --git a/test/runtime/samples/reactive-value-assign-property/_config.js b/test/runtime/samples/reactive-value-assign-property/_config.js new file mode 100644 index 0000000000..b6d8bf51be --- /dev/null +++ b/test/runtime/samples/reactive-value-assign-property/_config.js @@ -0,0 +1,5 @@ +export default { + html: ` +

Hello world!

+ ` +}; diff --git a/test/runtime/samples/reactive-value-assign-property/main.svelte b/test/runtime/samples/reactive-value-assign-property/main.svelte new file mode 100644 index 0000000000..58e0fdb03c --- /dev/null +++ b/test/runtime/samples/reactive-value-assign-property/main.svelte @@ -0,0 +1,6 @@ + + +

Hello {user.name}!

\ No newline at end of file diff --git a/test/runtime/samples/self-reference-component/_config.js b/test/runtime/samples/self-reference-component/_config.js index e3e0ad3a4f..e9cd0ac440 100644 --- a/test/runtime/samples/self-reference-component/_config.js +++ b/test/runtime/samples/self-reference-component/_config.js @@ -1,3 +1,3 @@ export default { - html: '5 4 3 2 1 0', + html: '5 4 3 2 1 0' }; \ No newline at end of file diff --git a/test/runtime/samples/set-undefined-attr/_config.js b/test/runtime/samples/set-undefined-attr/_config.js index b23f51dfc9..a0df368e65 100644 --- a/test/runtime/samples/set-undefined-attr/_config.js +++ b/test/runtime/samples/set-undefined-attr/_config.js @@ -1,5 +1,5 @@ export default { html: `
`, - ssrHtml: `
`, + ssrHtml: `
` }; diff --git a/test/runtime/samples/sigil-component-prop/_config.js b/test/runtime/samples/sigil-component-prop/_config.js index 2f467bb9d4..9f84a59994 100644 --- a/test/runtime/samples/sigil-component-prop/_config.js +++ b/test/runtime/samples/sigil-component-prop/_config.js @@ -3,5 +3,5 @@ export default { dev: true }, props: { foo: 'foo' }, - html: `
foo @ foo # foo
`, + html: `
foo @ foo # foo
` }; diff --git a/test/runtime/samples/slot-if-block-update-no-anchor/_config.js b/test/runtime/samples/slot-if-block-update-no-anchor/_config.js index 060cbaa619..58d2b49ade 100644 --- a/test/runtime/samples/slot-if-block-update-no-anchor/_config.js +++ b/test/runtime/samples/slot-if-block-update-no-anchor/_config.js @@ -3,5 +3,5 @@ export default { assert.htmlEqual(target.innerHTML, ``); component.enabled = true; assert.htmlEqual(target.innerHTML, `enabled`); - }, + } }; diff --git a/test/runtime/samples/spread-component-2/_config.js b/test/runtime/samples/spread-component-2/_config.js index 6d36e8e60d..e5441bc4b9 100644 --- a/test/runtime/samples/spread-component-2/_config.js +++ b/test/runtime/samples/spread-component-2/_config.js @@ -10,7 +10,7 @@ export default { baz: 50 + 2, qux: 1, quux: 'quuxx' - }], + }] }, html: ` diff --git a/test/runtime/samples/spread-component-dynamic-non-object-multiple-dependencies/_config.js b/test/runtime/samples/spread-component-dynamic-non-object-multiple-dependencies/_config.js index c5e23a023c..d7ad47b01f 100644 --- a/test/runtime/samples/spread-component-dynamic-non-object-multiple-dependencies/_config.js +++ b/test/runtime/samples/spread-component-dynamic-non-object-multiple-dependencies/_config.js @@ -2,7 +2,7 @@ export default { props: { props: { foo: 'lol', - baz: 40 + 2, + baz: 40 + 2 } }, diff --git a/test/runtime/samples/spread-component-dynamic-non-object/_config.js b/test/runtime/samples/spread-component-dynamic-non-object/_config.js index 094f2fbb9b..fa8de8ad94 100644 --- a/test/runtime/samples/spread-component-dynamic-non-object/_config.js +++ b/test/runtime/samples/spread-component-dynamic-non-object/_config.js @@ -2,7 +2,7 @@ export default { props: { props: { foo: 'lol', - baz: 40 + 2, + baz: 40 + 2 } }, diff --git a/test/runtime/samples/spread-component-dynamic-undefined/_config.js b/test/runtime/samples/spread-component-dynamic-undefined/_config.js index 09e5f87c14..e7e205a34b 100644 --- a/test/runtime/samples/spread-component-dynamic-undefined/_config.js +++ b/test/runtime/samples/spread-component-dynamic-undefined/_config.js @@ -1,17 +1,17 @@ export default { props: { props: { - a: 1, - }, + a: 1 + } }, html: ``, test({ assert, component, target }) { component.props = { - a: 2, + a: 2 }; assert.htmlEqual(target.innerHTML, ``); - }, + } }; diff --git a/test/runtime/samples/spread-component-dynamic/_config.js b/test/runtime/samples/spread-component-dynamic/_config.js index a6bf952ae0..08df27e1c2 100644 --- a/test/runtime/samples/spread-component-dynamic/_config.js +++ b/test/runtime/samples/spread-component-dynamic/_config.js @@ -1,8 +1,8 @@ export default { props: { props: { - a: 1, - }, + a: 1 + } }, html: ` @@ -11,9 +11,9 @@ export default { test({ assert, component, target }) { component.props = { - a: 2, + a: 2 }; assert.htmlEqual(target.innerHTML, `

a: 2

`); - }, + } }; diff --git a/test/runtime/samples/spread-component-multiple-dependencies/_config.js b/test/runtime/samples/spread-component-multiple-dependencies/_config.js index bc05f31130..070916ebd8 100644 --- a/test/runtime/samples/spread-component-multiple-dependencies/_config.js +++ b/test/runtime/samples/spread-component-multiple-dependencies/_config.js @@ -6,5 +6,5 @@ export default { target.innerHTML, `a baz` ); - }, + } }; diff --git a/test/runtime/samples/spread-each-component/_config.js b/test/runtime/samples/spread-each-component/_config.js index bc4d8ee7a4..66d2381875 100644 --- a/test/runtime/samples/spread-each-component/_config.js +++ b/test/runtime/samples/spread-each-component/_config.js @@ -20,5 +20,5 @@ export default {
`); - }, + } }; diff --git a/test/runtime/samples/spread-each-element/_config.js b/test/runtime/samples/spread-each-element/_config.js index 5dbd82a892..579f840099 100644 --- a/test/runtime/samples/spread-each-element/_config.js +++ b/test/runtime/samples/spread-each-element/_config.js @@ -20,5 +20,5 @@ export default {
`); - }, + } }; diff --git a/test/runtime/samples/spread-element-boolean/_config.js b/test/runtime/samples/spread-element-boolean/_config.js index 3ee277eec4..d336dae029 100644 --- a/test/runtime/samples/spread-element-boolean/_config.js +++ b/test/runtime/samples/spread-element-boolean/_config.js @@ -21,5 +21,5 @@ export default { `` ); assert.ok(!button.disabled); - }, + } }; diff --git a/test/runtime/samples/spread-element-input-select-multiple/_config.js b/test/runtime/samples/spread-element-input-select-multiple/_config.js new file mode 100644 index 0000000000..1ddcd9eb6d --- /dev/null +++ b/test/runtime/samples/spread-element-input-select-multiple/_config.js @@ -0,0 +1,39 @@ +export default { + async test({ assert, component, target, window }) { + const [input1, input2] = target.querySelectorAll('input'); + const select = target.querySelector('select'); + const [option1, option2] = select.childNodes; + + let selections = Array.from(select.selectedOptions); + assert.equal(selections.length, 2); + assert.ok(selections.includes(option1)); + assert.ok(selections.includes(option2)); + + const event = new window.Event('change'); + + input1.checked = false; + await input1.dispatchEvent(event); + + selections = Array.from(select.selectedOptions); + assert.equal(selections.length, 1); + assert.ok(!selections.includes(option1)); + assert.ok(selections.includes(option2)); + + input2.checked = false; + await input2.dispatchEvent(event); + input1.checked = true; + await input1.dispatchEvent(event); + + selections = Array.from(select.selectedOptions); + assert.equal(selections.length, 1); + assert.ok(selections.includes(option1)); + assert.ok(!selections.includes(option2)); + + component.spread = { value: ['Hello', 'World'] }; + + selections = Array.from(select.selectedOptions); + assert.equal(selections.length, 2); + assert.ok(selections.includes(option1)); + assert.ok(selections.includes(option2)); + } +}; diff --git a/test/runtime/samples/spread-element-input-select-multiple/main.svelte b/test/runtime/samples/spread-element-input-select-multiple/main.svelte new file mode 100644 index 0000000000..d2fb12dd20 --- /dev/null +++ b/test/runtime/samples/spread-element-input-select-multiple/main.svelte @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/test/runtime/samples/spread-element-input-value-undefined/_config.js b/test/runtime/samples/spread-element-input-value-undefined/_config.js new file mode 100644 index 0000000000..d66e215cde --- /dev/null +++ b/test/runtime/samples/spread-element-input-value-undefined/_config.js @@ -0,0 +1,12 @@ +export default { + async test({ assert, component, target, window }) { + const input = target.querySelector("input"); + component.value = undefined; + + assert.equal(input.value, "undefined"); + + component.value = "foobar"; + + assert.equal(input.value, "foobar"); + } +}; diff --git a/test/runtime/samples/spread-element-input-value-undefined/main.svelte b/test/runtime/samples/spread-element-input-value-undefined/main.svelte new file mode 100644 index 0000000000..5c9121dc03 --- /dev/null +++ b/test/runtime/samples/spread-element-input-value-undefined/main.svelte @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/test/runtime/samples/spread-element-input-value/InputOne.svelte b/test/runtime/samples/spread-element-input-value/InputOne.svelte new file mode 100644 index 0000000000..92ecb7b9a9 --- /dev/null +++ b/test/runtime/samples/spread-element-input-value/InputOne.svelte @@ -0,0 +1,18 @@ + + + diff --git a/test/runtime/samples/spread-element-input-value/InputTwo.svelte b/test/runtime/samples/spread-element-input-value/InputTwo.svelte new file mode 100644 index 0000000000..33ec0622a4 --- /dev/null +++ b/test/runtime/samples/spread-element-input-value/InputTwo.svelte @@ -0,0 +1,19 @@ + + + diff --git a/test/runtime/samples/spread-element-input-value/_config.js b/test/runtime/samples/spread-element-input-value/_config.js new file mode 100644 index 0000000000..abb63ceab3 --- /dev/null +++ b/test/runtime/samples/spread-element-input-value/_config.js @@ -0,0 +1,62 @@ +export default { + async test({ assert, component, target, window }) { + const [input1, input2] = target.querySelectorAll("input"); + + // we are not able emulate user interaction in jsdom, + // therefore, jsdom could not validate minlength / maxlength + + // we simulate user input with + // setting input.value + dispathEvent + + // and we determine if svelte does not set the `input.value` again by + // spying on the setter of `input.value` + + const spy1 = spyOnValueSetter(input1, input1.value); + const spy2 = spyOnValueSetter(input2, input2.value); + + const event = new window.Event("input"); + + input1.value = '12345'; + spy1.reset(); + await input1.dispatchEvent(event); + + assert.ok(!spy1.isSetCalled()); + + input2.value = '12345'; + spy2.reset(); + await input2.dispatchEvent(event); + + assert.ok(!spy2.isSetCalled()); + + spy1.reset(); + component.val1 = '56789'; + assert.ok(spy1.isSetCalled()); + + spy2.reset(); + component.val2 = '56789'; + assert.ok(spy2.isSetCalled()); + } +}; + +function spyOnValueSetter(input, initialValue) { + let value = initialValue; + let isSet = false; + Object.defineProperty(input, "value", { + get() { + return value; + }, + set(_value) { + value = _value; + isSet = true; + } + }); + + return { + isSetCalled() { + return isSet; + }, + reset() { + isSet = false; + } + }; +} diff --git a/test/runtime/samples/spread-element-input-value/main.svelte b/test/runtime/samples/spread-element-input-value/main.svelte new file mode 100644 index 0000000000..bb5f0e00bf --- /dev/null +++ b/test/runtime/samples/spread-element-input-value/main.svelte @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/test/runtime/samples/spread-element-input-value/utils.js b/test/runtime/samples/spread-element-input-value/utils.js new file mode 100644 index 0000000000..ee941bda55 --- /dev/null +++ b/test/runtime/samples/spread-element-input-value/utils.js @@ -0,0 +1,6 @@ +export function omit(obj, ...keysToOmit) { + return Object.keys(obj).reduce((acc, key) => { + if (keysToOmit.indexOf(key) === -1) acc[key] = obj[key]; + return acc; + }, {}); +} diff --git a/test/runtime/samples/spread-element-multiple-dependencies/_config.js b/test/runtime/samples/spread-element-multiple-dependencies/_config.js index 69ef1f8ebe..480eb6621c 100644 --- a/test/runtime/samples/spread-element-multiple-dependencies/_config.js +++ b/test/runtime/samples/spread-element-multiple-dependencies/_config.js @@ -6,5 +6,5 @@ export default { target.innerHTML, `
` ); - }, + } }; diff --git a/test/runtime/samples/spread-element-multiple/_config.js b/test/runtime/samples/spread-element-multiple/_config.js index 641f74d727..0c04b16d40 100644 --- a/test/runtime/samples/spread-element-multiple/_config.js +++ b/test/runtime/samples/spread-element-multiple/_config.js @@ -2,12 +2,12 @@ export default { props: { a: { 'data-one': 1, - 'data-two': 2, + 'data-two': 2 }, c: { - 'data-b': 'overridden', + 'data-b': 'overridden' }, - d: 'deeeeee', + d: 'deeeeee' }, html: ` @@ -27,5 +27,5 @@ export default { target.innerHTML, `
test
` ); - }, + } }; diff --git a/test/runtime/samples/store-auto-subscribe-event-callback/_config.js b/test/runtime/samples/store-auto-subscribe-event-callback/_config.js index 747ed3e4ad..7897036809 100644 --- a/test/runtime/samples/store-auto-subscribe-event-callback/_config.js +++ b/test/runtime/samples/store-auto-subscribe-event-callback/_config.js @@ -18,5 +18,5 @@ export default { Dirty: true Valid: true `); - }, + } }; diff --git a/test/runtime/samples/store-each-binding-deep/_config.js b/test/runtime/samples/store-each-binding-deep/_config.js new file mode 100644 index 0000000000..70776940dd --- /dev/null +++ b/test/runtime/samples/store-each-binding-deep/_config.js @@ -0,0 +1,14 @@ +export default { + async test({ assert, target, window }) { + const input = target.querySelector('input'); + + const event = new window.Event('input'); + input.value = 'changed'; + await input.dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` + +

changed

+ `); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/store-each-binding-deep/main.svelte b/test/runtime/samples/store-each-binding-deep/main.svelte new file mode 100644 index 0000000000..8f1cabf5b8 --- /dev/null +++ b/test/runtime/samples/store-each-binding-deep/main.svelte @@ -0,0 +1,11 @@ + + +{#each $itemStore.prop.things as thing } + +{/each} + +

{$itemStore.prop.things[0].name}

\ No newline at end of file diff --git a/test/runtime/samples/store-imports-hoisted/_config.js b/test/runtime/samples/store-imports-hoisted/_config.js new file mode 100644 index 0000000000..251866e5ba --- /dev/null +++ b/test/runtime/samples/store-imports-hoisted/_config.js @@ -0,0 +1,7 @@ +export default { + compileOptions: { dev: true }, // tests `@validate_store` code generation + + html: ` +

42

+ ` +}; \ No newline at end of file diff --git a/test/runtime/samples/store-imports-hoisted/foo.js b/test/runtime/samples/store-imports-hoisted/foo.js new file mode 100644 index 0000000000..5d15213c3a --- /dev/null +++ b/test/runtime/samples/store-imports-hoisted/foo.js @@ -0,0 +1,3 @@ +import { writable } from '../../../../store'; + +export default writable(42); \ No newline at end of file diff --git a/test/runtime/samples/store-imports-hoisted/main.svelte b/test/runtime/samples/store-imports-hoisted/main.svelte new file mode 100644 index 0000000000..223572962e --- /dev/null +++ b/test/runtime/samples/store-imports-hoisted/main.svelte @@ -0,0 +1,7 @@ + + +

{answer}

diff --git a/test/runtime/samples/store-resubscribe-b/_config.js b/test/runtime/samples/store-resubscribe-b/_config.js index d043bbcd87..dd11a863f2 100644 --- a/test/runtime/samples/store-resubscribe-b/_config.js +++ b/test/runtime/samples/store-resubscribe-b/_config.js @@ -1,3 +1,3 @@ export default { - html: `42`, + html: `42` }; diff --git a/test/runtime/samples/store-resubscribe-export/_config.js b/test/runtime/samples/store-resubscribe-export/_config.js index b6e6f11344..3c8473b3e1 100644 --- a/test/runtime/samples/store-resubscribe-export/_config.js +++ b/test/runtime/samples/store-resubscribe-export/_config.js @@ -6,14 +6,14 @@ const fakeStore = val => ({ return { unsubscribe: () => { subscribeCalled = true; - }, + } }; - }, + } }); export default { props: { - foo: fakeStore(1), + foo: fakeStore(1) }, html: `

1

@@ -23,5 +23,5 @@ export default { component.foo = fakeStore(5); return assert.htmlEqual(target.innerHTML, `

5

`); - }, + } }; diff --git a/test/runtime/samples/store-resubscribe-observable/_config.js b/test/runtime/samples/store-resubscribe-observable/_config.js index d043bbcd87..dd11a863f2 100644 --- a/test/runtime/samples/store-resubscribe-observable/_config.js +++ b/test/runtime/samples/store-resubscribe-observable/_config.js @@ -1,3 +1,3 @@ export default { - html: `42`, + html: `42` }; diff --git a/test/runtime/samples/store-shadow-scope/_config.js b/test/runtime/samples/store-shadow-scope/_config.js new file mode 100644 index 0000000000..e2d6fc7808 --- /dev/null +++ b/test/runtime/samples/store-shadow-scope/_config.js @@ -0,0 +1,3 @@ +export default { + error: `Stores must be declared at the top level of the component (this may change in a future version of Svelte)` +}; diff --git a/test/runtime/samples/store-shadow-scope/main.svelte b/test/runtime/samples/store-shadow-scope/main.svelte new file mode 100644 index 0000000000..72c4a06c2a --- /dev/null +++ b/test/runtime/samples/store-shadow-scope/main.svelte @@ -0,0 +1,9 @@ + diff --git a/test/runtime/samples/store-template-expression-scope/_config.js b/test/runtime/samples/store-template-expression-scope/_config.js new file mode 100644 index 0000000000..e2d6fc7808 --- /dev/null +++ b/test/runtime/samples/store-template-expression-scope/_config.js @@ -0,0 +1,3 @@ +export default { + error: `Stores must be declared at the top level of the component (this may change in a future version of Svelte)` +}; diff --git a/test/runtime/samples/store-template-expression-scope/main.svelte b/test/runtime/samples/store-template-expression-scope/main.svelte new file mode 100644 index 0000000000..1c9ccb2933 --- /dev/null +++ b/test/runtime/samples/store-template-expression-scope/main.svelte @@ -0,0 +1,9 @@ + + + + diff --git a/test/validator/samples/a11y-label-has-associated-control/warnings.json b/test/validator/samples/a11y-label-has-associated-control/warnings.json new file mode 100644 index 0000000000..b70a1a47de --- /dev/null +++ b/test/validator/samples/a11y-label-has-associated-control/warnings.json @@ -0,0 +1,32 @@ +[ + { + "code": "a11y-label-has-associated-control", + "end": { + "character": 16, + "column": 16, + "line": 1 + }, + "message": "A11y: A form label must be associated with a control.", + "pos": 0, + "start": { + "character": 0, + "column": 0, + "line": 1 + } + }, + { + "code": "a11y-label-has-associated-control", + "end": { + "character": 149, + "column": 30, + "line": 6 + }, + "message": "A11y: A form label must be associated with a control.", + "pos": 119, + "start": { + "character": 119, + "column": 0, + "line": 6 + } + } +] diff --git a/test/validator/samples/a11y-media-has-caption/input.svelte b/test/validator/samples/a11y-media-has-caption/input.svelte new file mode 100644 index 0000000000..105269cddb --- /dev/null +++ b/test/validator/samples/a11y-media-has-caption/input.svelte @@ -0,0 +1,4 @@ + + + + diff --git a/test/validator/samples/a11y-media-has-caption/warnings.json b/test/validator/samples/a11y-media-has-caption/warnings.json new file mode 100644 index 0000000000..a8c894b1d4 --- /dev/null +++ b/test/validator/samples/a11y-media-has-caption/warnings.json @@ -0,0 +1,32 @@ +[ + { + "code": "a11y-media-has-caption", + "end": { + "character": 55, + "column": 15, + "line": 2 + }, + "message": "A11y: Media elements must have a ", + "pos": 40, + "start": { + "character": 40, + "column": 0, + "line": 2 + } + }, + { + "code": "a11y-media-has-caption", + "end": { + "character": 80, + "column": 24, + "line": 3 + }, + "message": "A11y: Media elements must have a ", + "pos": 56, + "start": { + "character": 56, + "column": 0, + "line": 3 + } + } +] diff --git a/test/vars/samples/assumed-global/_config.js b/test/vars/samples/assumed-global/_config.js index 2b84e83f12..782760bb8b 100644 --- a/test/vars/samples/assumed-global/_config.js +++ b/test/vars/samples/assumed-global/_config.js @@ -1,5 +1,5 @@ export default { test(assert, vars) { assert.deepEqual(vars, []); - }, + } }; diff --git a/test/vars/samples/duplicate-globals/_config.js b/test/vars/samples/duplicate-globals/_config.js index 2b84e83f12..782760bb8b 100644 --- a/test/vars/samples/duplicate-globals/_config.js +++ b/test/vars/samples/duplicate-globals/_config.js @@ -1,5 +1,5 @@ export default { test(assert, vars) { assert.deepEqual(vars, []); - }, + } }; diff --git a/test/vars/samples/duplicate-non-hoistable/_config.js b/test/vars/samples/duplicate-non-hoistable/_config.js index 4ebc5b00cf..bd70e29800 100644 --- a/test/vars/samples/duplicate-non-hoistable/_config.js +++ b/test/vars/samples/duplicate-non-hoistable/_config.js @@ -13,5 +13,5 @@ export default { writable: true } ]); - }, + } }; diff --git a/test/vars/samples/duplicate-vars/_config.js b/test/vars/samples/duplicate-vars/_config.js index eb10c44a9a..749a0c59af 100644 --- a/test/vars/samples/duplicate-vars/_config.js +++ b/test/vars/samples/duplicate-vars/_config.js @@ -24,5 +24,5 @@ export default { writable: true } ]); - }, + } }; diff --git a/test/vars/samples/implicit-reactive/_config.js b/test/vars/samples/implicit-reactive/_config.js index 770de590e6..a8bf261d4f 100644 --- a/test/vars/samples/implicit-reactive/_config.js +++ b/test/vars/samples/implicit-reactive/_config.js @@ -24,5 +24,5 @@ export default { writable: true } ]); - }, + } }; diff --git a/test/vars/samples/referenced-from-script/_config.js b/test/vars/samples/referenced-from-script/_config.js index 191a52f8cc..ec068cb1d7 100644 --- a/test/vars/samples/referenced-from-script/_config.js +++ b/test/vars/samples/referenced-from-script/_config.js @@ -10,7 +10,7 @@ export default { reassigned: false, referenced: false, writable: false, - referenced_from_script: false, + referenced_from_script: false }, { name: 'j', @@ -21,7 +21,7 @@ export default { reassigned: false, referenced: false, writable: false, - referenced_from_script: false, + referenced_from_script: false }, { name: 'k', @@ -32,7 +32,7 @@ export default { reassigned: false, referenced: false, writable: false, - referenced_from_script: false, + referenced_from_script: false }, { name: 'a', @@ -43,7 +43,7 @@ export default { reassigned: true, referenced: false, writable: true, - referenced_from_script: true, + referenced_from_script: true }, { name: 'b', @@ -54,7 +54,7 @@ export default { reassigned: false, referenced: false, writable: true, - referenced_from_script: true, + referenced_from_script: true }, { name: 'c', @@ -65,7 +65,7 @@ export default { reassigned: false, referenced: false, writable: true, - referenced_from_script: true, + referenced_from_script: true }, { name: 'd', @@ -76,7 +76,7 @@ export default { reassigned: false, referenced: false, writable: true, - referenced_from_script: true, + referenced_from_script: true }, { name: 'e', @@ -87,7 +87,7 @@ export default { reassigned: false, referenced: false, writable: true, - referenced_from_script: false, + referenced_from_script: false }, { name: 'f', @@ -98,7 +98,7 @@ export default { reassigned: false, referenced: false, writable: true, - referenced_from_script: false, + referenced_from_script: false }, { name: 'g', @@ -109,7 +109,7 @@ export default { reassigned: false, referenced: false, writable: true, - referenced_from_script: true, + referenced_from_script: true }, { name: 'h', @@ -120,7 +120,7 @@ export default { reassigned: true, referenced: false, writable: true, - referenced_from_script: true, + referenced_from_script: true }, { name: 'foo', @@ -131,7 +131,7 @@ export default { reassigned: false, referenced: false, writable: false, - referenced_from_script: false, + referenced_from_script: false }, { name: 'l', @@ -142,7 +142,7 @@ export default { reassigned: false, referenced: false, referenced_from_script: true, - writable: false, + writable: false }, { name: 'bar', @@ -153,8 +153,8 @@ export default { reassigned: false, referenced: false, writable: false, - referenced_from_script: false, - }, + referenced_from_script: false + } ]); - }, + } }; diff --git a/test/vars/samples/template-references/_config.js b/test/vars/samples/template-references/_config.js index 674e351517..34c07e19e0 100644 --- a/test/vars/samples/template-references/_config.js +++ b/test/vars/samples/template-references/_config.js @@ -10,7 +10,7 @@ export default { reassigned: false, referenced: true, referenced_from_script: false, - writable: false, + writable: false }, { export_name: null, @@ -21,7 +21,7 @@ export default { reassigned: false, referenced: true, referenced_from_script: false, - writable: true, + writable: true }, { export_name: null, @@ -32,8 +32,8 @@ export default { reassigned: false, referenced: true, referenced_from_script: false, - writable: true, - }, + writable: true + } ]); - }, + } }; diff --git a/test/vars/samples/undeclared/_config.js b/test/vars/samples/undeclared/_config.js index 2b84e83f12..782760bb8b 100644 --- a/test/vars/samples/undeclared/_config.js +++ b/test/vars/samples/undeclared/_config.js @@ -1,5 +1,5 @@ export default { test(assert, vars) { assert.deepEqual(vars, []); - }, + } };