diff --git a/.gitignore b/.gitignore index 7a14244929..f7fac04eba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .idea .DS_Store .nyc_output +.vscode node_modules *.map /src/compiler/compile/internal_exports.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 759aabfd7d..cbab1872dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,50 @@ ## Unreleased +* Fix attaching of JS debugging comments to HTML comments ([#4565](https://github.com/sveltejs/svelte/issues/4565)) + +## 3.20.1 + +* Fix compiler regression with slots ([#4562](https://github.com/sveltejs/svelte/issues/4562)) + +## 3.20.0 + +* Allow destructuring in `{#await}` blocks ([#1851](https://github.com/sveltejs/svelte/issues/1851)) +* Allow `` to be used in a slot ([#2798](https://github.com/sveltejs/svelte/issues/2798)) +* Expose object of unknown props in `$$restProps` ([#2930](https://github.com/sveltejs/svelte/issues/2930)) +* Prevent passing named slots other than from the top level within a component ([#3385](https://github.com/sveltejs/svelte/issues/3385)) +* Allow transitions and animations to work within iframes ([#3624](https://github.com/sveltejs/svelte/issues/3624)) +* Fix initialising slot fallbacks when unnecessary ([#3763](https://github.com/sveltejs/svelte/issues/3763)) +* Disallow binding directly to `const` variables ([#4479](https://github.com/sveltejs/svelte/issues/4479)) +* Fix re-attaching event handlers on keyed `{#each}` blocks ([#4491](https://github.com/sveltejs/svelte/issues/4491)) +* Fix updating keyed `{#each}` blocks with `{:else}` ([#4536](https://github.com/sveltejs/svelte/issues/4536), [#4549](https://github.com/sveltejs/svelte/issues/4549)) +* Fix hydration of top-level content ([#4542](https://github.com/sveltejs/svelte/issues/4542)) + +## 3.19.2 + +* In `dev` mode, display a runtime warning when a component is passed an unexpected slot ([#1020](https://github.com/sveltejs/svelte/issues/1020), [#1447](https://github.com/sveltejs/svelte/issues/1447)) +* In `vars` array, correctly indicate whether `module` variables are `mutated` or `reassigned` ([#3215](https://github.com/sveltejs/svelte/issues/3215)) +* Fix spread props not updating in certain situations ([#3521](https://github.com/sveltejs/svelte/issues/3521), [#4480](https://github.com/sveltejs/svelte/issues/4480)) +* Use the fallback content for slots if they are passed only whitespace ([#4092](https://github.com/sveltejs/svelte/issues/4092)) +* Fix bitmask overflow for `{#if}` blocks ([#4263](https://github.com/sveltejs/svelte/issues/4263)) +* In `dev` mode, check for unknown props even if the component has no writable props ([#4323](https://github.com/sveltejs/svelte/issues/4323)) +* Exclude global variables from `$capture_state` ([#4463](https://github.com/sveltejs/svelte/issues/4463)) +* Fix bitmask overflow for slots ([#4481](https://github.com/sveltejs/svelte/issues/4481)) + +## 3.19.1 + +* Do not treat modifications to `$$props` as updates to a store called `$props` ([#4368](https://github.com/sveltejs/svelte/issues/4368)) +* Deconflict `value` parameter name used in contextual bindings ([#4445](https://github.com/sveltejs/svelte/issues/4445)) +* Fix dev mode validation of `{#each}` blocks using strings ([#4450](https://github.com/sveltejs/svelte/issues/4450)) + +## 3.19.0 + * Fix indirect bindings involving elements with spreads ([#3680](https://github.com/sveltejs/svelte/issues/3680)) +* `$capture_state`/`$inject_state` now act on the component's entire state, rather than its props ([#3822](https://github.com/sveltejs/svelte/pull/3822)) * Warn when using `` and `Foo` is dynamic ([#4331](https://github.com/sveltejs/svelte/issues/4331)) +* Display compilation warnings in `svelte/register` in dev mode ([#4364](https://github.com/sveltejs/svelte/issues/4364)) * Fix unneeded updating of keyed each blocks ([#4373](https://github.com/sveltejs/svelte/issues/4373)) +* Throw runtime error in dev mode for non-array-like values in `{#each}` blocks ([#4408](https://github.com/sveltejs/svelte/issues/4408)) ## 3.18.2 diff --git a/README.md b/README.md index e05154bd7c..fa725804a9 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,6 @@ npm version - - build status - - license @@ -37,6 +32,8 @@ cd svelte npm install ``` +> Do not use Yarn to install the dependencies, as the specific package versions in `package-lock.json` are used to build and test Svelte. + > Many tests depend on newlines being preserved as ``. On Windows, you can ensure this by cloning with: > ```bash > git -c core.autocrlf=false clone https://github.com/sveltejs/svelte.git diff --git a/banner.png b/banner.png deleted file mode 100644 index 0d117c3c09..0000000000 Binary files a/banner.png and /dev/null differ diff --git a/package-lock.json b/package-lock.json index 088fffd543..5114095057 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.18.2", + "version": "3.20.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -137,6 +137,12 @@ } } }, + "@tootallnate/once": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.0.0.tgz", + "integrity": "sha512-KYyTT/T6ALPkIRd2Ge080X/BsXvy9O0hcWTtMWkPvwAwF99+vn6Dv4GzrFT/Nn1LePr+FFDbRXXlqmsy9lw2zA==", + "dev": true + }, "@types/eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", @@ -274,9 +280,9 @@ "dev": true }, "acorn": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", - "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", "dev": true }, "acorn-globals": { @@ -609,16 +615,16 @@ } }, "codecov": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.5.0.tgz", - "integrity": "sha512-/OsWOfIHaQIr7aeZ4pY0UC1PZT6kimoKFOFYFNb6wxo3iw12nRrh+mNGH72rnXxNsq6SGfesVPizm/6Q3XqcFQ==", + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.6.5.tgz", + "integrity": "sha512-v48WuDMUug6JXwmmfsMzhCHRnhUf8O3duqXvltaYJKrO1OekZWpB/eH6iIoaxMl8Qli0+u3OxptdsBOYiD7VAQ==", "dev": true, "requires": { - "argv": "^0.0.2", - "ignore-walk": "^3.0.1", - "js-yaml": "^3.13.1", - "teeny-request": "^3.11.3", - "urlgrey": "^0.4.4" + "argv": "0.0.2", + "ignore-walk": "3.0.3", + "js-yaml": "3.13.1", + "teeny-request": "6.0.1", + "urlgrey": "0.4.4" } }, "color-convert": { @@ -1670,6 +1676,37 @@ "whatwg-encoding": "^1.0.1" } }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "agent-base": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.0.tgz", + "integrity": "sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -1707,9 +1744,9 @@ "dev": true }, "ignore-walk": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", + "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", "dev": true, "requires": { "minimatch": "^3.0.4" @@ -3362,6 +3399,15 @@ "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", "dev": true }, + "stream-events": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", + "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "dev": true, + "requires": { + "stubs": "^3.0.0" + } + }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -3409,6 +3455,12 @@ "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", "dev": true }, + "stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=", + "dev": true + }, "sucrase": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.10.1.tgz", @@ -3449,14 +3501,43 @@ } }, "teeny-request": { - "version": "3.11.3", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", - "integrity": "sha512-CKncqSF7sH6p4rzCgkb/z/Pcos5efl0DmolzvlqRQUNcpRIruOhY9+T1FsIlyEbfWd7MsFpodROOwHYh2BaXzw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-6.0.1.tgz", + "integrity": "sha512-TAK0c9a00ELOqLrZ49cFxvPVogMUFaWY8dUsQc/0CuQPGF+BOxOQzXfE413BAk2kLomwNplvdtMpeaeGWmoc2g==", "dev": true, "requires": { - "https-proxy-agent": "^2.2.1", + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^4.0.0", "node-fetch": "^2.2.0", + "stream-events": "^1.0.5", "uuid": "^3.3.2" + }, + "dependencies": { + "agent-base": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "https-proxy-agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "dev": true, + "requires": { + "agent-base": "5", + "debug": "4" + } + } } }, "test-exclude": { diff --git a/package.json b/package.json index 52ae0d95ac..f8e8e4ddb0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.18.2", + "version": "3.20.1", "description": "Cybernetically enhanced web apps", "module": "index.mjs", "main": "index", diff --git a/register.js b/register.js index 3278c1cbf5..25f8aa4309 100644 --- a/register.js +++ b/register.js @@ -36,7 +36,15 @@ function registerExtension(extension) { format: 'cjs' }); - const { js } = compile(fs.readFileSync(filename, 'utf-8'), options); + const { js, warnings } = compile(fs.readFileSync(filename, 'utf-8'), options); + + if (options.dev) { + warnings.forEach(warning => { + console.warn(`\nSvelte Warning in ${warning.filename}:`); + console.warn(warning.message); + console.warn(warning.frame); + }) + } return module._compile(js.code, filename); }; diff --git a/site/content/docs/01-component-format.md b/site/content/docs/01-component-format.md index 026a2da5b3..07a59c69f8 100644 --- a/site/content/docs/01-component-format.md +++ b/site/content/docs/01-component-format.md @@ -42,13 +42,13 @@ Svelte uses the `export` keyword to mark a variable declaration as a *property* --- -You can specify a default value, which will be used if the component's consumer doesn't specify a prop. +You can specify a default initial value for a prop. It will be used if the component's consumer doesn't specify the prop on the component (or if its initial value is `undefined`) when instantiating the component. Note that whenever a prop is removed by the consumer, its value is set to `undefined` rather than the initial value. -In development mode (see the [compiler options](docs#svelte_compile)), a warning will be printed if no default is provided and the consumer does not specify a value. To squelch this warning, ensure that a default is specified, even if it is `undefined`. +In development mode (see the [compiler options](docs#svelte_compile)), a warning will be printed if no default initial value is provided and the consumer does not specify a value. To squelch this warning, ensure that a default initial value is specified, even if it is `undefined`. ```html ``` diff --git a/site/content/docs/02-template-syntax.md b/site/content/docs/02-template-syntax.md index 0a4ca2ee1a..ea36474bed 100644 --- a/site/content/docs/02-template-syntax.md +++ b/site/content/docs/02-template-syntax.md @@ -58,6 +58,17 @@ Or they can *be* JavaScript expressions. --- +Boolean attributes are included on the element if their value is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) and excluded if it's [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy). + +All other attributes are included unless their value is [nullish](https://developer.mozilla.org/en-US/docs/Glossary/Nullish) (`null` or `undefined`). + +```html + +
This div has no title attribute
+``` + +--- + An expression might include characters that would cause syntax highlighting to fail in regular HTML, so quoting the value is permitted. The quotes do not affect how the value is parsed: ```html @@ -102,6 +113,15 @@ An element or component can have multiple spread attributes, interspersed with r ``` +--- + +*`$$restProps`* contains only the props which are *not* declared with `export`. It can be used to pass down other unknown attributes to an element in a component. + +```html + +``` + +--- ### Text expressions @@ -795,7 +815,7 @@ transition = (node: HTMLElement, params: any) => { A transition is triggered by an element entering or leaving the DOM as a result of a state change. -Elements inside an *outroing* block are kept in the DOM until all current transitions have completed. +When a block is transitioning out, elements inside the block are kept in the DOM until all current transitions have completed. The `transition:` directive indicates a *bidirectional* transition, which means it can be smoothly reversed while the transition is in progress. @@ -1249,15 +1269,15 @@ The usual shorthand rules apply — `let:item` is equivalent to `let:item={item} ```html - -
{item.text}
+ +
{thing.text}
    {#each items as item}
  • - +
  • {/each}
@@ -1270,7 +1290,7 @@ Named slots can also expose values. The `let:` directive goes on the element wit ```html -
{item.text}
+
{item.text}

Copyright (c) 2019 Svelte Industries

@@ -1278,7 +1298,7 @@ Named slots can also expose values. The `let:` directive goes on the element wit
    {#each items as item}
  • - +
  • {/each}
diff --git a/site/content/docs/03-run-time.md b/site/content/docs/03-run-time.md index c75ec694d9..0bbae24185 100644 --- a/site/content/docs/03-run-time.md +++ b/site/content/docs/03-run-time.md @@ -974,7 +974,7 @@ app.count += 1; Svelte components can also be compiled to custom elements (aka web components) using the `customElement: true` compiler option. You should specify a tag name for the component using the `` [element](docs#svelte_options). ```html - + - \ No newline at end of file + \ No newline at end of file diff --git a/site/content/examples/04-events/05-dom-event-forwarding/CustomButton.svelte b/site/content/examples/04-events/05-dom-event-forwarding/CustomButton.svelte new file mode 100644 index 0000000000..f521c1f471 --- /dev/null +++ b/site/content/examples/04-events/05-dom-event-forwarding/CustomButton.svelte @@ -0,0 +1,22 @@ + + + \ No newline at end of file diff --git a/site/content/examples/04-events/05-dom-event-forwarding/FancyButton.svelte b/site/content/examples/04-events/05-dom-event-forwarding/FancyButton.svelte deleted file mode 100644 index 68dcc68636..0000000000 --- a/site/content/examples/04-events/05-dom-event-forwarding/FancyButton.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - - \ No newline at end of file diff --git a/site/content/tutorial/05-events/06-dom-event-forwarding/app-a/App.svelte b/site/content/tutorial/05-events/06-dom-event-forwarding/app-a/App.svelte index 1429cae207..e75c78106a 100644 --- a/site/content/tutorial/05-events/06-dom-event-forwarding/app-a/App.svelte +++ b/site/content/tutorial/05-events/06-dom-event-forwarding/app-a/App.svelte @@ -1,9 +1,9 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/site/content/tutorial/05-events/06-dom-event-forwarding/app-a/CustomButton.svelte b/site/content/tutorial/05-events/06-dom-event-forwarding/app-a/CustomButton.svelte new file mode 100644 index 0000000000..0955930b5d --- /dev/null +++ b/site/content/tutorial/05-events/06-dom-event-forwarding/app-a/CustomButton.svelte @@ -0,0 +1,22 @@ + + + \ No newline at end of file diff --git a/site/content/tutorial/05-events/06-dom-event-forwarding/app-a/FancyButton.svelte b/site/content/tutorial/05-events/06-dom-event-forwarding/app-a/FancyButton.svelte deleted file mode 100644 index b75f19a1f2..0000000000 --- a/site/content/tutorial/05-events/06-dom-event-forwarding/app-a/FancyButton.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - - \ No newline at end of file diff --git a/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/App.svelte b/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/App.svelte index 1429cae207..e75c78106a 100644 --- a/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/App.svelte +++ b/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/App.svelte @@ -1,9 +1,9 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/CustomButton.svelte b/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/CustomButton.svelte new file mode 100644 index 0000000000..f521c1f471 --- /dev/null +++ b/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/CustomButton.svelte @@ -0,0 +1,22 @@ + + + \ No newline at end of file diff --git a/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/FancyButton.svelte b/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/FancyButton.svelte deleted file mode 100644 index 68dcc68636..0000000000 --- a/site/content/tutorial/05-events/06-dom-event-forwarding/app-b/FancyButton.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - - \ No newline at end of file diff --git a/site/content/tutorial/05-events/06-dom-event-forwarding/text.md b/site/content/tutorial/05-events/06-dom-event-forwarding/text.md index 0959e1d98b..be9ae77f89 100644 --- a/site/content/tutorial/05-events/06-dom-event-forwarding/text.md +++ b/site/content/tutorial/05-events/06-dom-event-forwarding/text.md @@ -4,7 +4,7 @@ title: DOM event forwarding Event forwarding works for DOM events too. -We want to get notified of clicks on our `` — to do that, we just need to forward `click` events on the ` \ No newline at end of file + \ No newline at end of file diff --git a/test/custom-elements/samples/extended-builtin/test.js b/test/custom-elements/samples/extended-builtin/test.js index d676fd137b..3886ae1149 100644 --- a/test/custom-elements/samples/extended-builtin/test.js +++ b/test/custom-elements/samples/extended-builtin/test.js @@ -11,5 +11,5 @@ export default function (target) { const el = target.querySelector('custom-element'); const button = el.shadowRoot.querySelector('button'); - assert.ok(button instanceof customElements.get('fancy-button')); + assert.ok(button instanceof customElements.get('custom-button')); } \ No newline at end of file diff --git a/test/hydration/samples/top-level-cleanup-2/_after.html b/test/hydration/samples/top-level-cleanup-2/_after.html new file mode 100644 index 0000000000..8dca56dd88 --- /dev/null +++ b/test/hydration/samples/top-level-cleanup-2/_after.html @@ -0,0 +1 @@ +
Hello world
\ No newline at end of file diff --git a/test/hydration/samples/top-level-cleanup-2/_before.html b/test/hydration/samples/top-level-cleanup-2/_before.html new file mode 100644 index 0000000000..fdc2379f63 --- /dev/null +++ b/test/hydration/samples/top-level-cleanup-2/_before.html @@ -0,0 +1,2 @@ +
This should be thrown away
+
hello
\ No newline at end of file diff --git a/test/hydration/samples/top-level-cleanup-2/_config.js b/test/hydration/samples/top-level-cleanup-2/_config.js new file mode 100644 index 0000000000..ff8b4c5632 --- /dev/null +++ b/test/hydration/samples/top-level-cleanup-2/_config.js @@ -0,0 +1 @@ +export default {}; diff --git a/test/hydration/samples/top-level-cleanup-2/main.svelte b/test/hydration/samples/top-level-cleanup-2/main.svelte new file mode 100644 index 0000000000..8dca56dd88 --- /dev/null +++ b/test/hydration/samples/top-level-cleanup-2/main.svelte @@ -0,0 +1 @@ +
Hello world
\ No newline at end of file diff --git a/test/hydration/samples/top-level-cleanup/_after.html b/test/hydration/samples/top-level-cleanup/_after.html new file mode 100644 index 0000000000..8dca56dd88 --- /dev/null +++ b/test/hydration/samples/top-level-cleanup/_after.html @@ -0,0 +1 @@ +
Hello world
\ No newline at end of file diff --git a/test/hydration/samples/top-level-cleanup/_before.html b/test/hydration/samples/top-level-cleanup/_before.html new file mode 100644 index 0000000000..c7e4bba233 --- /dev/null +++ b/test/hydration/samples/top-level-cleanup/_before.html @@ -0,0 +1 @@ +
This should be thrown away
\ No newline at end of file diff --git a/test/hydration/samples/top-level-cleanup/_config.js b/test/hydration/samples/top-level-cleanup/_config.js new file mode 100644 index 0000000000..ff8b4c5632 --- /dev/null +++ b/test/hydration/samples/top-level-cleanup/_config.js @@ -0,0 +1 @@ +export default {}; diff --git a/test/hydration/samples/top-level-cleanup/main.svelte b/test/hydration/samples/top-level-cleanup/main.svelte new file mode 100644 index 0000000000..8dca56dd88 --- /dev/null +++ b/test/hydration/samples/top-level-cleanup/main.svelte @@ -0,0 +1 @@ +
Hello world
\ No newline at end of file diff --git a/test/js/samples/action-custom-event-handler/expected.js b/test/js/samples/action-custom-event-handler/expected.js index ead6d90e06..aa2941f404 100644 --- a/test/js/samples/action-custom-event-handler/expected.js +++ b/test/js/samples/action-custom-event-handler/expected.js @@ -21,8 +21,9 @@ function create_fragment(ctx) { button = element("button"); button.textContent = "foo"; }, - m(target, anchor) { + m(target, anchor, remount) { insert(target, button, anchor); + if (remount) dispose(); dispose = action_destroyer(foo_action = foo.call(null, button, /*foo_function*/ ctx[1])); }, p(ctx, [dirty]) { diff --git a/test/js/samples/action/expected.js b/test/js/samples/action/expected.js index 22d9cd939c..1b3f5cc945 100644 --- a/test/js/samples/action/expected.js +++ b/test/js/samples/action/expected.js @@ -22,8 +22,9 @@ function create_fragment(ctx) { a.textContent = "Test"; attr(a, "href", "#"); }, - m(target, anchor) { + m(target, anchor, remount) { insert(target, a, anchor); + if (remount) dispose(); dispose = action_destroyer(link_action = link.call(null, a)); }, p: noop, diff --git a/test/js/samples/bind-online/expected.js b/test/js/samples/bind-online/expected.js index e129e66d71..fa955e4fd5 100644 --- a/test/js/samples/bind-online/expected.js +++ b/test/js/samples/bind-online/expected.js @@ -15,7 +15,9 @@ function create_fragment(ctx) { return { c: noop, - m(target, anchor) { + m(target, anchor, remount) { + if (remount) run_all(dispose); + dispose = [ listen(window, "online", /*onlinestatuschanged*/ ctx[1]), listen(window, "offline", /*onlinestatuschanged*/ ctx[1]) diff --git a/test/js/samples/bind-open/expected.js b/test/js/samples/bind-open/expected.js index 7d66145f0a..77b68f1b27 100644 --- a/test/js/samples/bind-open/expected.js +++ b/test/js/samples/bind-open/expected.js @@ -21,9 +21,10 @@ function create_fragment(ctx) { details.innerHTML = `summarycontent `; }, - m(target, anchor) { + m(target, anchor, remount) { insert(target, details, anchor); details.open = /*open*/ ctx[0]; + if (remount) dispose(); dispose = listen(details, "toggle", /*details_toggle_handler*/ ctx[1]); }, p(ctx, [dirty]) { diff --git a/test/js/samples/bindings-readonly-order/expected.js b/test/js/samples/bindings-readonly-order/expected.js index db0e7cb007..00e8a5bf00 100644 --- a/test/js/samples/bindings-readonly-order/expected.js +++ b/test/js/samples/bindings-readonly-order/expected.js @@ -27,10 +27,11 @@ function create_fragment(ctx) { attr(input0, "type", "file"); attr(input1, "type", "file"); }, - m(target, anchor) { + m(target, anchor, remount) { insert(target, input0, anchor); insert(target, t, anchor); insert(target, input1, anchor); + if (remount) run_all(dispose); dispose = [ listen(input0, "change", /*input0_change_handler*/ ctx[1]), diff --git a/test/js/samples/capture-inject-dev-only/expected.js b/test/js/samples/capture-inject-dev-only/expected.js index a314b0cff3..3e355e1491 100644 --- a/test/js/samples/capture-inject-dev-only/expected.js +++ b/test/js/samples/capture-inject-dev-only/expected.js @@ -29,12 +29,13 @@ function create_fragment(ctx) { t1 = space(); input = element("input"); }, - m(target, anchor) { + m(target, anchor, remount) { insert(target, p, anchor); append(p, t0); insert(target, t1, anchor); insert(target, input, anchor); set_input_value(input, /*foo*/ ctx[0]); + if (remount) dispose(); dispose = listen(input, "input", /*input_input_handler*/ ctx[1]); }, p(ctx, [dirty]) { diff --git a/test/js/samples/capture-inject-state/_config.js b/test/js/samples/capture-inject-state/_config.js new file mode 100644 index 0000000000..414b026a97 --- /dev/null +++ b/test/js/samples/capture-inject-state/_config.js @@ -0,0 +1,5 @@ +export default { + options: { + dev: true + } +}; diff --git a/test/js/samples/capture-inject-state/expected.js b/test/js/samples/capture-inject-state/expected.js new file mode 100644 index 0000000000..cd719ac5d2 --- /dev/null +++ b/test/js/samples/capture-inject-state/expected.js @@ -0,0 +1,201 @@ +/* generated by Svelte vX.Y.Z */ +import { + SvelteComponentDev, + add_location, + append_dev, + detach_dev, + dispatch_dev, + element, + init, + insert_dev, + noop, + safe_not_equal, + set_data_dev, + space, + subscribe, + text, + validate_slots, + validate_store +} from "svelte/internal"; + +const file = undefined; + +function create_fragment(ctx) { + let p; + let t0; + let t1; + let t2; + let t3; + let t4; + let t5; + let t6; + let t7; + let t8; + let t9; + let t10; + + const block = { + c: function create() { + p = element("p"); + t0 = text(/*prop*/ ctx[0]); + t1 = space(); + t2 = text(/*realName*/ ctx[1]); + t3 = space(); + t4 = text(/*local*/ ctx[3]); + t5 = space(); + t6 = text(priv); + t7 = space(); + t8 = text(/*$prop*/ ctx[2]); + t9 = space(); + t10 = text(/*shadowedByModule*/ ctx[4]); + add_location(p, file, 22, 0, 430); + }, + l: function claim(nodes) { + throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); + }, + m: function mount(target, anchor) { + insert_dev(target, p, anchor); + append_dev(p, t0); + append_dev(p, t1); + append_dev(p, t2); + append_dev(p, t3); + append_dev(p, t4); + append_dev(p, t5); + append_dev(p, t6); + append_dev(p, t7); + append_dev(p, t8); + append_dev(p, t9); + append_dev(p, t10); + }, + p: function update(ctx, [dirty]) { + if (dirty & /*prop*/ 1) set_data_dev(t0, /*prop*/ ctx[0]); + if (dirty & /*realName*/ 2) set_data_dev(t2, /*realName*/ ctx[1]); + if (dirty & /*$prop*/ 4) set_data_dev(t8, /*$prop*/ ctx[2]); + }, + i: noop, + o: noop, + d: function destroy(detaching) { + if (detaching) detach_dev(p); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_fragment.name, + type: "component", + source: "", + ctx + }); + + return block; +} + +let moduleLiveBinding; +const moduleContantProps = 4; +let moduleLet; +const moduleConst = 2; +let shadowedByModule; +const priv = "priv"; + +function instance($$self, $$props, $$invalidate) { + let $prop, + $$unsubscribe_prop = noop, + $$subscribe_prop = () => ($$unsubscribe_prop(), $$unsubscribe_prop = subscribe(prop, $$value => $$invalidate(2, $prop = $$value)), prop); + + $$self.$$.on_destroy.push(() => $$unsubscribe_prop()); + let { prop } = $$props; + validate_store(prop, "prop"); + $$subscribe_prop(); + let { alias: realName } = $$props; + let local; + let shadowedByModule; + const writable_props = ["prop", "alias"]; + + Object.keys($$props).forEach(key => { + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); + }); + + let { $$slots = {}, $$scope } = $$props; + validate_slots("Component", $$slots, []); + + $$self.$set = $$props => { + if ("prop" in $$props) $$subscribe_prop($$invalidate(0, prop = $$props.prop)); + if ("alias" in $$props) $$invalidate(1, realName = $$props.alias); + }; + + $$self.$capture_state = () => ({ + moduleLiveBinding, + moduleContantProps, + moduleLet, + moduleConst, + shadowedByModule, + prop, + realName, + local, + priv, + shadowedByModule, + computed, + $prop + }); + + $$self.$inject_state = $$props => { + if ("prop" in $$props) $$subscribe_prop($$invalidate(0, prop = $$props.prop)); + if ("realName" in $$props) $$invalidate(1, realName = $$props.realName); + if ("local" in $$props) $$invalidate(3, local = $$props.local); + if ("shadowedByModule" in $$props) $$invalidate(4, shadowedByModule = $$props.shadowedByModule); + if ("computed" in $$props) computed = $$props.computed; + }; + + let computed; + + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + + $: computed = local * 2; + return [prop, realName, $prop, local, shadowedByModule]; +} + +class Component extends SvelteComponentDev { + constructor(options) { + super(options); + init(this, options, instance, create_fragment, safe_not_equal, { prop: 0, alias: 1 }); + + dispatch_dev("SvelteRegisterComponent", { + component: this, + tagName: "Component", + options, + id: create_fragment.name + }); + + const { ctx } = this.$$; + const props = options.props || {}; + + if (/*prop*/ ctx[0] === undefined && !("prop" in props)) { + console.warn(" was created without expected prop 'prop'"); + } + + if (/*realName*/ ctx[1] === undefined && !("alias" in props)) { + console.warn(" was created without expected prop 'alias'"); + } + } + + get prop() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set prop(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + + get alias() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set alias(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } +} + +export default Component; +export { moduleLiveBinding, moduleContantProps }; \ No newline at end of file diff --git a/test/js/samples/capture-inject-state/input.svelte b/test/js/samples/capture-inject-state/input.svelte new file mode 100644 index 0000000000..a1051bc147 --- /dev/null +++ b/test/js/samples/capture-inject-state/input.svelte @@ -0,0 +1,23 @@ + + + +

{prop} {realName} {local} {priv} {$prop} {shadowedByModule}

diff --git a/test/js/samples/component-static-var/expected.js b/test/js/samples/component-static-var/expected.js index a65d9186a7..c032a0636d 100644 --- a/test/js/samples/component-static-var/expected.js +++ b/test/js/samples/component-static-var/expected.js @@ -36,7 +36,7 @@ function create_fragment(ctx) { t1 = space(); input = element("input"); }, - m(target, anchor) { + m(target, anchor, remount) { mount_component(foo, target, anchor); insert(target, t0, anchor); mount_component(bar, target, anchor); @@ -44,6 +44,7 @@ function create_fragment(ctx) { insert(target, input, anchor); set_input_value(input, /*z*/ ctx[0]); current = true; + if (remount) dispose(); dispose = listen(input, "input", /*input_input_handler*/ ctx[1]); }, p(ctx, [dirty]) { diff --git a/test/js/samples/component-store-reassign-invalidate/expected.js b/test/js/samples/component-store-reassign-invalidate/expected.js index 771b20dec4..b33047d8f3 100644 --- a/test/js/samples/component-store-reassign-invalidate/expected.js +++ b/test/js/samples/component-store-reassign-invalidate/expected.js @@ -32,11 +32,12 @@ function create_fragment(ctx) { button = element("button"); button.textContent = "reset"; }, - m(target, anchor) { + m(target, anchor, remount) { insert(target, h1, anchor); append(h1, t0); insert(target, t1, anchor); insert(target, button, anchor); + if (remount) dispose(); dispose = listen(button, "click", /*click_handler*/ ctx[2]); }, p(ctx, [dirty]) { diff --git a/test/js/samples/debug-empty/expected.js b/test/js/samples/debug-empty/expected.js index 358363c661..dd142adb26 100644 --- a/test/js/samples/debug-empty/expected.js +++ b/test/js/samples/debug-empty/expected.js @@ -12,7 +12,8 @@ import { safe_not_equal, set_data_dev, space, - text + text, + validate_slots } from "svelte/internal"; const file = undefined; @@ -75,18 +76,23 @@ function instance($$self, $$props, $$invalidate) { if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); }); + let { $$slots = {}, $$scope } = $$props; + validate_slots("Component", $$slots, []); + $$self.$set = $$props => { if ("name" in $$props) $$invalidate(0, name = $$props.name); }; - $$self.$capture_state = () => { - return { name }; - }; + $$self.$capture_state = () => ({ name }); $$self.$inject_state = $$props => { if ("name" in $$props) $$invalidate(0, name = $$props.name); }; + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + return [name]; } diff --git a/test/js/samples/debug-foo-bar-baz-things/expected.js b/test/js/samples/debug-foo-bar-baz-things/expected.js index fc65c59eda..977702b99f 100644 --- a/test/js/samples/debug-foo-bar-baz-things/expected.js +++ b/test/js/samples/debug-foo-bar-baz-things/expected.js @@ -13,7 +13,9 @@ import { safe_not_equal, set_data_dev, space, - text + text, + validate_each_argument, + validate_slots } from "svelte/internal"; const file = undefined; @@ -88,6 +90,7 @@ function create_fragment(ctx) { let t1; let t2; let each_value = /*things*/ ctx[0]; + validate_each_argument(each_value); let each_blocks = []; for (let i = 0; i < each_value.length; i += 1) { @@ -122,6 +125,7 @@ function create_fragment(ctx) { p: function update(ctx, [dirty]) { if (dirty & /*things*/ 1) { each_value = /*things*/ ctx[0]; + validate_each_argument(each_value); let i; for (i = 0; i < each_value.length; i += 1) { @@ -176,6 +180,9 @@ function instance($$self, $$props, $$invalidate) { if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); }); + let { $$slots = {}, $$scope } = $$props; + validate_slots("Component", $$slots, []); + $$self.$set = $$props => { if ("things" in $$props) $$invalidate(0, things = $$props.things); if ("foo" in $$props) $$invalidate(1, foo = $$props.foo); @@ -183,9 +190,7 @@ function instance($$self, $$props, $$invalidate) { if ("baz" in $$props) $$invalidate(3, baz = $$props.baz); }; - $$self.$capture_state = () => { - return { things, foo, bar, baz }; - }; + $$self.$capture_state = () => ({ things, foo, bar, baz }); $$self.$inject_state = $$props => { if ("things" in $$props) $$invalidate(0, things = $$props.things); @@ -194,6 +199,10 @@ function instance($$self, $$props, $$invalidate) { if ("baz" in $$props) $$invalidate(3, baz = $$props.baz); }; + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + return [things, foo, bar, baz]; } diff --git a/test/js/samples/debug-foo/expected.js b/test/js/samples/debug-foo/expected.js index 710d6b2232..fe62ff77bf 100644 --- a/test/js/samples/debug-foo/expected.js +++ b/test/js/samples/debug-foo/expected.js @@ -13,7 +13,9 @@ import { safe_not_equal, set_data_dev, space, - text + text, + validate_each_argument, + validate_slots } from "svelte/internal"; const file = undefined; @@ -82,6 +84,7 @@ function create_fragment(ctx) { let t1; let t2; let each_value = /*things*/ ctx[0]; + validate_each_argument(each_value); let each_blocks = []; for (let i = 0; i < each_value.length; i += 1) { @@ -116,6 +119,7 @@ function create_fragment(ctx) { p: function update(ctx, [dirty]) { if (dirty & /*things*/ 1) { each_value = /*things*/ ctx[0]; + validate_each_argument(each_value); let i; for (i = 0; i < each_value.length; i += 1) { @@ -168,20 +172,25 @@ function instance($$self, $$props, $$invalidate) { if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); }); + let { $$slots = {}, $$scope } = $$props; + validate_slots("Component", $$slots, []); + $$self.$set = $$props => { if ("things" in $$props) $$invalidate(0, things = $$props.things); if ("foo" in $$props) $$invalidate(1, foo = $$props.foo); }; - $$self.$capture_state = () => { - return { things, foo }; - }; + $$self.$capture_state = () => ({ things, foo }); $$self.$inject_state = $$props => { if ("things" in $$props) $$invalidate(0, things = $$props.things); if ("foo" in $$props) $$invalidate(1, foo = $$props.foo); }; + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + return [things, foo]; } diff --git a/test/js/samples/debug-hoisted/expected.js b/test/js/samples/debug-hoisted/expected.js index eeb9465499..0e634297f0 100644 --- a/test/js/samples/debug-hoisted/expected.js +++ b/test/js/samples/debug-hoisted/expected.js @@ -4,7 +4,8 @@ import { dispatch_dev, init, noop, - safe_not_equal + safe_not_equal, + validate_slots } from "svelte/internal"; const file = undefined; @@ -47,19 +48,28 @@ function create_fragment(ctx) { return block; } -function instance($$self) { +function instance($$self, $$props, $$invalidate) { let obj = { x: 5 }; let kobzol = 5; + const writable_props = []; - $$self.$capture_state = () => { - return {}; - }; + Object.keys($$props).forEach(key => { + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); + }); + + let { $$slots = {}, $$scope } = $$props; + validate_slots("Component", $$slots, []); + $$self.$capture_state = () => ({ obj, kobzol }); $$self.$inject_state = $$props => { if ("obj" in $$props) $$invalidate(0, obj = $$props.obj); if ("kobzol" in $$props) $$invalidate(1, kobzol = $$props.kobzol); }; + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + return [obj, kobzol]; } diff --git a/test/js/samples/debug-no-dependencies/expected.js b/test/js/samples/debug-no-dependencies/expected.js index 054dda7953..76068e8cf4 100644 --- a/test/js/samples/debug-no-dependencies/expected.js +++ b/test/js/samples/debug-no-dependencies/expected.js @@ -10,7 +10,9 @@ import { noop, safe_not_equal, space, - text + text, + validate_each_argument, + validate_slots } from "svelte/internal"; const file = undefined; @@ -64,6 +66,7 @@ function create_each_block(ctx) { function create_fragment(ctx) { let each_1_anchor; let each_value = things; + validate_each_argument(each_value); let each_blocks = []; for (let i = 0; i < each_value.length; i += 1) { @@ -91,6 +94,7 @@ function create_fragment(ctx) { p: function update(ctx, [dirty]) { if (dirty & /*things*/ 0) { each_value = things; + validate_each_argument(each_value); let i; for (i = 0; i < each_value.length; i += 1) { @@ -131,10 +135,22 @@ function create_fragment(ctx) { return block; } +function instance($$self, $$props) { + const writable_props = []; + + Object.keys($$props).forEach(key => { + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); + }); + + let { $$slots = {}, $$scope } = $$props; + validate_slots("Component", $$slots, []); + return []; +} + class Component extends SvelteComponentDev { constructor(options) { super(options); - init(this, options, null, create_fragment, safe_not_equal, {}); + init(this, options, instance, create_fragment, safe_not_equal, {}); dispatch_dev("SvelteRegisterComponent", { component: this, diff --git a/test/js/samples/dev-warning-missing-data-computed/expected.js b/test/js/samples/dev-warning-missing-data-computed/expected.js index cc16de67e6..0a50e2cd97 100644 --- a/test/js/samples/dev-warning-missing-data-computed/expected.js +++ b/test/js/samples/dev-warning-missing-data-computed/expected.js @@ -12,7 +12,8 @@ import { safe_not_equal, set_data_dev, space, - text + text, + validate_slots } from "svelte/internal"; const file = undefined; @@ -72,19 +73,24 @@ function instance($$self, $$props, $$invalidate) { if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); }); + let { $$slots = {}, $$scope } = $$props; + validate_slots("Component", $$slots, []); + $$self.$set = $$props => { if ("foo" in $$props) $$invalidate(0, foo = $$props.foo); }; - $$self.$capture_state = () => { - return { foo, bar }; - }; + $$self.$capture_state = () => ({ foo, bar }); $$self.$inject_state = $$props => { if ("foo" in $$props) $$invalidate(0, foo = $$props.foo); if ("bar" in $$props) $$invalidate(1, bar = $$props.bar); }; + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + $$self.$$.update = () => { if ($$self.$$.dirty & /*foo*/ 1) { $: $$invalidate(1, bar = foo * 2); diff --git a/test/js/samples/dont-invalidate-this/expected.js b/test/js/samples/dont-invalidate-this/expected.js index f5f6d07812..ba9e7152d7 100644 --- a/test/js/samples/dont-invalidate-this/expected.js +++ b/test/js/samples/dont-invalidate-this/expected.js @@ -18,8 +18,9 @@ function create_fragment(ctx) { c() { input = element("input"); }, - m(target, anchor) { + m(target, anchor, remount) { insert(target, input, anchor); + if (remount) dispose(); dispose = listen(input, "input", make_uppercase); }, p: noop, diff --git a/test/js/samples/event-handler-dynamic/expected.js b/test/js/samples/event-handler-dynamic/expected.js index 16b4a3f626..d8f5710023 100644 --- a/test/js/samples/event-handler-dynamic/expected.js +++ b/test/js/samples/event-handler-dynamic/expected.js @@ -43,7 +43,7 @@ function create_fragment(ctx) { button2 = element("button"); button2.textContent = "click"; }, - m(target, anchor) { + m(target, anchor, remount) { insert(target, p0, anchor); append(p0, button0); append(p0, t1); @@ -53,6 +53,7 @@ function create_fragment(ctx) { append(p1, t4); insert(target, t5, anchor); insert(target, button2, anchor); + if (remount) run_all(dispose); dispose = [ listen(button0, "click", /*updateHandler1*/ ctx[2]), diff --git a/test/js/samples/event-handler-no-passive/expected.js b/test/js/samples/event-handler-no-passive/expected.js index c519fac668..8bf2de7693 100644 --- a/test/js/samples/event-handler-no-passive/expected.js +++ b/test/js/samples/event-handler-no-passive/expected.js @@ -21,8 +21,9 @@ function create_fragment(ctx) { a.textContent = "this should not navigate to example.com"; attr(a, "href", "https://example.com"); }, - m(target, anchor) { + m(target, anchor, remount) { insert(target, a, anchor); + if (remount) dispose(); dispose = listen(a, "touchstart", touchstart_handler); }, p: noop, diff --git a/test/js/samples/event-modifiers/expected.js b/test/js/samples/event-modifiers/expected.js index c12c3523a0..2eca5f29b8 100644 --- a/test/js/samples/event-modifiers/expected.js +++ b/test/js/samples/event-modifiers/expected.js @@ -36,13 +36,14 @@ function create_fragment(ctx) { button2 = element("button"); button2.textContent = "or me!"; }, - m(target, anchor) { + m(target, anchor, remount) { insert(target, div, anchor); append(div, button0); append(div, t1); append(div, button1); append(div, t3); append(div, button2); + if (remount) run_all(dispose); dispose = [ listen(button0, "click", stop_propagation(prevent_default(handleClick))), diff --git a/test/js/samples/input-files/expected.js b/test/js/samples/input-files/expected.js index 2a2254fbd7..1c1e57fc9b 100644 --- a/test/js/samples/input-files/expected.js +++ b/test/js/samples/input-files/expected.js @@ -21,8 +21,9 @@ function create_fragment(ctx) { attr(input, "type", "file"); input.multiple = true; }, - m(target, anchor) { + m(target, anchor, remount) { insert(target, input, anchor); + if (remount) dispose(); dispose = listen(input, "change", /*input_change_handler*/ ctx[1]); }, p: noop, diff --git a/test/js/samples/input-no-initial-value/expected.js b/test/js/samples/input-no-initial-value/expected.js index d588f0bf73..f72daa22a3 100644 --- a/test/js/samples/input-no-initial-value/expected.js +++ b/test/js/samples/input-no-initial-value/expected.js @@ -32,12 +32,13 @@ function create_fragment(ctx) { attr(input, "type", "text"); input.required = true; }, - m(target, anchor) { + m(target, anchor, remount) { 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]), diff --git a/test/js/samples/input-range/expected.js b/test/js/samples/input-range/expected.js index 12dfd3e90e..17a8065449 100644 --- a/test/js/samples/input-range/expected.js +++ b/test/js/samples/input-range/expected.js @@ -23,9 +23,10 @@ function create_fragment(ctx) { input = element("input"); attr(input, "type", "range"); }, - m(target, anchor) { + m(target, anchor, remount) { 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]), diff --git a/test/js/samples/input-value/expected.js b/test/js/samples/input-value/expected.js index 21c7bfc83b..31be2895ac 100644 --- a/test/js/samples/input-value/expected.js +++ b/test/js/samples/input-value/expected.js @@ -31,12 +31,13 @@ function create_fragment(ctx) { t2 = text("!"); input.value = /*name*/ ctx[0]; }, - m(target, anchor) { + m(target, anchor, remount) { 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]); }, p(ctx, [dirty]) { diff --git a/test/js/samples/input-without-blowback-guard/expected.js b/test/js/samples/input-without-blowback-guard/expected.js index fefe867e14..1e379032f3 100644 --- a/test/js/samples/input-without-blowback-guard/expected.js +++ b/test/js/samples/input-without-blowback-guard/expected.js @@ -20,9 +20,10 @@ function create_fragment(ctx) { input = element("input"); attr(input, "type", "checkbox"); }, - m(target, anchor) { + m(target, anchor, remount) { insert(target, input, anchor); input.checked = /*foo*/ ctx[0]; + if (remount) dispose(); dispose = listen(input, "change", /*input_change_handler*/ ctx[1]); }, p(ctx, [dirty]) { 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 7634481a2d..f45e52aebd 100644 --- a/test/js/samples/instrumentation-script-if-no-block/expected.js +++ b/test/js/samples/instrumentation-script-if-no-block/expected.js @@ -31,12 +31,13 @@ function create_fragment(ctx) { t2 = text("x: "); t3 = text(/*x*/ ctx[0]); }, - m(target, anchor) { + m(target, anchor, remount) { 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]); }, p(ctx, [dirty]) { 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 c154608cd5..9fe9640978 100644 --- a/test/js/samples/instrumentation-script-x-equals-x/expected.js +++ b/test/js/samples/instrumentation-script-x-equals-x/expected.js @@ -32,12 +32,13 @@ function create_fragment(ctx) { t2 = text("number of things: "); t3 = text(t3_value); }, - m(target, anchor) { + m(target, anchor, remount) { 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]); }, p(ctx, [dirty]) { 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 77780baa99..6f3bea4010 100644 --- a/test/js/samples/instrumentation-template-if-no-block/expected.js +++ b/test/js/samples/instrumentation-template-if-no-block/expected.js @@ -31,12 +31,13 @@ function create_fragment(ctx) { t2 = text("x: "); t3 = text(/*x*/ ctx[0]); }, - m(target, anchor) { + m(target, anchor, remount) { 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]); }, p(ctx, [dirty]) { 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 4fe45616c7..ed095353bd 100644 --- a/test/js/samples/instrumentation-template-x-equals-x/expected.js +++ b/test/js/samples/instrumentation-template-x-equals-x/expected.js @@ -32,12 +32,13 @@ function create_fragment(ctx) { t2 = text("number of things: "); t3 = text(t3_value); }, - m(target, anchor) { + m(target, anchor, remount) { 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]); }, p(ctx, [dirty]) { diff --git a/test/js/samples/loop-protect/expected.js b/test/js/samples/loop-protect/expected.js index 554ccf23b1..c52d9df437 100644 --- a/test/js/samples/loop-protect/expected.js +++ b/test/js/samples/loop-protect/expected.js @@ -6,13 +6,16 @@ import { detach_dev, dispatch_dev, element, + globals, init, insert_dev, loop_guard, noop, - safe_not_equal + safe_not_equal, + validate_slots } from "svelte/internal"; +const { console: console_1 } = globals; const file = undefined; function create_fragment(ctx) { @@ -102,20 +105,31 @@ function instance($$self, $$props, $$invalidate) { } while (true); } + const writable_props = []; + + Object.keys($$props).forEach(key => { + 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); }); } - $$self.$capture_state = () => { - return {}; - }; + $$self.$capture_state = () => ({ node, foo }); $$self.$inject_state = $$props => { if ("node" in $$props) $$invalidate(0, node = $$props.node); }; + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + $: { const guard_4 = loop_guard(100); diff --git a/test/js/samples/media-bindings/expected.js b/test/js/samples/media-bindings/expected.js index 52fef36792..e58d32cf29 100644 --- a/test/js/samples/media-bindings/expected.js +++ b/test/js/samples/media-bindings/expected.js @@ -42,7 +42,7 @@ function create_fragment(ctx) { if (/*seeking*/ ctx[8] === void 0) add_render_callback(() => /*audio_seeking_seeked_handler*/ ctx[17].call(audio)); if (/*ended*/ ctx[9] === void 0) add_render_callback(() => /*audio_ended_handler*/ ctx[18].call(audio)); }, - m(target, anchor) { + m(target, anchor, remount) { insert(target, audio, anchor); if (!isNaN(/*volume*/ ctx[6])) { @@ -53,6 +53,8 @@ function create_fragment(ctx) { audio.playbackRate = /*playbackRate*/ ctx[7]; } + if (remount) run_all(dispose); + dispose = [ listen(audio, "progress", /*audio_progress_handler*/ ctx[10]), listen(audio, "loadedmetadata", /*audio_loadedmetadata_handler*/ ctx[11]), diff --git a/test/js/samples/video-bindings/expected.js b/test/js/samples/video-bindings/expected.js index c8cd1d84ce..3cad17b34d 100644 --- a/test/js/samples/video-bindings/expected.js +++ b/test/js/samples/video-bindings/expected.js @@ -38,9 +38,10 @@ 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) { + m(target, anchor, remount) { 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), diff --git a/test/js/samples/window-binding-online/expected.js b/test/js/samples/window-binding-online/expected.js index e129e66d71..fa955e4fd5 100644 --- a/test/js/samples/window-binding-online/expected.js +++ b/test/js/samples/window-binding-online/expected.js @@ -15,7 +15,9 @@ function create_fragment(ctx) { return { c: noop, - m(target, anchor) { + m(target, anchor, remount) { + if (remount) run_all(dispose); + dispose = [ listen(window, "online", /*onlinestatuschanged*/ ctx[1]), listen(window, "offline", /*onlinestatuschanged*/ ctx[1]) diff --git a/test/js/samples/window-binding-scroll/expected.js b/test/js/samples/window-binding-scroll/expected.js index 70c39eedd2..30723cc142 100644 --- a/test/js/samples/window-binding-scroll/expected.js +++ b/test/js/samples/window-binding-scroll/expected.js @@ -34,10 +34,11 @@ function create_fragment(ctx) { t0 = text("scrolled to "); t1 = text(/*y*/ ctx[0]); }, - m(target, anchor) { + m(target, anchor, remount) { insert(target, p, anchor); append(p, t0); append(p, t1); + if (remount) dispose(); dispose = listen(window, "scroll", () => { scrolling = true; diff --git a/test/parser/samples/await-catch/output.json b/test/parser/samples/await-catch/output.json index 2461f467f2..d47d27e4cb 100644 --- a/test/parser/samples/await-catch/output.json +++ b/test/parser/samples/await-catch/output.json @@ -25,7 +25,10 @@ "name": "thePromise" }, "value": null, - "error": "theError", + "error": { + "type": "Identifier", + "name": "theError" + }, "pending": { "start": 19, "end": 39, diff --git a/test/parser/samples/await-then-catch/output.json b/test/parser/samples/await-then-catch/output.json index d9defb6932..01dc89f3f9 100644 --- a/test/parser/samples/await-then-catch/output.json +++ b/test/parser/samples/await-then-catch/output.json @@ -24,8 +24,14 @@ }, "name": "thePromise" }, - "value": "theValue", - "error": "theError", + "value": { + "type": "Identifier", + "name": "theValue" + }, + "error": { + "type": "Identifier", + "name": "theError" + }, "pending": { "start": 19, "end": 39, diff --git a/test/parser/samples/error-self-reference/error.json b/test/parser/samples/error-self-reference/error.json index 798b5cb300..31ecab2b12 100644 --- a/test/parser/samples/error-self-reference/error.json +++ b/test/parser/samples/error-self-reference/error.json @@ -1,6 +1,6 @@ { "code": "invalid-self-placement", - "message": " components can only exist inside if-blocks or each-blocks", + "message": " components can only exist inside {#if} blocks, {#each} blocks, or slots passed to components", "start": { "line": 1, "column": 1, 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 251cefc0ca..e30c302e0f 100644 --- a/test/parser/samples/no-error-if-before-closing/output.json +++ b/test/parser/samples/no-error-if-before-closing/output.json @@ -115,7 +115,10 @@ "value": true, "raw": "true" }, - "value": "f", + "value": { + "type": "Identifier", + "name": "f" + }, "error": null, "pending": { "start": 80, @@ -198,7 +201,10 @@ "value": true, "raw": "true" }, - "value": "f", + "value": { + "type": "Identifier", + "name": "f" + }, "error": null, "pending": { "start": 123, diff --git a/test/runtime/samples/$$rest-without-props/App.svelte b/test/runtime/samples/$$rest-without-props/App.svelte new file mode 100644 index 0000000000..e98fec30d4 --- /dev/null +++ b/test/runtime/samples/$$rest-without-props/App.svelte @@ -0,0 +1,12 @@ + +
Length: {length}
+
Values: {values.join(',')}
+ +
\ No newline at end of file diff --git a/test/runtime/samples/$$rest-without-props/_config.js b/test/runtime/samples/$$rest-without-props/_config.js new file mode 100644 index 0000000000..017f9df561 --- /dev/null +++ b/test/runtime/samples/$$rest-without-props/_config.js @@ -0,0 +1,54 @@ +export default { + props: { + a: 3, + b: 4, + c: 5, + d: 6 + }, + html: ` +
Length: 3
+
Values: 4,5,1
+
+ + `, + async test({ assert, target, window, }) { + const [btn1, btn2, btn3, btn4] = target.querySelectorAll('button'); + const clickEvent = new window.MouseEvent('click'); + + await btn1.dispatchEvent(clickEvent); + + assert.htmlEqual(target.innerHTML, ` +
Length: 3
+
Values: 4,5,1
+
+ + `); + + await btn2.dispatchEvent(clickEvent); + + assert.htmlEqual(target.innerHTML, ` +
Length: 3
+
Values: 34,5,1
+
+ + `); + + await btn3.dispatchEvent(clickEvent); + + assert.htmlEqual(target.innerHTML, ` +
Length: 3
+
Values: 34,5,31
+
+ + `); + + await btn4.dispatchEvent(clickEvent); + + assert.htmlEqual(target.innerHTML, ` +
Length: 4
+
Values: 34,5,31,2
+
+ + `); + } +}; diff --git a/test/runtime/samples/$$rest-without-props/main.svelte b/test/runtime/samples/$$rest-without-props/main.svelte new file mode 100644 index 0000000000..21b2690584 --- /dev/null +++ b/test/runtime/samples/$$rest-without-props/main.svelte @@ -0,0 +1,25 @@ + + + + + + + \ No newline at end of file diff --git a/test/runtime/samples/$$rest/App.svelte b/test/runtime/samples/$$rest/App.svelte new file mode 100644 index 0000000000..875372f670 --- /dev/null +++ b/test/runtime/samples/$$rest/App.svelte @@ -0,0 +1,13 @@ + +
Length: {length}
+
Values: {values.join(',')}
+ +
+
\ No newline at end of file diff --git a/test/runtime/samples/$$rest/_config.js b/test/runtime/samples/$$rest/_config.js new file mode 100644 index 0000000000..255927f354 --- /dev/null +++ b/test/runtime/samples/$$rest/_config.js @@ -0,0 +1,60 @@ +export default { + props: { + a: 3, + b: 4, + c: 5, + d: 6 + }, + html: ` +
Length: 3
+
Values: 4,5,1
+
+
+ + `, + + async test({ assert, target, window, }) { + const [btn1, btn2, btn3, btn4] = target.querySelectorAll('button'); + const clickEvent = new window.MouseEvent('click'); + + await btn1.dispatchEvent(clickEvent); + + assert.htmlEqual(target.innerHTML, ` +
Length: 3
+
Values: 4,5,1
+
+
+ + `); + + await btn2.dispatchEvent(clickEvent); + + assert.htmlEqual(target.innerHTML, ` +
Length: 3
+
Values: 34,5,1
+
+
+ + `); + + await btn3.dispatchEvent(clickEvent); + + assert.htmlEqual(target.innerHTML, ` +
Length: 3
+
Values: 34,5,31
+
+
+ + `); + + await btn4.dispatchEvent(clickEvent); + + assert.htmlEqual(target.innerHTML, ` +
Length: 4
+
Values: 34,5,31,2
+
+
+ + `); + } +}; diff --git a/test/runtime/samples/$$rest/main.svelte b/test/runtime/samples/$$rest/main.svelte new file mode 100644 index 0000000000..21b2690584 --- /dev/null +++ b/test/runtime/samples/$$rest/main.svelte @@ -0,0 +1,25 @@ + + + + + + + \ No newline at end of file diff --git a/test/runtime/samples/await-then-destruct-array/_config.js b/test/runtime/samples/await-then-destruct-array/_config.js new file mode 100644 index 0000000000..55c48481e0 --- /dev/null +++ b/test/runtime/samples/await-then-destruct-array/_config.js @@ -0,0 +1,61 @@ +export default { + props: { + thePromise: new Promise(resolve => {}) + }, + + html: ` + loading... + `, + + async test({ assert, component, target }) { + await (component.thePromise = Promise.resolve([1, 2])); + + assert.htmlEqual( + target.innerHTML, + ` +

a: 1

+

b: 2

+ ` + ); + + await (component.thePromise = Promise.resolve([4, 5])); + + assert.htmlEqual( + target.innerHTML, + ` +

a: 4

+

b: 5

+ ` + ); + + try { + await (component.thePromise = Promise.reject(['a', [6, 7]])); + } catch (e) { + // do nothing + } + + assert.htmlEqual( + target.innerHTML, + ` +

c: a

+

d: 6

+

e: 7

+ ` + ); + + try { + await (component.thePromise = Promise.reject(['b', [8, 9]])); + } catch (e) { + // do nothing + } + + assert.htmlEqual( + target.innerHTML, + ` +

c: b

+

d: 8

+

e: 9

+ ` + ); + } +}; diff --git a/test/runtime/samples/await-then-destruct-array/main.svelte b/test/runtime/samples/await-then-destruct-array/main.svelte new file mode 100644 index 0000000000..cc0d217f79 --- /dev/null +++ b/test/runtime/samples/await-then-destruct-array/main.svelte @@ -0,0 +1,14 @@ + + +{#await thePromise} + loading... +{:then [ a, b ]} +

a: {a}

+

b: {b}

+{:catch [c, [d, e]]} +

c: {c}

+

d: {d}

+

e: {e}

+{/await} \ No newline at end of file diff --git a/test/runtime/samples/await-then-destruct-default/_config.js b/test/runtime/samples/await-then-destruct-default/_config.js new file mode 100644 index 0000000000..d0e5a49f28 --- /dev/null +++ b/test/runtime/samples/await-then-destruct-default/_config.js @@ -0,0 +1,23 @@ +export default { + async test({ assert, component, target }) { + await Promise.resolve(); + + assert.htmlEqual( + target.innerHTML, + ` +

a: 3

+

b: 2

+

c: 3

+

a: 1

+

b: 2

+

c: 3

+

a: 3

+

b: 2

+

c: 3

+

a: 1

+

b: 2

+

c: 3

+ ` + ); + } +}; diff --git a/test/runtime/samples/await-then-destruct-default/main.svelte b/test/runtime/samples/await-then-destruct-default/main.svelte new file mode 100644 index 0000000000..d559aadab1 --- /dev/null +++ b/test/runtime/samples/await-then-destruct-default/main.svelte @@ -0,0 +1,34 @@ + + +{#await object then { a = 3, b = 4, c }} +

a: {a}

+

b: {b}

+

c: {c}

+{/await} + +{#await array then [a, b, c = 3]} +

a: {a}

+

b: {b}

+

c: {c}

+{/await} + +{#await objectReject then value} + resolved +{:catch { a = 3, b = 4, c }} +

a: {a}

+

b: {b}

+

c: {c}

+{/await} + +{#await arrayReject then value} + resolved +{:catch [a, b, c = 3]} +

a: {a}

+

b: {b}

+

c: {c}

+{/await} \ No newline at end of file diff --git a/test/runtime/samples/await-then-destruct-object/_config.js b/test/runtime/samples/await-then-destruct-object/_config.js new file mode 100644 index 0000000000..371462de97 --- /dev/null +++ b/test/runtime/samples/await-then-destruct-object/_config.js @@ -0,0 +1,63 @@ +export default { + props: { + thePromise: new Promise(resolve => {}) + }, + + html: ` + loading... + `, + + async test({ assert, component, target }) { + await (component.thePromise = Promise.resolve({ error: "error message" })); + + assert.htmlEqual( + target.innerHTML, + ` +

error: error message

+

result: undefined

+ ` + ); + + await (component.thePromise = Promise.resolve({ result: "42" })); + + assert.htmlEqual( + target.innerHTML, + ` +

error: undefined

+

result: 42

+ ` + ); + + try { + await (component.thePromise = Promise.reject({ + error: { message: "oops", code: "123" } + })); + } catch (e) { + // do nothing + } + + assert.htmlEqual( + target.innerHTML, + ` +

message: oops

+

code: 123

+ ` + ); + + try { + await (component.thePromise = Promise.reject({ + error: { message: "timeout", code: "456" } + })); + } catch (e) { + // do nothing + } + + assert.htmlEqual( + target.innerHTML, + ` +

message: timeout

+

code: 456

+ ` + ); + } +}; diff --git a/test/runtime/samples/await-then-destruct-object/main.svelte b/test/runtime/samples/await-then-destruct-object/main.svelte new file mode 100644 index 0000000000..ff574b7be8 --- /dev/null +++ b/test/runtime/samples/await-then-destruct-object/main.svelte @@ -0,0 +1,13 @@ + + +{#await thePromise} + loading... +{:then { result, error }} +

error: {error}

+

result: {result}

+{:catch { error: { message, code } }} +

message: {message}

+

code: {code}

+{/await} \ No newline at end of file diff --git a/test/runtime/samples/await-then-destruct-rest/_config.js b/test/runtime/samples/await-then-destruct-rest/_config.js new file mode 100644 index 0000000000..528568e569 --- /dev/null +++ b/test/runtime/samples/await-then-destruct-rest/_config.js @@ -0,0 +1,21 @@ +export default { + async test({ assert, component, target }) { + await Promise.resolve(); + + assert.htmlEqual( + target.innerHTML, + ` +

a: 1

+

rest: {"b":2,"c":3}

+

a: 1

+

b: 2

+

rest: [3,4,5,6]

+

a: 1

+

rest: {"b":2,"c":3}

+

a: 1

+

b: 2

+

rest: [3,4,5,6]

+ ` + ); + } +}; diff --git a/test/runtime/samples/await-then-destruct-rest/main.svelte b/test/runtime/samples/await-then-destruct-rest/main.svelte new file mode 100644 index 0000000000..a2d57dabf3 --- /dev/null +++ b/test/runtime/samples/await-then-destruct-rest/main.svelte @@ -0,0 +1,32 @@ + + +{#await object then { a, ...rest }} +

a: {a}

+

rest: {JSON.stringify(rest)}

+{/await} + +{#await array then [a, b, ...rest]} +

a: {a}

+

b: {b}

+

rest: {JSON.stringify(rest)}

+{/await} + +{#await objectReject then value} + resolved +{:catch { a, ...rest }} +

a: {a}

+

rest: {JSON.stringify(rest)}

+{/await} + +{#await arrayReject then value} + resolved +{:catch [a, b, ...rest]} +

a: {a}

+

b: {b}

+

rest: {JSON.stringify(rest)}

+{/await} \ No newline at end of file diff --git a/test/runtime/samples/bitmask-overflow-if/_config.js b/test/runtime/samples/bitmask-overflow-if/_config.js new file mode 100644 index 0000000000..74bc70d414 --- /dev/null +++ b/test/runtime/samples/bitmask-overflow-if/_config.js @@ -0,0 +1,24 @@ +export default { + html: ` + 012345678910111213141516171819202122232425262728293031323334353637383940 + expected: true + if: true + + `, + + async test({ assert, component, target, window }) { + const button = target.querySelector("button"); + await button.dispatchEvent(new window.MouseEvent("click")); + + assert.htmlEqual( + target.innerHTML, + ` + 112345678910111213141516171819202122232425262728293031323334353637383940 + expected: false + if: false +
+ + ` + ); + } +}; diff --git a/test/runtime/samples/bitmask-overflow-if/main.svelte b/test/runtime/samples/bitmask-overflow-if/main.svelte new file mode 100644 index 0000000000..2c1c453091 --- /dev/null +++ b/test/runtime/samples/bitmask-overflow-if/main.svelte @@ -0,0 +1,62 @@ + + + +{_0}{_1}{_2}{_3}{_4}{_5}{_6}{_7}{_8}{_9}{_10}{_11}{_12}{_13}{_14}{_15}{_16}{_17}{_18}{_19}{_20}{_21}{_22}{_23}{_24}{_25}{_26}{_27}{_28}{_29}{_30}{_31}{_32}{_33}{_34}{_35}{_36}{_37}{_38}{_39}{_40} + +expected: {_a.indexOf(_0) && _0 === '0' && _1 === '1'} +{#if _a.indexOf(_0) && _0 === '0' && _1 === '1'} +if: true +{:else} +if: false +
+{/if} + + \ No newline at end of file diff --git a/test/runtime/samples/bitmask-overflow-slot-3/Echo.svelte b/test/runtime/samples/bitmask-overflow-slot-3/Echo.svelte new file mode 100644 index 0000000000..d3ecf142c9 --- /dev/null +++ b/test/runtime/samples/bitmask-overflow-slot-3/Echo.svelte @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/test/runtime/samples/bitmask-overflow-slot-3/_config.js b/test/runtime/samples/bitmask-overflow-slot-3/_config.js new file mode 100644 index 0000000000..93e548e5f7 --- /dev/null +++ b/test/runtime/samples/bitmask-overflow-slot-3/_config.js @@ -0,0 +1,30 @@ +export default { + + html: ` +

_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40

+

0

+ + `, + + async test({ assert, component, target, window }) { + // change from inside + const button = target.querySelector('button'); + await button.dispatchEvent(new window.MouseEvent('click')); + + assert.htmlEqual(target.innerHTML, ` +

_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40

+

1

+ + `); + + // change from outside + component._0 = 'a'; + component._40 = 'b'; + + assert.htmlEqual(target.innerHTML, ` +

a_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39b

+

1

+ + `); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/bitmask-overflow-slot-3/main.svelte b/test/runtime/samples/bitmask-overflow-slot-3/main.svelte new file mode 100644 index 0000000000..ae798e4aee --- /dev/null +++ b/test/runtime/samples/bitmask-overflow-slot-3/main.svelte @@ -0,0 +1,11 @@ + + + +

{_0}{_1}{_2}{_3}{_4}{_5}{_6}{_7}{_8}{_9}{_10}{_11}{_12}{_13}{_14}{_15}{_16}{_17}{_18}{_19}{_20}{_21}{_22}{_23}{_24}{_25}{_26}{_27}{_28}{_29}{_30}{_31}{_32}{_33}{_34}{_35}{_36}{_37}{_38}{_39}{_40}

+

{dummy}

+
+ diff --git a/test/runtime/samples/bitmask-overflow-slot-4/Echo.svelte b/test/runtime/samples/bitmask-overflow-slot-4/Echo.svelte new file mode 100644 index 0000000000..2e1beda492 --- /dev/null +++ b/test/runtime/samples/bitmask-overflow-slot-4/Echo.svelte @@ -0,0 +1,11 @@ + + +

{_0}{_1}{_2}{_3}{_4}{_5}{_6}{_7}{_8}{_9}{_10}{_11}{_12}{_13}{_14}{_15}{_16}{_17}{_18}{_19}{_20}{_21}{_22}{_23}{_24}{_25}{_26}{_27}{_28}{_29}{_30}{_31}{_32}{_33}{_34}{_35}{_36}{_37}{_38}{_39}{_40}

+ + \ No newline at end of file diff --git a/test/runtime/samples/bitmask-overflow-slot-4/_config.js b/test/runtime/samples/bitmask-overflow-slot-4/_config.js new file mode 100644 index 0000000000..cdaa5de77f --- /dev/null +++ b/test/runtime/samples/bitmask-overflow-slot-4/_config.js @@ -0,0 +1,41 @@ +export default { + html: ` +

_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40

+

0

+

0

+ + `, + + async test({ assert, component, target, window }) { + // change from inside + const button = target.querySelector('button'); + await button.dispatchEvent(new window.MouseEvent('click')); + + assert.htmlEqual(target.innerHTML, ` +

_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40

+

0

+

1

+ + `); + + // change from outside + component._0 = 'a'; + + assert.htmlEqual(target.innerHTML, ` +

_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40

+

a

+

1

+ + `); + + // change from outside through props + component._40 = 'b'; + + assert.htmlEqual(target.innerHTML, ` +

_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39b

+

a

+

1

+ + `); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/bitmask-overflow-slot-4/main.svelte b/test/runtime/samples/bitmask-overflow-slot-4/main.svelte new file mode 100644 index 0000000000..7e02487a30 --- /dev/null +++ b/test/runtime/samples/bitmask-overflow-slot-4/main.svelte @@ -0,0 +1,12 @@ + + + +

{_0}

+

{dummy}

+
+ diff --git a/test/runtime/samples/bitmask-overflow-slot-5/Echo.svelte b/test/runtime/samples/bitmask-overflow-slot-5/Echo.svelte new file mode 100644 index 0000000000..dddb3f7642 --- /dev/null +++ b/test/runtime/samples/bitmask-overflow-slot-5/Echo.svelte @@ -0,0 +1,13 @@ + + +

{_0}{_1}{_2}{_3}{_4}{_5}{_6}{_7}{_8}{_9}{_10}{_11}{_12}{_13}{_14}{_15}{_16}{_17}{_18}{_19}{_20}{_21}{_22}{_23}{_24}{_25}{_26}{_27}{_28}{_29}{_30}{_31}{_32}{_33}{_34}{_35}{_36}{_37}{_38}{_39}{_40}

+

{b}

+ + \ No newline at end of file diff --git a/test/runtime/samples/bitmask-overflow-slot-5/_config.js b/test/runtime/samples/bitmask-overflow-slot-5/_config.js new file mode 100644 index 0000000000..7dedb8f7eb --- /dev/null +++ b/test/runtime/samples/bitmask-overflow-slot-5/_config.js @@ -0,0 +1,49 @@ +export default { + html: ` +

_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40

+

b

+

-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-31-32-33-34-35-36-37-38-39-40

+

0

+

0

+ + `, + + async test({ assert, component, target, window }) { + // change from inside + const button = target.querySelector('button'); + await button.dispatchEvent(new window.MouseEvent('click')); + + assert.htmlEqual(target.innerHTML, ` +

_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40

+

b

+

-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-31-32-33-34-35-36-37-38-39-40

+

0

+

1

+ + `); + + // change from outside + component.a = 'AA'; + + assert.htmlEqual(target.innerHTML, ` +

_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40

+

b

+

-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-31-32-33-34-35-36-37-38-39-40

+

AA

+

1

+ + `); + + // change from outside through props + component.b = 'BB'; + + assert.htmlEqual(target.innerHTML, ` +

_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40

+

BB

+

-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-31-32-33-34-35-36-37-38-39-40

+

AA

+

1

+ + `); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/bitmask-overflow-slot-5/main.svelte b/test/runtime/samples/bitmask-overflow-slot-5/main.svelte new file mode 100644 index 0000000000..b17d6f7bae --- /dev/null +++ b/test/runtime/samples/bitmask-overflow-slot-5/main.svelte @@ -0,0 +1,13 @@ + + + +

{_0}{_1}{_2}{_3}{_4}{_5}{_6}{_7}{_8}{_9}{_10}{_11}{_12}{_13}{_14}{_15}{_16}{_17}{_18}{_19}{_20}{_21}{_22}{_23}{_24}{_25}{_26}{_27}{_28}{_29}{_30}{_31}{_32}{_33}{_34}{_35}{_36}{_37}{_38}{_39}{_40}

+

{a}

+

{dummy}

+
+ diff --git a/test/runtime/samples/component-slot-fallback-2/Inner.svelte b/test/runtime/samples/component-slot-fallback-2/Inner.svelte new file mode 100644 index 0000000000..d1c247ad35 --- /dev/null +++ b/test/runtime/samples/component-slot-fallback-2/Inner.svelte @@ -0,0 +1,7 @@ + + + +{value} \ No newline at end of file diff --git a/test/runtime/samples/component-slot-fallback-2/Outer.svelte b/test/runtime/samples/component-slot-fallback-2/Outer.svelte new file mode 100644 index 0000000000..1e44ba4db7 --- /dev/null +++ b/test/runtime/samples/component-slot-fallback-2/Outer.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/test/runtime/samples/component-slot-fallback-2/_config.js b/test/runtime/samples/component-slot-fallback-2/_config.js new file mode 100644 index 0000000000..585e3b4c9e --- /dev/null +++ b/test/runtime/samples/component-slot-fallback-2/_config.js @@ -0,0 +1,39 @@ +export default { + html: ` `, + ssrHtml: ` `, + + async test({ assert, target, component, window }) { + const [input1, input2, inputFallback] = target.querySelectorAll("input"); + + assert.equal(component.getSubscriberCount(), 3); + + input1.value = "a"; + await input1.dispatchEvent(new window.Event("input")); + input1.value = "ab"; + await input1.dispatchEvent(new window.Event("input")); + assert.equal(input1.value, "ab"); + assert.equal(input2.value, "ab"); + assert.equal(inputFallback.value, "ab"); + + component.props = "hello"; + + assert.htmlEqual( + target.innerHTML, + ` + hello + hello + + ` + ); + + component.fallback = "world"; + assert.htmlEqual( + target.innerHTML, + ` + hello + hello + world + ` + ); + } +}; diff --git a/test/runtime/samples/component-slot-fallback-2/main.svelte b/test/runtime/samples/component-slot-fallback-2/main.svelte new file mode 100644 index 0000000000..4583667015 --- /dev/null +++ b/test/runtime/samples/component-slot-fallback-2/main.svelte @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/test/runtime/samples/component-slot-fallback-2/store.svelte b/test/runtime/samples/component-slot-fallback-2/store.svelte new file mode 100644 index 0000000000..e377aaf314 --- /dev/null +++ b/test/runtime/samples/component-slot-fallback-2/store.svelte @@ -0,0 +1,23 @@ + \ No newline at end of file diff --git a/test/runtime/samples/component-slot-fallback-3/Inner.svelte b/test/runtime/samples/component-slot-fallback-3/Inner.svelte new file mode 100644 index 0000000000..db2af272d2 --- /dev/null +++ b/test/runtime/samples/component-slot-fallback-3/Inner.svelte @@ -0,0 +1,6 @@ + +
Hello
+
world
+
Bye
+
World
+
diff --git a/test/runtime/samples/component-slot-fallback-3/_config.js b/test/runtime/samples/component-slot-fallback-3/_config.js new file mode 100644 index 0000000000..b5591fb5e0 --- /dev/null +++ b/test/runtime/samples/component-slot-fallback-3/_config.js @@ -0,0 +1,6 @@ +export default { + html: ` +
Hello World
+
Hello
world
Bye
World
+ `, +}; diff --git a/test/runtime/samples/component-slot-fallback-3/main.svelte b/test/runtime/samples/component-slot-fallback-3/main.svelte new file mode 100644 index 0000000000..eda7ea60e4 --- /dev/null +++ b/test/runtime/samples/component-slot-fallback-3/main.svelte @@ -0,0 +1,9 @@ + + + +
Hello World
+
+ + diff --git a/test/runtime/samples/component-slot-fallback-4/Inner.svelte b/test/runtime/samples/component-slot-fallback-4/Inner.svelte new file mode 100644 index 0000000000..9eb3ef1401 --- /dev/null +++ b/test/runtime/samples/component-slot-fallback-4/Inner.svelte @@ -0,0 +1,3 @@ + + + foobar \ No newline at end of file diff --git a/test/runtime/samples/component-slot-fallback-4/_config.js b/test/runtime/samples/component-slot-fallback-4/_config.js new file mode 100644 index 0000000000..b7c2b63ed6 --- /dev/null +++ b/test/runtime/samples/component-slot-fallback-4/_config.js @@ -0,0 +1,5 @@ +export default { + html: ` + foobar + `, +}; diff --git a/test/runtime/samples/component-slot-fallback-4/main.svelte b/test/runtime/samples/component-slot-fallback-4/main.svelte new file mode 100644 index 0000000000..206ce21def --- /dev/null +++ b/test/runtime/samples/component-slot-fallback-4/main.svelte @@ -0,0 +1,5 @@ + + + diff --git a/test/runtime/samples/component-slot-fallback-empty/Nested.svelte b/test/runtime/samples/component-slot-fallback-empty/Nested.svelte new file mode 100644 index 0000000000..9e6683feb7 --- /dev/null +++ b/test/runtime/samples/component-slot-fallback-empty/Nested.svelte @@ -0,0 +1,4 @@ +
+

default fallback content

+ bar fallback +
\ No newline at end of file diff --git a/test/runtime/samples/component-slot-fallback-empty/_config.js b/test/runtime/samples/component-slot-fallback-empty/_config.js new file mode 100644 index 0000000000..2e153d24db --- /dev/null +++ b/test/runtime/samples/component-slot-fallback-empty/_config.js @@ -0,0 +1,13 @@ +export default { + html: ` +
+

default fallback content

+ +
+ +
+

default fallback content

+ bar fallback +
+ ` +}; diff --git a/test/runtime/samples/component-slot-fallback-empty/main.svelte b/test/runtime/samples/component-slot-fallback-empty/main.svelte new file mode 100644 index 0000000000..7ae5f4c5d7 --- /dev/null +++ b/test/runtime/samples/component-slot-fallback-empty/main.svelte @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/test/runtime/samples/component-slot-nested-error-2/Nested.svelte b/test/runtime/samples/component-slot-nested-error-2/Nested.svelte new file mode 100644 index 0000000000..c6f086d96c --- /dev/null +++ b/test/runtime/samples/component-slot-nested-error-2/Nested.svelte @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/runtime/samples/component-slot-nested-error-2/_config.js b/test/runtime/samples/component-slot-nested-error-2/_config.js new file mode 100644 index 0000000000..98a9f1cab0 --- /dev/null +++ b/test/runtime/samples/component-slot-nested-error-2/_config.js @@ -0,0 +1,3 @@ +export default { + error: [`Element with a slot='...' attribute must be a child of a component or a descendant of a custom element`] +}; diff --git a/test/runtime/samples/component-slot-nested-error-2/main.svelte b/test/runtime/samples/component-slot-nested-error-2/main.svelte new file mode 100644 index 0000000000..a7142d6dc1 --- /dev/null +++ b/test/runtime/samples/component-slot-nested-error-2/main.svelte @@ -0,0 +1,11 @@ + + + +
+
+
+
+
+ diff --git a/test/runtime/samples/component-slot-nested-error-3/Nested.svelte b/test/runtime/samples/component-slot-nested-error-3/Nested.svelte new file mode 100644 index 0000000000..c6f086d96c --- /dev/null +++ b/test/runtime/samples/component-slot-nested-error-3/Nested.svelte @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/runtime/samples/component-slot-nested-error-3/_config.js b/test/runtime/samples/component-slot-nested-error-3/_config.js new file mode 100644 index 0000000000..98a9f1cab0 --- /dev/null +++ b/test/runtime/samples/component-slot-nested-error-3/_config.js @@ -0,0 +1,3 @@ +export default { + error: [`Element with a slot='...' attribute must be a child of a component or a descendant of a custom element`] +}; diff --git a/test/runtime/samples/component-slot-nested-error-3/main.svelte b/test/runtime/samples/component-slot-nested-error-3/main.svelte new file mode 100644 index 0000000000..a63b1defde --- /dev/null +++ b/test/runtime/samples/component-slot-nested-error-3/main.svelte @@ -0,0 +1,11 @@ + + + +
+
+
+
+
+ diff --git a/test/runtime/samples/component-slot-nested-error/Nested.svelte b/test/runtime/samples/component-slot-nested-error/Nested.svelte new file mode 100644 index 0000000000..c6f086d96c --- /dev/null +++ b/test/runtime/samples/component-slot-nested-error/Nested.svelte @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/runtime/samples/component-slot-nested-error/_config.js b/test/runtime/samples/component-slot-nested-error/_config.js new file mode 100644 index 0000000000..98a9f1cab0 --- /dev/null +++ b/test/runtime/samples/component-slot-nested-error/_config.js @@ -0,0 +1,3 @@ +export default { + error: [`Element with a slot='...' attribute must be a child of a component or a descendant of a custom element`] +}; diff --git a/test/runtime/samples/component-slot-nested-error/main.svelte b/test/runtime/samples/component-slot-nested-error/main.svelte new file mode 100644 index 0000000000..531c96f08c --- /dev/null +++ b/test/runtime/samples/component-slot-nested-error/main.svelte @@ -0,0 +1,9 @@ + + + +
+
+
+ diff --git a/test/runtime/samples/component-slot-warning/Nested.svelte b/test/runtime/samples/component-slot-warning/Nested.svelte new file mode 100644 index 0000000000..c6f086d96c --- /dev/null +++ b/test/runtime/samples/component-slot-warning/Nested.svelte @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/runtime/samples/component-slot-warning/_config.js b/test/runtime/samples/component-slot-warning/_config.js new file mode 100644 index 0000000000..6ffe624782 --- /dev/null +++ b/test/runtime/samples/component-slot-warning/_config.js @@ -0,0 +1,9 @@ +export default { + compileOptions: { + dev: true + }, + warnings: [ + ' received an unexpected slot "default".', + ' received an unexpected slot "slot1".' + ] +}; diff --git a/test/runtime/samples/component-slot-warning/main.svelte b/test/runtime/samples/component-slot-warning/main.svelte new file mode 100644 index 0000000000..c29ef3e85b --- /dev/null +++ b/test/runtime/samples/component-slot-warning/main.svelte @@ -0,0 +1,7 @@ + + + + + diff --git a/test/runtime/samples/deconflict-contextual-bind/Widget.svelte b/test/runtime/samples/deconflict-contextual-bind/Widget.svelte new file mode 100644 index 0000000000..3aaa59b747 --- /dev/null +++ b/test/runtime/samples/deconflict-contextual-bind/Widget.svelte @@ -0,0 +1,3 @@ + diff --git a/test/runtime/samples/deconflict-contextual-bind/_config.js b/test/runtime/samples/deconflict-contextual-bind/_config.js new file mode 100644 index 0000000000..7602cde023 --- /dev/null +++ b/test/runtime/samples/deconflict-contextual-bind/_config.js @@ -0,0 +1,3 @@ +export default { + preserveIdentifiers: true +}; diff --git a/test/runtime/samples/deconflict-contextual-bind/main.svelte b/test/runtime/samples/deconflict-contextual-bind/main.svelte new file mode 100644 index 0000000000..fe91deca17 --- /dev/null +++ b/test/runtime/samples/deconflict-contextual-bind/main.svelte @@ -0,0 +1,8 @@ + + +{#each values as value} + +{/each} diff --git a/test/runtime/samples/dev-warning-each-block-no-sets-maps/_config.js b/test/runtime/samples/dev-warning-each-block-no-sets-maps/_config.js new file mode 100644 index 0000000000..83481d9ebe --- /dev/null +++ b/test/runtime/samples/dev-warning-each-block-no-sets-maps/_config.js @@ -0,0 +1,6 @@ +export default { + compileOptions: { + dev: true + }, + error: `{#each} only iterates over array-like objects. You can use a spread to convert this iterable into an array.` +}; diff --git a/test/runtime/samples/dev-warning-each-block-no-sets-maps/main.svelte b/test/runtime/samples/dev-warning-each-block-no-sets-maps/main.svelte new file mode 100644 index 0000000000..e1aae26d12 --- /dev/null +++ b/test/runtime/samples/dev-warning-each-block-no-sets-maps/main.svelte @@ -0,0 +1,7 @@ + + +{#each foo as item} +
{item}
+{/each} \ No newline at end of file diff --git a/test/runtime/samples/dev-warning-each-block-require-arraylike/_config.js b/test/runtime/samples/dev-warning-each-block-require-arraylike/_config.js new file mode 100644 index 0000000000..62e5fc209b --- /dev/null +++ b/test/runtime/samples/dev-warning-each-block-require-arraylike/_config.js @@ -0,0 +1,6 @@ +export default { + compileOptions: { + dev: true + }, + error: `{#each} only iterates over array-like objects.` +}; diff --git a/test/runtime/samples/dev-warning-each-block-require-arraylike/main.svelte b/test/runtime/samples/dev-warning-each-block-require-arraylike/main.svelte new file mode 100644 index 0000000000..f85df8d84b --- /dev/null +++ b/test/runtime/samples/dev-warning-each-block-require-arraylike/main.svelte @@ -0,0 +1,3 @@ +{#each {} as item} +
{item}
+{/each} \ No newline at end of file diff --git a/test/runtime/samples/dev-warning-unknown-props-2/Foo.svelte b/test/runtime/samples/dev-warning-unknown-props-2/Foo.svelte new file mode 100644 index 0000000000..bc56c4d894 --- /dev/null +++ b/test/runtime/samples/dev-warning-unknown-props-2/Foo.svelte @@ -0,0 +1 @@ +Foo diff --git a/test/runtime/samples/dev-warning-unknown-props-2/_config.js b/test/runtime/samples/dev-warning-unknown-props-2/_config.js new file mode 100644 index 0000000000..9bff4a2a74 --- /dev/null +++ b/test/runtime/samples/dev-warning-unknown-props-2/_config.js @@ -0,0 +1,9 @@ +export default { + compileOptions: { + dev: true + }, + + warnings: [ + ` was created with unknown prop 'fo'` + ] +}; diff --git a/test/runtime/samples/dev-warning-unknown-props-2/main.svelte b/test/runtime/samples/dev-warning-unknown-props-2/main.svelte new file mode 100644 index 0000000000..1566cf3e41 --- /dev/null +++ b/test/runtime/samples/dev-warning-unknown-props-2/main.svelte @@ -0,0 +1,5 @@ + + + diff --git a/test/runtime/samples/dev-warning-unknown-props-with-$$props/Foo.svelte b/test/runtime/samples/dev-warning-unknown-props-with-$$props/Foo.svelte index 9e5c62339d..375b1a6a0a 100644 --- a/test/runtime/samples/dev-warning-unknown-props-with-$$props/Foo.svelte +++ b/test/runtime/samples/dev-warning-unknown-props-with-$$props/Foo.svelte @@ -4,4 +4,4 @@
{foo}
-
{JSON.stringify($$props)}
+
{JSON.stringify($$restProps)}
diff --git a/test/runtime/samples/dev-warning-unknown-props-with-$$rest/Foo.svelte b/test/runtime/samples/dev-warning-unknown-props-with-$$rest/Foo.svelte new file mode 100644 index 0000000000..9e5c62339d --- /dev/null +++ b/test/runtime/samples/dev-warning-unknown-props-with-$$rest/Foo.svelte @@ -0,0 +1,7 @@ + + +
{foo}
+
{JSON.stringify($$props)}
diff --git a/test/runtime/samples/dev-warning-unknown-props-with-$$rest/_config.js b/test/runtime/samples/dev-warning-unknown-props-with-$$rest/_config.js new file mode 100644 index 0000000000..62ad08624d --- /dev/null +++ b/test/runtime/samples/dev-warning-unknown-props-with-$$rest/_config.js @@ -0,0 +1,7 @@ +export default { + compileOptions: { + dev: true + }, + + warnings: [] +}; diff --git a/test/runtime/samples/dev-warning-unknown-props-with-$$rest/main.svelte b/test/runtime/samples/dev-warning-unknown-props-with-$$rest/main.svelte new file mode 100644 index 0000000000..1566cf3e41 --- /dev/null +++ b/test/runtime/samples/dev-warning-unknown-props-with-$$rest/main.svelte @@ -0,0 +1,5 @@ + + + diff --git a/test/runtime/samples/each-block-keyed-else/_config.js b/test/runtime/samples/each-block-keyed-else/_config.js new file mode 100644 index 0000000000..a5bf722a80 --- /dev/null +++ b/test/runtime/samples/each-block-keyed-else/_config.js @@ -0,0 +1,37 @@ +export default { + props: { + animals: ['alpaca', 'baboon', 'capybara'], + foo: 'something else' + }, + + html: ` + before +

alpaca

+

baboon

+

capybara

+ after + `, + + test({ assert, component, target }) { + component.animals = []; + assert.htmlEqual(target.innerHTML, ` + before +

no animals, but rather something else

+ after + `); + + component.foo = 'something other'; + assert.htmlEqual(target.innerHTML, ` + before +

no animals, but rather something other

+ after + `); + + component.animals = ['wombat']; + assert.htmlEqual(target.innerHTML, ` + before +

wombat

+ after + `); + } +}; diff --git a/test/runtime/samples/each-block-keyed-else/main.svelte b/test/runtime/samples/each-block-keyed-else/main.svelte new file mode 100644 index 0000000000..2a82653ff1 --- /dev/null +++ b/test/runtime/samples/each-block-keyed-else/main.svelte @@ -0,0 +1,12 @@ + + +before +{#each animals as animal (animal)} +

{animal}

+{:else} +

no animals, but rather {foo}

+{/each} +after diff --git a/test/runtime/samples/each-block-string/_config.js b/test/runtime/samples/each-block-string/_config.js new file mode 100644 index 0000000000..7366c964eb --- /dev/null +++ b/test/runtime/samples/each-block-string/_config.js @@ -0,0 +1,10 @@ +export default { + compileOptions: { + dev: true + }, + html: ` +
f
+
o
+
o
+ ` +}; diff --git a/test/runtime/samples/each-block-string/main.svelte b/test/runtime/samples/each-block-string/main.svelte new file mode 100644 index 0000000000..ae60f0f6b3 --- /dev/null +++ b/test/runtime/samples/each-block-string/main.svelte @@ -0,0 +1,3 @@ +{#each 'foo' as c} +
{c}
+{/each} diff --git a/test/runtime/samples/each-block-unkeyed-else-2/_config.js b/test/runtime/samples/each-block-unkeyed-else-2/_config.js new file mode 100644 index 0000000000..a5bf722a80 --- /dev/null +++ b/test/runtime/samples/each-block-unkeyed-else-2/_config.js @@ -0,0 +1,37 @@ +export default { + props: { + animals: ['alpaca', 'baboon', 'capybara'], + foo: 'something else' + }, + + html: ` + before +

alpaca

+

baboon

+

capybara

+ after + `, + + test({ assert, component, target }) { + component.animals = []; + assert.htmlEqual(target.innerHTML, ` + before +

no animals, but rather something else

+ after + `); + + component.foo = 'something other'; + assert.htmlEqual(target.innerHTML, ` + before +

no animals, but rather something other

+ after + `); + + component.animals = ['wombat']; + assert.htmlEqual(target.innerHTML, ` + before +

wombat

+ after + `); + } +}; diff --git a/test/runtime/samples/each-block-unkeyed-else-2/main.svelte b/test/runtime/samples/each-block-unkeyed-else-2/main.svelte new file mode 100644 index 0000000000..3275cb1f83 --- /dev/null +++ b/test/runtime/samples/each-block-unkeyed-else-2/main.svelte @@ -0,0 +1,12 @@ + + +before +{#each animals as animal} +

{animal}

+{:else} +

no animals, but rather {foo}

+{/each} +after diff --git a/test/runtime/samples/event-handler-each-modifier/_config.js b/test/runtime/samples/event-handler-each-modifier/_config.js new file mode 100644 index 0000000000..702addd3c3 --- /dev/null +++ b/test/runtime/samples/event-handler-each-modifier/_config.js @@ -0,0 +1,42 @@ +export default { + async test({ assert, component, target, window }) { + // set first + await component.lists.update(() => [ + { text: "item1" }, + { text: "item2" }, + { text: "item3" } + ]); + + await component.lists.update(() => [ + { text: "item3" }, + { text: "item2" }, + { text: "item1" } + ]); + + await component.lists.update(() => [ + { text: "item1" }, + { text: "item2" }, + { text: "item3" } + ]); + + assert.equal(component.updated, 4); + + const [item1, item2] = target.childNodes; + const [item1Btn1, item1Btn2] = item1.querySelectorAll('button'); + const [item2Btn1, item2Btn2] = item2.querySelectorAll('button'); + + const clickEvent = new window.MouseEvent('click'); + + await item1Btn1.dispatchEvent(clickEvent); + assert.equal(component.getNormalCount(), 1); + + await item1Btn2.dispatchEvent(clickEvent); + assert.equal(component.getModifierCount(), 1); + + await item2Btn1.dispatchEvent(clickEvent); + assert.equal(component.getNormalCount(), 2); + + await item2Btn2.dispatchEvent(clickEvent); + assert.equal(component.getModifierCount(), 2); + } +}; diff --git a/test/runtime/samples/event-handler-each-modifier/main.svelte b/test/runtime/samples/event-handler-each-modifier/main.svelte new file mode 100644 index 0000000000..ca7447f728 --- /dev/null +++ b/test/runtime/samples/event-handler-each-modifier/main.svelte @@ -0,0 +1,37 @@ + + +{#each $lists as item (item.text)} +
+ {item.text} + + +
+{/each} diff --git a/test/runtime/samples/self-reference-component/Countdown.svelte b/test/runtime/samples/self-reference-component/Countdown.svelte new file mode 100644 index 0000000000..21178f2567 --- /dev/null +++ b/test/runtime/samples/self-reference-component/Countdown.svelte @@ -0,0 +1,7 @@ + + +{#if count > 0} + +{/if} \ 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 new file mode 100644 index 0000000000..e3e0ad3a4f --- /dev/null +++ b/test/runtime/samples/self-reference-component/_config.js @@ -0,0 +1,3 @@ +export default { + html: '5 4 3 2 1 0', +}; \ No newline at end of file diff --git a/test/runtime/samples/self-reference-component/main.svelte b/test/runtime/samples/self-reference-component/main.svelte new file mode 100644 index 0000000000..fd28ec4e40 --- /dev/null +++ b/test/runtime/samples/self-reference-component/main.svelte @@ -0,0 +1,10 @@ + + +{count} + + + + \ No newline at end of file diff --git a/test/runtime/samples/spread-component-2/Widget.svelte b/test/runtime/samples/spread-component-2/Widget.svelte new file mode 100644 index 0000000000..ae27aeb5e5 --- /dev/null +++ b/test/runtime/samples/spread-component-2/Widget.svelte @@ -0,0 +1,13 @@ + + +

foo: {foo}

+

baz: {baz} ({typeof baz})

+

qux: {qux}

+

quux: {quux}

+

selected: {selected}

diff --git a/test/runtime/samples/spread-component-2/_config.js b/test/runtime/samples/spread-component-2/_config.js new file mode 100644 index 0000000000..6d36e8e60d --- /dev/null +++ b/test/runtime/samples/spread-component-2/_config.js @@ -0,0 +1,76 @@ +export default { + props: { + list: [{ + foo: 'lol', + baz: 40 + 2, + qux: 5, + quux: 'core' + }, { + foo: 'lolzz', + baz: 50 + 2, + qux: 1, + quux: 'quuxx' + }], + }, + + html: ` +
+

foo: lol

+

baz: 42 (number)

+

qux: 0

+

quux: core

+

selected: true

+

foo: lolzz

+

baz: 52 (number)

+

qux: 0

+

quux: quuxx

+

selected: false

+
+ `, + + test({ assert, component, target }) { + component.list = [{ + foo: 'lol', + baz: 40 + 3, + qux: 8, + quux: 'heart' + }, { + foo: 'lolzz', + baz: 50 + 3, + qux: 8, + quux: 'heartxx' + }]; + + assert.htmlEqual(target.innerHTML, ` +
+

foo: lol

+

baz: 43 (number)

+

qux: 0

+

quux: heart

+

selected: true

+

foo: lolzz

+

baz: 53 (number)

+

qux: 0

+

quux: heartxx

+

selected: false

+
+ `); + + component.qux = 1; + + assert.htmlEqual(target.innerHTML, ` +
+

foo: lol

+

baz: 43 (number)

+

qux: 1

+

quux: heart

+

selected: false

+

foo: lolzz

+

baz: 53 (number)

+

qux: 1

+

quux: heartxx

+

selected: true

+
+ `); + } +}; diff --git a/test/runtime/samples/spread-component-2/main.svelte b/test/runtime/samples/spread-component-2/main.svelte new file mode 100644 index 0000000000..436e11f9c5 --- /dev/null +++ b/test/runtime/samples/spread-component-2/main.svelte @@ -0,0 +1,12 @@ + + +
+ {#each list as item, index (item.foo)} + + {/each} +
diff --git a/test/runtime/samples/transition-css-iframe/Foo.svelte b/test/runtime/samples/transition-css-iframe/Foo.svelte new file mode 100644 index 0000000000..c79672f21b --- /dev/null +++ b/test/runtime/samples/transition-css-iframe/Foo.svelte @@ -0,0 +1,16 @@ + + +{#if visible} +
+{/if} \ No newline at end of file diff --git a/test/runtime/samples/transition-css-iframe/Frame.svelte b/test/runtime/samples/transition-css-iframe/Frame.svelte new file mode 100644 index 0000000000..c7ac9cf76f --- /dev/null +++ b/test/runtime/samples/transition-css-iframe/Frame.svelte @@ -0,0 +1,58 @@ + + + + + diff --git a/test/runtime/samples/transition-css-iframe/_config.js b/test/runtime/samples/transition-css-iframe/_config.js new file mode 100644 index 0000000000..507efe44f4 --- /dev/null +++ b/test/runtime/samples/transition-css-iframe/_config.js @@ -0,0 +1,18 @@ +export default { + skip_if_ssr: true, + + async test({ assert, component, target, window, raf }) { + const frame = target.querySelector('iframe'); + await Promise.resolve(); + + component.visible = true; + const div = frame.contentDocument.querySelector('div'); + + raf.tick(25); + + component.visible = false; + + raf.tick(26); + assert.ok(~div.style.animation.indexOf('25ms')); + }, +}; diff --git a/test/runtime/samples/transition-css-iframe/main.svelte b/test/runtime/samples/transition-css-iframe/main.svelte new file mode 100644 index 0000000000..b1686ff15e --- /dev/null +++ b/test/runtime/samples/transition-css-iframe/main.svelte @@ -0,0 +1,8 @@ + + + \ No newline at end of file diff --git a/test/validator/samples/binding-const-field/errors.json b/test/validator/samples/binding-const-field/errors.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/test/validator/samples/binding-const-field/errors.json @@ -0,0 +1 @@ +[] diff --git a/test/validator/samples/binding-const-field/input.svelte b/test/validator/samples/binding-const-field/input.svelte new file mode 100644 index 0000000000..055a16438d --- /dev/null +++ b/test/validator/samples/binding-const-field/input.svelte @@ -0,0 +1,7 @@ + + + diff --git a/test/validator/samples/binding-const/errors.json b/test/validator/samples/binding-const/errors.json new file mode 100644 index 0000000000..6d48af9c4e --- /dev/null +++ b/test/validator/samples/binding-const/errors.json @@ -0,0 +1,15 @@ +[{ + "code": "invalid-binding", + "message": "Cannot bind to a variable which is not writable", + "pos": 61, + "start": { + "line": 5, + "column": 19, + "character": 61 + }, + "end": { + "line": 5, + "column": 24, + "character": 66 + } +}] \ No newline at end of file diff --git a/test/validator/samples/binding-const/input.svelte b/test/validator/samples/binding-const/input.svelte new file mode 100644 index 0000000000..1857a1932c --- /dev/null +++ b/test/validator/samples/binding-const/input.svelte @@ -0,0 +1,5 @@ + + + diff --git a/test/validator/samples/component-slotted-custom-element-2/errors.json b/test/validator/samples/component-slotted-custom-element-2/errors.json new file mode 100644 index 0000000000..06be51d72d --- /dev/null +++ b/test/validator/samples/component-slotted-custom-element-2/errors.json @@ -0,0 +1,9 @@ +[ + { + "code": "invalid-slotted-content", + "message": "Element with a slot='...' attribute must be a child of a component or a descendant of a custom element", + "start": { "line": 10, "column": 9, "character": 138 }, + "end": { "line": 10, "column": 19, "character": 148 }, + "pos": 138 + } +] diff --git a/test/validator/samples/component-slotted-custom-element-2/input.svelte b/test/validator/samples/component-slotted-custom-element-2/input.svelte new file mode 100644 index 0000000000..221659ca4d --- /dev/null +++ b/test/validator/samples/component-slotted-custom-element-2/input.svelte @@ -0,0 +1,14 @@ + + + + + {#if thing} +
+
+
+ {/if} + + \ No newline at end of file diff --git a/test/validator/samples/component-slotted-custom-element/errors.json b/test/validator/samples/component-slotted-custom-element/errors.json new file mode 100644 index 0000000000..0637a088a0 --- /dev/null +++ b/test/validator/samples/component-slotted-custom-element/errors.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/test/validator/samples/component-slotted-custom-element/input.svelte b/test/validator/samples/component-slotted-custom-element/input.svelte new file mode 100644 index 0000000000..e0e27834c1 --- /dev/null +++ b/test/validator/samples/component-slotted-custom-element/input.svelte @@ -0,0 +1,15 @@ + + + + +
+
+
+ {#if thing} +
+ {/if} + + \ No newline at end of file diff --git a/test/validator/samples/component-slotted-each-block/errors.json b/test/validator/samples/component-slotted-each-block/errors.json index 89f394bca4..2944acae17 100644 --- a/test/validator/samples/component-slotted-each-block/errors.json +++ b/test/validator/samples/component-slotted-each-block/errors.json @@ -1,6 +1,6 @@ [{ "code": "invalid-slotted-content", - "message": "Cannot place slotted elements inside an each-block", + "message": "Element with a slot='...' attribute must be a child of a component or a descendant of a custom element", "start": { "line": 7, "column": 7, diff --git a/test/validator/samples/component-slotted-if-block/errors.json b/test/validator/samples/component-slotted-if-block/errors.json index ab35a77fce..3ae07c1b3b 100644 --- a/test/validator/samples/component-slotted-if-block/errors.json +++ b/test/validator/samples/component-slotted-if-block/errors.json @@ -1,6 +1,6 @@ [{ "code": "invalid-slotted-content", - "message": "Cannot place slotted elements inside an if-block", + "message": "Element with a slot='...' attribute must be a child of a component or a descendant of a custom element", "start": { "line": 7, "column": 7, diff --git a/test/validator/samples/slot-attribute-invalid/errors.json b/test/validator/samples/slot-attribute-invalid/errors.json index fc01fa9792..a75fdc065c 100644 --- a/test/validator/samples/slot-attribute-invalid/errors.json +++ b/test/validator/samples/slot-attribute-invalid/errors.json @@ -1,6 +1,6 @@ [{ "code": "invalid-slotted-content", - "message": "Element with a slot='...' attribute must be a descendant of a component or custom element", + "message": "Element with a slot='...' attribute must be a child of a component or a descendant of a custom element", "start": { "line": 1, "column": 5, diff --git a/test/vars/samples/modules-vars/_config.js b/test/vars/samples/modules-vars/_config.js new file mode 100644 index 0000000000..e178941db6 --- /dev/null +++ b/test/vars/samples/modules-vars/_config.js @@ -0,0 +1,72 @@ +export default { + test(assert, vars) { + assert.deepEqual(vars, [ + { + name: "a", + export_name: null, + injected: false, + module: true, + mutated: false, + reassigned: true, + referenced: false, + referenced_from_script: false, + writable: true + }, + { + name: "b", + export_name: null, + injected: false, + module: true, + mutated: true, + reassigned: false, + referenced: false, + referenced_from_script: false, + writable: true + }, + { + name: "c", + export_name: null, + injected: false, + module: true, + mutated: false, + reassigned: false, + referenced: false, + referenced_from_script: false, + writable: true + }, + { + name: "d", + export_name: null, + injected: false, + module: true, + mutated: false, + reassigned: false, + referenced: false, + referenced_from_script: false, + writable: true + }, + { + name: "c", + export_name: null, + injected: false, + module: false, + mutated: false, + reassigned: true, + referenced: false, + referenced_from_script: true, + writable: true + }, + { + name: "foo", + export_name: null, + injected: false, + module: false, + mutated: false, + reassigned: false, + referenced: false, + referenced_from_script: false, + writable: false + } + ]); + } +}; diff --git a/test/vars/samples/modules-vars/input.svelte b/test/vars/samples/modules-vars/input.svelte new file mode 100644 index 0000000000..8bbd5bdc5e --- /dev/null +++ b/test/vars/samples/modules-vars/input.svelte @@ -0,0 +1,18 @@ + + \ No newline at end of file