diff --git a/.gitignore b/.gitignore index ee1daa2c03..22389f683c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ node_modules /compiler.*js /index.*js /ssr.*js +/action /internal /store /easing diff --git a/CHANGELOG.md b/CHANGELOG.md index 19938792da..0b2bb5d7fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,39 @@ ## Unreleased +* Return the context object in `setContext` [#7427](https://github.com/sveltejs/svelte/issues/7427) +* Fix `{@const}` tag not working inside Component when there's no `let:` [#7189](https://github.com/sveltejs/svelte/issues/7189) +* Ignore comments in `{#each}` blocks when containing elements with `animate:` ([#3999](https://github.com/sveltejs/svelte/issues/3999)) +* Add a third parameter to the returned function of `createEventDispatcher` that allows passing an object of `{ cancelable: true }` to create a cancelable custom event. The returned function when called will also return a boolean depending on whether the event is cancelled ([#7064](https://github.com/sveltejs/svelte/pull/7064)) + +## 3.47.0 + +* Add support for dynamic elements through `` ([#2324](https://github.com/sveltejs/svelte/issues/2324)) +* Miscellaneous variable context fixes in `{@const}` ([#7222](https://github.com/sveltejs/svelte/pull/7222)) +* Fix `{#key}` block not being reactive when the key variable is not otherwise used ([#7408](https://github.com/sveltejs/svelte/issues/7408)) +* Add `Symbol` as a known global ([#7418](https://github.com/sveltejs/svelte/issues/7418)) + +## 3.46.6 + +* Actually include action TypeScript interface in published package ([#7407](https://github.com/sveltejs/svelte/pull/7407)) + +## 3.46.5 + +* Add TypeScript interfaces for typing actions ([#6538](https://github.com/sveltejs/svelte/issues/6538)) +* Do not generate `unused-export-let` warning inside ` + +Foo +``` ### `` @@ -1683,7 +1705,7 @@ All except `scrollX` and `scrollY` are readonly. Similarly to ``, this element allows you to add listeners to events on `document.body`, such as `mouseenter` and `mouseleave`, which don't fire on `window`. It also lets you use [actions](/docs#template-syntax-element-directives-use-action) on the `` element. -`` also has to appear at the top level of your component. +As with ``, this element may only appear the top level of your component and must never be inside a block or element. ```sv `, this element allows you to add listeners to even This element makes it possible to insert elements into `document.head`. During server-side rendering, `head` content is exposed separately to the main `html` content. -As with `` and ``, this element has to appear at the top level of your component and cannot be inside a block or other element. +As with `` and ``, this element may only appear at the top level of your component and must never be inside a block or element. ```sv diff --git a/site/content/docs/03-run-time.md b/site/content/docs/03-run-time.md index 35e3ed03ec..c6423f408c 100644 --- a/site/content/docs/03-run-time.md +++ b/site/content/docs/03-run-time.md @@ -148,7 +148,7 @@ setContext(key: any, context: any) --- -Associates an arbitrary `context` object with the current component and the specified `key`. The context is then available to children of the component (including slotted content) with `getContext`. +Associates an arbitrary `context` object with the current component and the specified `key` and returns that object. The context is then available to children of the component (including slotted content) with `getContext`. Like lifecycle functions, this must be called during component initialisation. diff --git a/site/content/docs/04-compile-time.md b/site/content/docs/04-compile-time.md index 1ee41eeb93..35a57ced85 100644 --- a/site/content/docs/04-compile-time.md +++ b/site/content/docs/04-compile-time.md @@ -2,11 +2,7 @@ title: Compile time --- -Typically, you won't interact with the Svelte compiler directly, but will instead integrate it into your build system using a bundler plugin: - -* [rollup-plugin-svelte](https://github.com/sveltejs/rollup-plugin-svelte) for users of [Rollup](https://rollupjs.org) -* [svelte-loader](https://github.com/sveltejs/svelte-loader) for users of [webpack](https://webpack.js.org) -* or one of the [community-maintained plugins](https://sveltesociety.dev/tools) +Typically, you won't interact with the Svelte compiler directly, but will instead integrate it into your build system using a bundler plugin. The bundler plugin that the Svelte team most recommends and invests in is [vite-plugin-svelte](https://github.com/sveltejs/vite-plugin-svelte). The [SvelteKit](https://kit.svelte.dev/) framework provides a setup leveraging `vite-plugin-svelte` to build applications as well as a [tool for packaging Svelte component libraries](https://kit.svelte.dev/docs/packaging). Svelte Society maintains a list of [other bundler plugins](https://sveltesociety.dev/tools/#bundling) for additional tools like Rollup and Webpack. Nonetheless, it's useful to understand how to use the compiler, since bundler plugins generally expose compiler options to you. @@ -77,7 +73,7 @@ The following options can be passed to the compiler. None are required: | `accessors` | `false` | If `true`, getters and setters will be created for the component's props. If `false`, they will only be created for readonly exported values (i.e. those declared with `const`, `class` and `function`). If compiling with `customElement: true` this option defaults to `true`. | `customElement` | `false` | If `true`, tells the compiler to generate a custom element constructor instead of a regular Svelte component. | `tag` | `null` | A `string` that tells Svelte what tag name to register the custom element with. It must be a lowercase alphanumeric string with at least one hyphen, e.g. `"my-element"`. -| `css` | `true` | If `true`, styles will be included in the JavaScript class and injected at runtime. It's recommended that you set this to `false` and use the CSS that is statically generated, as it will result in smaller JavaScript bundles and better performance. +| `css` | `true` | If `true`, styles will be included in the JavaScript class and injected at runtime for the components actually rendered. If `false`, the CSS will be returned in the `css` field of the compilation result. Most Svelte bundler plugins will set this to `false` and use the CSS that is statically generated for better performance, as it will result in smaller JavaScript bundles and the output can be served as cacheable `.css` files. | `cssHash` | See right | A function that takes a `{ hash, css, name, filename }` argument and returns the string that is used as a classname for scoped CSS. It defaults to returning `svelte-${hash(css)}` | `loopGuardTimeout` | 0 | A `number` that tells Svelte to break the loop if it blocks the thread for more than `loopGuardTimeout` ms. This is useful to prevent infinite loops. **Only available when `dev: true`** | `preserveComments` | `false` | If `true`, your HTML comments will be preserved during server-side rendering. By default, they are stripped out. diff --git a/site/content/examples/13-actions/00-actions/App.svelte b/site/content/examples/13-actions/00-actions/App.svelte index bd990a5360..79214ec81f 100644 --- a/site/content/examples/13-actions/00-actions/App.svelte +++ b/site/content/examples/13-actions/00-actions/App.svelte @@ -20,6 +20,9 @@ height: var(--height); left: calc(50% - var(--width) / 2); top: calc(50% - var(--height) / 2); + display: flex; + align-items: center; + padding: 8px; border-radius: 4px; background-color: #ff3e00; color: #fff; diff --git a/site/content/examples/17-special-elements/02-svelte-element/App.svelte b/site/content/examples/17-special-elements/02-svelte-element/App.svelte new file mode 100644 index 0000000000..068f7b3c4f --- /dev/null +++ b/site/content/examples/17-special-elements/02-svelte-element/App.svelte @@ -0,0 +1,12 @@ + + + + +I'm a {selected} tag diff --git a/site/content/examples/17-special-elements/02-svelte-element/meta.json b/site/content/examples/17-special-elements/02-svelte-element/meta.json new file mode 100644 index 0000000000..4ff15b716f --- /dev/null +++ b/site/content/examples/17-special-elements/02-svelte-element/meta.json @@ -0,0 +1,3 @@ +{ + "title": "" +} \ No newline at end of file diff --git a/site/content/examples/17-special-elements/02-svelte-window/App.svelte b/site/content/examples/17-special-elements/03-svelte-window/App.svelte similarity index 100% rename from site/content/examples/17-special-elements/02-svelte-window/App.svelte rename to site/content/examples/17-special-elements/03-svelte-window/App.svelte diff --git a/site/content/examples/17-special-elements/02-svelte-window/meta.json b/site/content/examples/17-special-elements/03-svelte-window/meta.json similarity index 100% rename from site/content/examples/17-special-elements/02-svelte-window/meta.json rename to site/content/examples/17-special-elements/03-svelte-window/meta.json diff --git a/site/content/examples/17-special-elements/03-svelte-window-bindings/App.svelte b/site/content/examples/17-special-elements/04-svelte-window-bindings/App.svelte similarity index 100% rename from site/content/examples/17-special-elements/03-svelte-window-bindings/App.svelte rename to site/content/examples/17-special-elements/04-svelte-window-bindings/App.svelte diff --git a/site/content/examples/17-special-elements/03-svelte-window-bindings/meta.json b/site/content/examples/17-special-elements/04-svelte-window-bindings/meta.json similarity index 100% rename from site/content/examples/17-special-elements/03-svelte-window-bindings/meta.json rename to site/content/examples/17-special-elements/04-svelte-window-bindings/meta.json diff --git a/site/content/examples/17-special-elements/04-svelte-body/App.svelte b/site/content/examples/17-special-elements/05-svelte-body/App.svelte similarity index 100% rename from site/content/examples/17-special-elements/04-svelte-body/App.svelte rename to site/content/examples/17-special-elements/05-svelte-body/App.svelte diff --git a/site/content/examples/17-special-elements/04-svelte-body/meta.json b/site/content/examples/17-special-elements/05-svelte-body/meta.json similarity index 100% rename from site/content/examples/17-special-elements/04-svelte-body/meta.json rename to site/content/examples/17-special-elements/05-svelte-body/meta.json diff --git a/site/content/examples/17-special-elements/05-svelte-head/App.svelte b/site/content/examples/17-special-elements/06-svelte-head/App.svelte similarity index 100% rename from site/content/examples/17-special-elements/05-svelte-head/App.svelte rename to site/content/examples/17-special-elements/06-svelte-head/App.svelte diff --git a/site/content/examples/17-special-elements/05-svelte-head/meta.json b/site/content/examples/17-special-elements/06-svelte-head/meta.json similarity index 100% rename from site/content/examples/17-special-elements/05-svelte-head/meta.json rename to site/content/examples/17-special-elements/06-svelte-head/meta.json diff --git a/site/content/faq/100-im-new-to-svelte.md b/site/content/faq/100-im-new-to-svelte.md index cfe5eb8ec0..5bd7b96379 100644 --- a/site/content/faq/100-im-new-to-svelte.md +++ b/site/content/faq/100-im-new-to-svelte.md @@ -2,6 +2,6 @@ question: I'm new to Svelte. Where should I start? --- -We think the best way to get started is playing through the interactive [Tutorial](/tutorial). Each step there is mainly focused on one specific aspect and is easy to follow. You'll be editing and running real Svelte components right in your browser. +We think the best way to get started is playing through the interactive [tutorial](/tutorial). Each step there is mainly focused on one specific aspect and is easy to follow. You'll be editing and running real Svelte components right in your browser. Five to ten minutes should be enough to get you up and running. An hour and a half should get you through the entire tutorial. diff --git a/site/content/faq/450-how-do-i-document-my-components.md b/site/content/faq/450-how-do-i-document-my-components.md index 78177abd54..4574d02961 100644 --- a/site/content/faq/450-how-do-i-document-my-components.md +++ b/site/content/faq/450-how-do-i-document-my-components.md @@ -4,7 +4,7 @@ question: How do I document my components? In editors which use the Svelte Language Server you can document Components, functions and exports using specially formatted comments. -````svelte +````sv + + + +{#if selected === 'h1'} +

I'm a h1 tag

+{:else if selected === 'h3'} +

I'm a h3 tag

+{:else if selected === 'p'} +

I'm a p tag

+{/if} diff --git a/site/content/tutorial/16-special-elements/03-svelte-element/app-b/App.svelte b/site/content/tutorial/16-special-elements/03-svelte-element/app-b/App.svelte new file mode 100644 index 0000000000..068f7b3c4f --- /dev/null +++ b/site/content/tutorial/16-special-elements/03-svelte-element/app-b/App.svelte @@ -0,0 +1,12 @@ + + + + +I'm a {selected} tag diff --git a/site/content/tutorial/16-special-elements/03-svelte-element/text.md b/site/content/tutorial/16-special-elements/03-svelte-element/text.md new file mode 100644 index 0000000000..ace344db42 --- /dev/null +++ b/site/content/tutorial/16-special-elements/03-svelte-element/text.md @@ -0,0 +1,23 @@ +--- +title: +--- + +Sometimes we don't know in advance what kind of DOM element to render. `` comes in handy here. Instead of a sequence of `if` blocks... + +```html +{#if selected === 'h1'} +

I'm a h1 tag

+{:else if selected === 'h3'} +

I'm a h3 tag

+{:else if selected === 'p'} +

I'm a p tag

+{/if} +``` + +...we can have a single dynamic component: + +```html +I'm a {selected} tag +``` + +The `this` value can be any string, or a falsy value — if it's falsy, no element is rendered. \ No newline at end of file diff --git a/site/content/tutorial/16-special-elements/03-svelte-window/app-a/App.svelte b/site/content/tutorial/16-special-elements/04-svelte-window/app-a/App.svelte similarity index 100% rename from site/content/tutorial/16-special-elements/03-svelte-window/app-a/App.svelte rename to site/content/tutorial/16-special-elements/04-svelte-window/app-a/App.svelte diff --git a/site/content/tutorial/16-special-elements/03-svelte-window/app-b/App.svelte b/site/content/tutorial/16-special-elements/04-svelte-window/app-b/App.svelte similarity index 100% rename from site/content/tutorial/16-special-elements/03-svelte-window/app-b/App.svelte rename to site/content/tutorial/16-special-elements/04-svelte-window/app-b/App.svelte diff --git a/site/content/tutorial/16-special-elements/03-svelte-window/text.md b/site/content/tutorial/16-special-elements/04-svelte-window/text.md similarity index 100% rename from site/content/tutorial/16-special-elements/03-svelte-window/text.md rename to site/content/tutorial/16-special-elements/04-svelte-window/text.md diff --git a/site/content/tutorial/16-special-elements/04-svelte-window-bindings/app-a/App.svelte b/site/content/tutorial/16-special-elements/05-svelte-window-bindings/app-a/App.svelte similarity index 100% rename from site/content/tutorial/16-special-elements/04-svelte-window-bindings/app-a/App.svelte rename to site/content/tutorial/16-special-elements/05-svelte-window-bindings/app-a/App.svelte diff --git a/site/content/tutorial/16-special-elements/04-svelte-window-bindings/app-b/App.svelte b/site/content/tutorial/16-special-elements/05-svelte-window-bindings/app-b/App.svelte similarity index 100% rename from site/content/tutorial/16-special-elements/04-svelte-window-bindings/app-b/App.svelte rename to site/content/tutorial/16-special-elements/05-svelte-window-bindings/app-b/App.svelte diff --git a/site/content/tutorial/16-special-elements/04-svelte-window-bindings/text.md b/site/content/tutorial/16-special-elements/05-svelte-window-bindings/text.md similarity index 100% rename from site/content/tutorial/16-special-elements/04-svelte-window-bindings/text.md rename to site/content/tutorial/16-special-elements/05-svelte-window-bindings/text.md diff --git a/site/content/tutorial/16-special-elements/05-svelte-body/app-a/App.svelte b/site/content/tutorial/16-special-elements/06-svelte-body/app-a/App.svelte similarity index 100% rename from site/content/tutorial/16-special-elements/05-svelte-body/app-a/App.svelte rename to site/content/tutorial/16-special-elements/06-svelte-body/app-a/App.svelte diff --git a/site/content/tutorial/16-special-elements/05-svelte-body/app-b/App.svelte b/site/content/tutorial/16-special-elements/06-svelte-body/app-b/App.svelte similarity index 100% rename from site/content/tutorial/16-special-elements/05-svelte-body/app-b/App.svelte rename to site/content/tutorial/16-special-elements/06-svelte-body/app-b/App.svelte diff --git a/site/content/tutorial/16-special-elements/05-svelte-body/text.md b/site/content/tutorial/16-special-elements/06-svelte-body/text.md similarity index 100% rename from site/content/tutorial/16-special-elements/05-svelte-body/text.md rename to site/content/tutorial/16-special-elements/06-svelte-body/text.md diff --git a/site/content/tutorial/16-special-elements/06-svelte-head/app-a/App.svelte b/site/content/tutorial/16-special-elements/07-svelte-head/app-a/App.svelte similarity index 100% rename from site/content/tutorial/16-special-elements/06-svelte-head/app-a/App.svelte rename to site/content/tutorial/16-special-elements/07-svelte-head/app-a/App.svelte diff --git a/site/content/tutorial/16-special-elements/06-svelte-head/app-b/App.svelte b/site/content/tutorial/16-special-elements/07-svelte-head/app-b/App.svelte similarity index 100% rename from site/content/tutorial/16-special-elements/06-svelte-head/app-b/App.svelte rename to site/content/tutorial/16-special-elements/07-svelte-head/app-b/App.svelte diff --git a/site/content/tutorial/16-special-elements/06-svelte-head/text.md b/site/content/tutorial/16-special-elements/07-svelte-head/text.md similarity index 100% rename from site/content/tutorial/16-special-elements/06-svelte-head/text.md rename to site/content/tutorial/16-special-elements/07-svelte-head/text.md diff --git a/site/content/tutorial/16-special-elements/07-svelte-options/app-a/App.svelte b/site/content/tutorial/16-special-elements/08-svelte-options/app-a/App.svelte similarity index 100% rename from site/content/tutorial/16-special-elements/07-svelte-options/app-a/App.svelte rename to site/content/tutorial/16-special-elements/08-svelte-options/app-a/App.svelte diff --git a/site/content/tutorial/16-special-elements/07-svelte-options/app-a/Todo.svelte b/site/content/tutorial/16-special-elements/08-svelte-options/app-a/Todo.svelte similarity index 100% rename from site/content/tutorial/16-special-elements/07-svelte-options/app-a/Todo.svelte rename to site/content/tutorial/16-special-elements/08-svelte-options/app-a/Todo.svelte diff --git a/site/content/tutorial/16-special-elements/07-svelte-options/app-a/flash.js b/site/content/tutorial/16-special-elements/08-svelte-options/app-a/flash.js similarity index 100% rename from site/content/tutorial/16-special-elements/07-svelte-options/app-a/flash.js rename to site/content/tutorial/16-special-elements/08-svelte-options/app-a/flash.js diff --git a/site/content/tutorial/16-special-elements/07-svelte-options/app-b/App.svelte b/site/content/tutorial/16-special-elements/08-svelte-options/app-b/App.svelte similarity index 100% rename from site/content/tutorial/16-special-elements/07-svelte-options/app-b/App.svelte rename to site/content/tutorial/16-special-elements/08-svelte-options/app-b/App.svelte diff --git a/site/content/tutorial/16-special-elements/07-svelte-options/app-b/Todo.svelte b/site/content/tutorial/16-special-elements/08-svelte-options/app-b/Todo.svelte similarity index 100% rename from site/content/tutorial/16-special-elements/07-svelte-options/app-b/Todo.svelte rename to site/content/tutorial/16-special-elements/08-svelte-options/app-b/Todo.svelte diff --git a/site/content/tutorial/16-special-elements/07-svelte-options/app-b/flash.js b/site/content/tutorial/16-special-elements/08-svelte-options/app-b/flash.js similarity index 100% rename from site/content/tutorial/16-special-elements/07-svelte-options/app-b/flash.js rename to site/content/tutorial/16-special-elements/08-svelte-options/app-b/flash.js diff --git a/site/content/tutorial/16-special-elements/07-svelte-options/text.md b/site/content/tutorial/16-special-elements/08-svelte-options/text.md similarity index 100% rename from site/content/tutorial/16-special-elements/07-svelte-options/text.md rename to site/content/tutorial/16-special-elements/08-svelte-options/text.md diff --git a/site/content/tutorial/16-special-elements/08-svelte-fragment/app-a/App.svelte b/site/content/tutorial/16-special-elements/09-svelte-fragment/app-a/App.svelte similarity index 100% rename from site/content/tutorial/16-special-elements/08-svelte-fragment/app-a/App.svelte rename to site/content/tutorial/16-special-elements/09-svelte-fragment/app-a/App.svelte diff --git a/site/content/tutorial/16-special-elements/08-svelte-fragment/app-a/Box.svelte b/site/content/tutorial/16-special-elements/09-svelte-fragment/app-a/Box.svelte similarity index 100% rename from site/content/tutorial/16-special-elements/08-svelte-fragment/app-a/Box.svelte rename to site/content/tutorial/16-special-elements/09-svelte-fragment/app-a/Box.svelte diff --git a/site/content/tutorial/16-special-elements/08-svelte-fragment/app-b/App.svelte b/site/content/tutorial/16-special-elements/09-svelte-fragment/app-b/App.svelte similarity index 100% rename from site/content/tutorial/16-special-elements/08-svelte-fragment/app-b/App.svelte rename to site/content/tutorial/16-special-elements/09-svelte-fragment/app-b/App.svelte diff --git a/site/content/tutorial/16-special-elements/08-svelte-fragment/app-b/Box.svelte b/site/content/tutorial/16-special-elements/09-svelte-fragment/app-b/Box.svelte similarity index 100% rename from site/content/tutorial/16-special-elements/08-svelte-fragment/app-b/Box.svelte rename to site/content/tutorial/16-special-elements/09-svelte-fragment/app-b/Box.svelte diff --git a/site/content/tutorial/16-special-elements/08-svelte-fragment/text.md b/site/content/tutorial/16-special-elements/09-svelte-fragment/text.md similarity index 100% rename from site/content/tutorial/16-special-elements/08-svelte-fragment/text.md rename to site/content/tutorial/16-special-elements/09-svelte-fragment/text.md diff --git a/site/content/tutorial/17-module-context/02-module-exports/text.md b/site/content/tutorial/17-module-context/02-module-exports/text.md index d5b4b96621..ec8364da22 100644 --- a/site/content/tutorial/17-module-context/02-module-exports/text.md +++ b/site/content/tutorial/17-module-context/02-module-exports/text.md @@ -16,7 +16,7 @@ Anything exported from a `context="module"` script block becomes an export from ``` -...we can then import it from `App.svelte`... +...we can then import it in `App.svelte`... ```html + + + + {@const foo = "static"} + {@const bar = props} +
{foo} {bar}
+
+ + + {@const foo = "static"} + {@const bar = props} +
{foo} {bar}
+
+
+ + + {@const foo = "static"} + {@const bar = props} +
{foo} {bar}
+
diff --git a/test/runtime/samples/const-tag-each-const/_config.js b/test/runtime/samples/const-tag-each-const/_config.js new file mode 100644 index 0000000000..cde4226a25 --- /dev/null +++ b/test/runtime/samples/const-tag-each-const/_config.js @@ -0,0 +1,29 @@ +export default { + html: ` +

0

+

bar: 1,2,3,1,1,2,3,2, num: 1

+

bar: 0,2,4,1,0,2,4,2, num: 2

+ `, + async test({ component, target, assert }) { + assert.htmlEqual( + target.innerHTML, + ` +

0

+

bar: 1,2,3,1,1,2,3,2, num: 1

+

bar: 0,2,4,1,0,2,4,2, num: 2

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

0

+

bar: 1,2,3,1,1,2,3,2,1,2,3,3, num: 1

+

bar: 0,2,4,1,0,2,4,2,0,2,4,3, num: 2

+

bar: -100,0,100,1,-100,0,100,2,-100,0,100,3, num: 3

+ ` + ); + } +}; diff --git a/test/runtime/samples/const-tag-each-const/main.svelte b/test/runtime/samples/const-tag-each-const/main.svelte new file mode 100644 index 0000000000..182ea3cfc6 --- /dev/null +++ b/test/runtime/samples/const-tag-each-const/main.svelte @@ -0,0 +1,26 @@ + + +

{foo}

+{#each nums as num, index} + {@const bar = nums.map((num) => { + const func = (foos, num) => { + return [...foos.map((foo) => foo), num]; + } + return func(foos[index].nums, num); + })} +

bar: {bar}, num: {num}

+{/each} diff --git a/test/runtime/samples/const-tag-each-duplicated-variable1/_config.js b/test/runtime/samples/const-tag-each-duplicated-variable1/_config.js new file mode 100644 index 0000000000..1f3e5856f2 --- /dev/null +++ b/test/runtime/samples/const-tag-each-duplicated-variable1/_config.js @@ -0,0 +1,29 @@ +export default { + html: ` +

bar: 1,2,3,0,2,4,-100,0,100, num: 1

+

bar: 1,2,3,0,2,4,-100,0,100, num: 2

+

bar: 1,2,3,0,2,4,-100,0,100, num: 3

+ `, + async test({ component, target, assert }) { + assert.htmlEqual( + target.innerHTML, + ` +

bar: 1,2,3,0,2,4,-100,0,100, num: 1

+

bar: 1,2,3,0,2,4,-100,0,100, num: 2

+

bar: 1,2,3,0,2,4,-100,0,100, num: 3

+ ` + ); + + component.nums = [1, 2, 3, 4]; + + assert.htmlEqual( + target.innerHTML, + ` +

bar: 1,2,3,0,2,4,-100,0,100, num: 1

+

bar: 1,2,3,0,2,4,-100,0,100, num: 2

+

bar: 1,2,3,0,2,4,-100,0,100, num: 3

+

bar: 1,2,3,0,2,4,-100,0,100, num: 4

+ ` + ); + } +}; diff --git a/test/runtime/samples/const-tag-each-duplicated-variable1/main.svelte b/test/runtime/samples/const-tag-each-duplicated-variable1/main.svelte new file mode 100644 index 0000000000..00c53dd4ff --- /dev/null +++ b/test/runtime/samples/const-tag-each-duplicated-variable1/main.svelte @@ -0,0 +1,19 @@ + + +{#each nums as num} + {@const bar = foos.map((foos) => foos.nums)} +

bar: {bar}, num: {num}

+{/each} diff --git a/test/runtime/samples/const-tag-each-duplicated-variable2/_config.js b/test/runtime/samples/const-tag-each-duplicated-variable2/_config.js new file mode 100644 index 0000000000..16f48218f1 --- /dev/null +++ b/test/runtime/samples/const-tag-each-duplicated-variable2/_config.js @@ -0,0 +1,32 @@ +export default { + html: ` +

foo: dummy-foo, num: dummy-num

+

bar: 1,2,3,2,, num: 1

+

bar: 1,2,3,2,, num: 2

+

bar: 1,2,3,2,, num: 3

+ `, + async test({ component, target, assert }) { + assert.htmlEqual( + target.innerHTML, + ` +

foo: dummy-foo, num: dummy-num

+

bar: 1,2,3,2,, num: 1

+

bar: 1,2,3,2,, num: 2

+

bar: 1,2,3,2,, num: 3

+ ` + ); + + component.nums = [1, 2, 3, 4]; + + assert.htmlEqual( + target.innerHTML, + ` +

foo: dummy-foo, num: dummy-num

+

bar: 1,2,3,2,4,, num: 1

+

bar: 1,2,3,2,4,, num: 2

+

bar: 1,2,3,2,4,, num: 3

+

bar: 1,2,3,2,4,, num: 4

+ ` + ); + } +}; diff --git a/test/runtime/samples/const-tag-each-duplicated-variable2/main.svelte b/test/runtime/samples/const-tag-each-duplicated-variable2/main.svelte new file mode 100644 index 0000000000..1f7afd92fd --- /dev/null +++ b/test/runtime/samples/const-tag-each-duplicated-variable2/main.svelte @@ -0,0 +1,33 @@ + + +

foo: {foo}, num: {num}

+{#each nums as num} + {@const bar = foos.map((foo) => + foo.nums.filter((num) => { + if (Object.keys($$slots).length) { + return false; + } else if (Object.keys(foo).length) { + return nums.includes(num) || default_nums.includes(num); + } else { + return false; + } + }) || num + )} +

bar: {bar}, num: {num}

+{/each} diff --git a/test/runtime/samples/const-tag-each-duplicated-variable3/_config.js b/test/runtime/samples/const-tag-each-duplicated-variable3/_config.js new file mode 100644 index 0000000000..cde4226a25 --- /dev/null +++ b/test/runtime/samples/const-tag-each-duplicated-variable3/_config.js @@ -0,0 +1,29 @@ +export default { + html: ` +

0

+

bar: 1,2,3,1,1,2,3,2, num: 1

+

bar: 0,2,4,1,0,2,4,2, num: 2

+ `, + async test({ component, target, assert }) { + assert.htmlEqual( + target.innerHTML, + ` +

0

+

bar: 1,2,3,1,1,2,3,2, num: 1

+

bar: 0,2,4,1,0,2,4,2, num: 2

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

0

+

bar: 1,2,3,1,1,2,3,2,1,2,3,3, num: 1

+

bar: 0,2,4,1,0,2,4,2,0,2,4,3, num: 2

+

bar: -100,0,100,1,-100,0,100,2,-100,0,100,3, num: 3

+ ` + ); + } +}; diff --git a/test/runtime/samples/const-tag-each-duplicated-variable3/main.svelte b/test/runtime/samples/const-tag-each-duplicated-variable3/main.svelte new file mode 100644 index 0000000000..f559627d23 --- /dev/null +++ b/test/runtime/samples/const-tag-each-duplicated-variable3/main.svelte @@ -0,0 +1,25 @@ + + +

{foo}

+{#each nums as num, index} + {@const bar = nums.map((num) => { + return (function (foos, num) { + return [...foos.map((foo) => foo), num]; + })(foos[index].nums, num); + })} +

bar: {bar}, num: {num}

+{/each} diff --git a/test/runtime/samples/const-tag-each-function/_config.js b/test/runtime/samples/const-tag-each-function/_config.js new file mode 100644 index 0000000000..cde4226a25 --- /dev/null +++ b/test/runtime/samples/const-tag-each-function/_config.js @@ -0,0 +1,29 @@ +export default { + html: ` +

0

+

bar: 1,2,3,1,1,2,3,2, num: 1

+

bar: 0,2,4,1,0,2,4,2, num: 2

+ `, + async test({ component, target, assert }) { + assert.htmlEqual( + target.innerHTML, + ` +

0

+

bar: 1,2,3,1,1,2,3,2, num: 1

+

bar: 0,2,4,1,0,2,4,2, num: 2

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

0

+

bar: 1,2,3,1,1,2,3,2,1,2,3,3, num: 1

+

bar: 0,2,4,1,0,2,4,2,0,2,4,3, num: 2

+

bar: -100,0,100,1,-100,0,100,2,-100,0,100,3, num: 3

+ ` + ); + } +}; diff --git a/test/runtime/samples/const-tag-each-function/main.svelte b/test/runtime/samples/const-tag-each-function/main.svelte new file mode 100644 index 0000000000..2e027c6620 --- /dev/null +++ b/test/runtime/samples/const-tag-each-function/main.svelte @@ -0,0 +1,26 @@ + + +

{foo}

+{#each nums as num, index} + {@const bar = nums.map((num) => { + function func(foos, num) { + return [...foos.map((foo) => foo), num]; + } + return func(foos[index].nums, num); + })} +

bar: {bar}, num: {num}

+{/each} diff --git a/test/runtime/samples/const-tag-shadow-2/_config.js b/test/runtime/samples/const-tag-shadow-2/_config.js new file mode 100644 index 0000000000..9ad4aed48c --- /dev/null +++ b/test/runtime/samples/const-tag-shadow-2/_config.js @@ -0,0 +1,37 @@ +export default { + html: ` +

1

+

3,6,9

+

2

+

3,6,9

+

3

+

3,6,9

+ `, + test({ component, target, assert }) { + component.baz = 5; + assert.htmlEqual( + target.innerHTML, + ` +

1

+

5,10,15

+

2

+

5,10,15

+

3

+

5,10,15

+ ` + ); + + component.array = [3, 4, 5]; + assert.htmlEqual( + target.innerHTML, + ` +

3

+

15,20,25

+

4

+

15,20,25

+

5

+

15,20,25

+ ` + ); + } +}; diff --git a/test/runtime/samples/const-tag-shadow-2/main.svelte b/test/runtime/samples/const-tag-shadow-2/main.svelte new file mode 100644 index 0000000000..c3bcb2f605 --- /dev/null +++ b/test/runtime/samples/const-tag-shadow-2/main.svelte @@ -0,0 +1,15 @@ + + +{#each array as item} +

{foo(item)}

+ {@const bar = array.map((item) => { + const bar = baz; + const foo = (item) => item * bar; + return foo(item); + })} +

{bar}

+{/each} diff --git a/test/runtime/samples/context-setcontext-return/_config.js b/test/runtime/samples/context-setcontext-return/_config.js new file mode 100644 index 0000000000..28a78f1359 --- /dev/null +++ b/test/runtime/samples/context-setcontext-return/_config.js @@ -0,0 +1,5 @@ +export default { + html: ` +
true
+ ` +}; diff --git a/test/runtime/samples/context-setcontext-return/main.svelte b/test/runtime/samples/context-setcontext-return/main.svelte new file mode 100644 index 0000000000..87153ee846 --- /dev/null +++ b/test/runtime/samples/context-setcontext-return/main.svelte @@ -0,0 +1,7 @@ + + +
{a === b}
diff --git a/test/runtime/samples/dynamic-element-action-update/_config.js b/test/runtime/samples/dynamic-element-action-update/_config.js new file mode 100644 index 0000000000..ebbe6f05a9 --- /dev/null +++ b/test/runtime/samples/dynamic-element-action-update/_config.js @@ -0,0 +1,45 @@ +let logs = []; + +export default { + html: ` +

tag is h1.

+ `, + props: { + logs + }, + after_test() { + logs = []; + }, + + async test({ assert, component, target }) { + assert.equal(component.tag, 'h1'); + + assert.deepEqual(logs, ['create: h1,opt1']); + component.opt = 'opt2'; + + assert.equal(component.tag, 'h1'); + assert.deepEqual(logs, ['create: h1,opt1', 'update: h1,opt2']); + + component.tag = 'h2'; + + assert.equal(component.tag, 'h2'); + assert.deepEqual(logs, [ + 'create: h1,opt1', + 'update: h1,opt2', + 'destroy', + 'create: h2,opt2' + ]); + assert.htmlEqual(target.innerHTML, '

tag is h2.

'); + + component.tag = false; + assert.deepEqual(logs, [ + 'create: h1,opt1', + 'update: h1,opt2', + 'destroy', + 'create: h2,opt2', + 'destroy' + ]); + + assert.htmlEqual(target.innerHTML, ''); + } +}; diff --git a/test/runtime/samples/dynamic-element-action-update/main.svelte b/test/runtime/samples/dynamic-element-action-update/main.svelte new file mode 100644 index 0000000000..da269e115e --- /dev/null +++ b/test/runtime/samples/dynamic-element-action-update/main.svelte @@ -0,0 +1,14 @@ + + +tag is {tag}. diff --git a/test/runtime/samples/dynamic-element-animation-2/_config.js b/test/runtime/samples/dynamic-element-animation-2/_config.js new file mode 100644 index 0000000000..27b28bb349 --- /dev/null +++ b/test/runtime/samples/dynamic-element-animation-2/_config.js @@ -0,0 +1,105 @@ +let originalDivGetBoundingClientRect; +let originalSpanGetBoundingClientRect; +let originalParagraphGetBoundingClientRect; + +export default { + skip_if_ssr: true, + props: { + things: [ + { id: 1, name: 'a' }, + { id: 2, name: 'b' }, + { id: 3, name: 'c' }, + { id: 4, name: 'd' }, + { id: 5, name: 'e' } + ], + tag: 'div' + }, + + html: ` +
a
+
b
+
c
+
d
+
e
+ `, + + before_test() { + originalDivGetBoundingClientRect = + window.HTMLDivElement.prototype.getBoundingClientRect; + originalSpanGetBoundingClientRect = + window.HTMLSpanElement.prototype.getBoundingClientRect; + originalParagraphGetBoundingClientRect = + window.HTMLParagraphElement.prototype.getBoundingClientRect; + + window.HTMLDivElement.prototype.getBoundingClientRect = + fakeGetBoundingClientRect; + window.HTMLSpanElement.prototype.getBoundingClientRect = + fakeGetBoundingClientRect; + window.HTMLParagraphElement.prototype.getBoundingClientRect = + fakeGetBoundingClientRect; + + function fakeGetBoundingClientRect() { + const index = [...this.parentNode.children].indexOf(this); + const top = index * 30; + + return { + left: 0, + right: 100, + top, + bottom: top + 20 + }; + } + }, + after_test() { + window.HTMLDivElement.prototype.getBoundingClientRect = + originalDivGetBoundingClientRect; + window.HTMLSpanElement.prototype.getBoundingClientRect = + originalSpanGetBoundingClientRect; + window.HTMLParagraphElement.prototype.getBoundingClientRect = + originalParagraphGetBoundingClientRect; + }, + + async test({ assert, component, target, raf }) { + // switch tag and things at the same time + await component.update('p', [ + { id: 5, name: 'e' }, + { id: 2, name: 'b' }, + { id: 3, name: 'c' }, + { id: 4, name: 'd' }, + { id: 1, name: 'a' } + ]); + + const ps = document.querySelectorAll('p'); + assert.equal(ps[0].dy, 120); + assert.equal(ps[4].dy, -120); + + raf.tick(50); + assert.equal(ps[0].dy, 60); + assert.equal(ps[4].dy, -60); + + raf.tick(100); + assert.equal(ps[0].dy, 0); + assert.equal(ps[4].dy, 0); + + await component.update('span', [ + { id: 1, name: 'a' }, + { id: 2, name: 'b' }, + { id: 3, name: 'c' }, + { id: 4, name: 'd' }, + { id: 5, name: 'e' } + ]); + + const spans = document.querySelectorAll('span'); + + assert.equal(spans[0].dy, 120); + assert.equal(spans[4].dy, -120); + + raf.tick(150); + assert.equal(spans[0].dy, 60); + assert.equal(spans[4].dy, -60); + + raf.tick(200); + assert.equal(spans[0].dy, 0); + assert.equal(spans[4].dy, 0); + } +}; diff --git a/test/runtime/samples/dynamic-element-animation-2/main.svelte b/test/runtime/samples/dynamic-element-animation-2/main.svelte new file mode 100644 index 0000000000..f655a40af9 --- /dev/null +++ b/test/runtime/samples/dynamic-element-animation-2/main.svelte @@ -0,0 +1,26 @@ + + +{#each things as thing (thing.id)} + {thing.name} +{/each} \ No newline at end of file diff --git a/test/runtime/samples/dynamic-element-animation/_config.js b/test/runtime/samples/dynamic-element-animation/_config.js new file mode 100644 index 0000000000..e3c57a868e --- /dev/null +++ b/test/runtime/samples/dynamic-element-animation/_config.js @@ -0,0 +1,62 @@ +export default { + props: { + things: [ + { id: 1, name: 'a' }, + { id: 2, name: 'b' }, + { id: 3, name: 'c' }, + { id: 4, name: 'd' }, + { id: 5, name: 'e' } + ], + tag: 'div' + }, + + html: ` +
a
+
b
+
c
+
d
+
e
+ `, + + test({ assert, component, target, raf }) { + component.tag = 'p'; + assert.equal(target.querySelectorAll('p').length, 5); + + component.tag = 'div'; + let divs = target.querySelectorAll('div'); + divs.forEach(div => { + div.getBoundingClientRect = function() { + const index = [...this.parentNode.children].indexOf(this); + const top = index * 30; + + return { + left: 0, + right: 100, + top, + bottom: top + 20 + }; + }; + }); + + component.things = [ + { id: 5, name: 'e' }, + { id: 2, name: 'b' }, + { id: 3, name: 'c' }, + { id: 4, name: 'd' }, + { id: 1, name: 'a' } + ]; + + divs = target.querySelectorAll('div'); + assert.ok(~divs[0].style.animation.indexOf('__svelte')); + assert.equal(divs[1].style.animation, ''); + assert.equal(divs[2].style.animation, ''); + assert.equal(divs[3].style.animation, ''); + assert.ok(~divs[4].style.animation.indexOf('__svelte')); + + raf.tick(100); + assert.deepEqual([ + divs[0].style.animation, + divs[4].style.animation + ], ['', '']); + } +}; diff --git a/test/runtime/samples/dynamic-element-animation/main.svelte b/test/runtime/samples/dynamic-element-animation/main.svelte new file mode 100644 index 0000000000..596d12c77a --- /dev/null +++ b/test/runtime/samples/dynamic-element-animation/main.svelte @@ -0,0 +1,18 @@ + + +{#each things as thing (thing.id)} + {thing.name} +{/each} \ No newline at end of file diff --git a/test/runtime/samples/dynamic-element-attribute/_config.js b/test/runtime/samples/dynamic-element-attribute/_config.js new file mode 100644 index 0000000000..6e7c340437 --- /dev/null +++ b/test/runtime/samples/dynamic-element-attribute/_config.js @@ -0,0 +1,17 @@ +export default { + props: { + tag: 'div' + }, + html: '
Foo
', + + test({ assert, component, target }) { + component.tag = 'h1'; + + assert.htmlEqual( + target.innerHTML, + ` +

Foo

+ ` + ); + } +}; diff --git a/test/runtime/samples/dynamic-element-attribute/main.svelte b/test/runtime/samples/dynamic-element-attribute/main.svelte new file mode 100644 index 0000000000..2498e06de9 --- /dev/null +++ b/test/runtime/samples/dynamic-element-attribute/main.svelte @@ -0,0 +1,5 @@ + + +Foo diff --git a/test/runtime/samples/dynamic-element-binding-invalid/_config.js b/test/runtime/samples/dynamic-element-binding-invalid/_config.js new file mode 100644 index 0000000000..14c6d775dc --- /dev/null +++ b/test/runtime/samples/dynamic-element-binding-invalid/_config.js @@ -0,0 +1,3 @@ +export default { + error: "'value' is not a valid binding on elements" +}; diff --git a/test/runtime/samples/dynamic-element-binding-invalid/main.svelte b/test/runtime/samples/dynamic-element-binding-invalid/main.svelte new file mode 100644 index 0000000000..45f8f96061 --- /dev/null +++ b/test/runtime/samples/dynamic-element-binding-invalid/main.svelte @@ -0,0 +1,6 @@ + + + diff --git a/test/runtime/samples/dynamic-element-binding-this/_config.js b/test/runtime/samples/dynamic-element-binding-this/_config.js new file mode 100644 index 0000000000..e0722c9375 --- /dev/null +++ b/test/runtime/samples/dynamic-element-binding-this/_config.js @@ -0,0 +1,8 @@ +export default { + html: '
', + + test({ assert, component, target }) { + const div = target.querySelector('div'); + assert.equal(div, component.foo); + } +}; diff --git a/test/runtime/samples/dynamic-element-binding-this/main.svelte b/test/runtime/samples/dynamic-element-binding-this/main.svelte new file mode 100644 index 0000000000..75e8b02ce1 --- /dev/null +++ b/test/runtime/samples/dynamic-element-binding-this/main.svelte @@ -0,0 +1,6 @@ + + + diff --git a/test/runtime/samples/dynamic-element-change-tag/_config.js b/test/runtime/samples/dynamic-element-change-tag/_config.js new file mode 100644 index 0000000000..9e4bf6fd32 --- /dev/null +++ b/test/runtime/samples/dynamic-element-change-tag/_config.js @@ -0,0 +1,17 @@ +export default { + props: { + tag: 'div' + }, + html: '
Foo
', + + test({ assert, component, target }) { + component.tag = 'h1'; + + assert.htmlEqual( + target.innerHTML, + ` +

Foo

+ ` + ); + } +}; diff --git a/test/runtime/samples/dynamic-element-change-tag/main.svelte b/test/runtime/samples/dynamic-element-change-tag/main.svelte new file mode 100644 index 0000000000..a9c4d5c00c --- /dev/null +++ b/test/runtime/samples/dynamic-element-change-tag/main.svelte @@ -0,0 +1,5 @@ + + +Foo \ No newline at end of file diff --git a/test/runtime/samples/dynamic-element-empty-tag/_config.js b/test/runtime/samples/dynamic-element-empty-tag/_config.js new file mode 100644 index 0000000000..22dc25b41e --- /dev/null +++ b/test/runtime/samples/dynamic-element-empty-tag/_config.js @@ -0,0 +1,3 @@ +export default { + html: '' +}; diff --git a/test/runtime/samples/dynamic-element-empty-tag/main.svelte b/test/runtime/samples/dynamic-element-empty-tag/main.svelte new file mode 100644 index 0000000000..e3889ce0f5 --- /dev/null +++ b/test/runtime/samples/dynamic-element-empty-tag/main.svelte @@ -0,0 +1,5 @@ + + +Foo diff --git a/test/runtime/samples/dynamic-element-event-handler1/_config.js b/test/runtime/samples/dynamic-element-event-handler1/_config.js new file mode 100644 index 0000000000..03b8f7879d --- /dev/null +++ b/test/runtime/samples/dynamic-element-event-handler1/_config.js @@ -0,0 +1,21 @@ +let clicked = false; +function handler() { + clicked = true; +} + +export default { + props: { + handler + }, + html: '', + + test({ assert, target }) { + assert.equal(clicked, false); + + const button = target.querySelector('button'); + const click = new window.MouseEvent('click'); + button.dispatchEvent(click); + + assert.equal(clicked, true); + } +}; diff --git a/test/runtime/samples/dynamic-element-event-handler1/main.svelte b/test/runtime/samples/dynamic-element-event-handler1/main.svelte new file mode 100644 index 0000000000..7a7fef9c22 --- /dev/null +++ b/test/runtime/samples/dynamic-element-event-handler1/main.svelte @@ -0,0 +1,6 @@ + + +Foo \ No newline at end of file diff --git a/test/runtime/samples/dynamic-element-event-handler2/_config.js b/test/runtime/samples/dynamic-element-event-handler2/_config.js new file mode 100644 index 0000000000..22cbe735a7 --- /dev/null +++ b/test/runtime/samples/dynamic-element-event-handler2/_config.js @@ -0,0 +1,23 @@ +let clicked = false; +function handler() { + clicked = true; +} + +export default { + props: { + tag: 'div', + handler + }, + html: '
Foo
', + + test({ assert, component, target }) { + assert.equal(clicked, false); + + component.tag = 'button'; + const button = target.querySelector('button'); + const click = new window.MouseEvent('click'); + button.dispatchEvent(click); + + assert.equal(clicked, true); + } +}; diff --git a/test/runtime/samples/dynamic-element-event-handler2/main.svelte b/test/runtime/samples/dynamic-element-event-handler2/main.svelte new file mode 100644 index 0000000000..f2534c1f62 --- /dev/null +++ b/test/runtime/samples/dynamic-element-event-handler2/main.svelte @@ -0,0 +1,6 @@ + + +Foo diff --git a/test/runtime/samples/dynamic-element-expression/_config.js b/test/runtime/samples/dynamic-element-expression/_config.js new file mode 100644 index 0000000000..acad91c901 --- /dev/null +++ b/test/runtime/samples/dynamic-element-expression/_config.js @@ -0,0 +1,3 @@ +export default { + html: '
Foo
' +}; diff --git a/test/runtime/samples/dynamic-element-expression/main.svelte b/test/runtime/samples/dynamic-element-expression/main.svelte new file mode 100644 index 0000000000..7ec11e4ef6 --- /dev/null +++ b/test/runtime/samples/dynamic-element-expression/main.svelte @@ -0,0 +1 @@ +Foo \ No newline at end of file diff --git a/test/runtime/samples/dynamic-element-invalid-this/_config.js b/test/runtime/samples/dynamic-element-invalid-this/_config.js new file mode 100644 index 0000000000..3aaa554991 --- /dev/null +++ b/test/runtime/samples/dynamic-element-invalid-this/_config.js @@ -0,0 +1,9 @@ +export default { + compileOptions: { + dev: true + }, + props: { + tag: 123 + }, + error: ' expects "this" attribute to be a string.' +}; diff --git a/test/runtime/samples/dynamic-element-invalid-this/main.svelte b/test/runtime/samples/dynamic-element-invalid-this/main.svelte new file mode 100644 index 0000000000..bcc2c293bb --- /dev/null +++ b/test/runtime/samples/dynamic-element-invalid-this/main.svelte @@ -0,0 +1,5 @@ + + + diff --git a/test/runtime/samples/dynamic-element-null-tag/_config.js b/test/runtime/samples/dynamic-element-null-tag/_config.js new file mode 100644 index 0000000000..22dc25b41e --- /dev/null +++ b/test/runtime/samples/dynamic-element-null-tag/_config.js @@ -0,0 +1,3 @@ +export default { + html: '' +}; diff --git a/test/runtime/samples/dynamic-element-null-tag/main.svelte b/test/runtime/samples/dynamic-element-null-tag/main.svelte new file mode 100644 index 0000000000..58dc96ff2a --- /dev/null +++ b/test/runtime/samples/dynamic-element-null-tag/main.svelte @@ -0,0 +1,5 @@ + + +Foo diff --git a/test/runtime/samples/dynamic-element-pass-props/_config.js b/test/runtime/samples/dynamic-element-pass-props/_config.js new file mode 100644 index 0000000000..35f8b7abdf --- /dev/null +++ b/test/runtime/samples/dynamic-element-pass-props/_config.js @@ -0,0 +1,16 @@ +let clicked = false; + +export default { + props: { + tag: 'div', + onClick: () => clicked = true + }, + html: '
Foo
', + + async test({ assert, target, window }) { + const div = target.querySelector('div'); + await div.dispatchEvent(new window.MouseEvent('click')); + + assert.equal(clicked, true); + } +}; diff --git a/test/runtime/samples/dynamic-element-pass-props/main.svelte b/test/runtime/samples/dynamic-element-pass-props/main.svelte new file mode 100644 index 0000000000..6a54a93f27 --- /dev/null +++ b/test/runtime/samples/dynamic-element-pass-props/main.svelte @@ -0,0 +1,6 @@ + + +Foo \ No newline at end of file diff --git a/test/runtime/samples/dynamic-element-slot/Foo.svelte b/test/runtime/samples/dynamic-element-slot/Foo.svelte new file mode 100644 index 0000000000..51dda4b7e3 --- /dev/null +++ b/test/runtime/samples/dynamic-element-slot/Foo.svelte @@ -0,0 +1,7 @@ +

Foo

+
+ +
+
+ +
diff --git a/test/runtime/samples/dynamic-element-slot/_config.js b/test/runtime/samples/dynamic-element-slot/_config.js new file mode 100644 index 0000000000..aa9da522a3 --- /dev/null +++ b/test/runtime/samples/dynamic-element-slot/_config.js @@ -0,0 +1,29 @@ +export default { + props: { + x: true + }, + + html: ` +

Foo

+
+

This is default slot

+
+
+

This is other slot

+
+ `, + + test({ assert, component, target }) { + component.tag = 'h2'; + + assert.htmlEqual(target.innerHTML, ` +

Foo

+
+

This is default slot

+
+
+

This is other slot

+
+ `); + } +}; diff --git a/test/runtime/samples/dynamic-element-slot/main.svelte b/test/runtime/samples/dynamic-element-slot/main.svelte new file mode 100644 index 0000000000..4b1cd81969 --- /dev/null +++ b/test/runtime/samples/dynamic-element-slot/main.svelte @@ -0,0 +1,10 @@ + + + + This is default slot + This is other slot + + diff --git a/test/runtime/samples/dynamic-element-store/_config.js b/test/runtime/samples/dynamic-element-store/_config.js new file mode 100644 index 0000000000..ded19eef79 --- /dev/null +++ b/test/runtime/samples/dynamic-element-store/_config.js @@ -0,0 +1,3 @@ +export default { + html: '
' +}; diff --git a/test/runtime/samples/dynamic-element-store/main.svelte b/test/runtime/samples/dynamic-element-store/main.svelte new file mode 100644 index 0000000000..84a577ecee --- /dev/null +++ b/test/runtime/samples/dynamic-element-store/main.svelte @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/test/runtime/samples/dynamic-element-string/_config.js b/test/runtime/samples/dynamic-element-string/_config.js new file mode 100644 index 0000000000..acad91c901 --- /dev/null +++ b/test/runtime/samples/dynamic-element-string/_config.js @@ -0,0 +1,3 @@ +export default { + html: '
Foo
' +}; diff --git a/test/runtime/samples/dynamic-element-string/main.svelte b/test/runtime/samples/dynamic-element-string/main.svelte new file mode 100644 index 0000000000..62d65d5f20 --- /dev/null +++ b/test/runtime/samples/dynamic-element-string/main.svelte @@ -0,0 +1 @@ +Foo \ No newline at end of file diff --git a/test/runtime/samples/dynamic-element-template-literals/_config.js b/test/runtime/samples/dynamic-element-template-literals/_config.js new file mode 100644 index 0000000000..d37164b4d8 --- /dev/null +++ b/test/runtime/samples/dynamic-element-template-literals/_config.js @@ -0,0 +1,21 @@ +export default { + props: { + size: 1 + }, + html: '

This is h1 tag

', + + test({ assert, component, target }) { + const h1 = target.firstChild; + component.size = 2; + + assert.htmlEqual( + target.innerHTML, + ` +

This is h2 tag

+ ` + ); + + const h2 = target.firstChild; + assert.notEqual(h1, h2); + } +}; diff --git a/test/runtime/samples/dynamic-element-template-literals/main.svelte b/test/runtime/samples/dynamic-element-template-literals/main.svelte new file mode 100644 index 0000000000..84b63dcca7 --- /dev/null +++ b/test/runtime/samples/dynamic-element-template-literals/main.svelte @@ -0,0 +1,5 @@ + + +This is h{size} tag diff --git a/test/runtime/samples/dynamic-element-transition/_config.js b/test/runtime/samples/dynamic-element-transition/_config.js new file mode 100644 index 0000000000..cb8474afc1 --- /dev/null +++ b/test/runtime/samples/dynamic-element-transition/_config.js @@ -0,0 +1,17 @@ +export default { + test({ assert, component, target, raf }) { + component.visible = true; + const h1 = target.querySelector('h1'); + assert.equal(h1.style.animation, '__svelte_3809512021_0 100ms linear 0ms 1 both'); + + raf.tick(150); + component.tag = 'h2'; + const h2 = target.querySelector('h2'); + assert.equal(h1.style.animation, ''); + assert.equal(h2.style.animation, ''); + + raf.tick(50); + component.visible = false; + assert.equal(h2.style.animation, '__svelte_3750847757_0 100ms linear 0ms 1 both'); + } +}; diff --git a/test/runtime/samples/dynamic-element-transition/main.svelte b/test/runtime/samples/dynamic-element-transition/main.svelte new file mode 100644 index 0000000000..b8c0eff0bd --- /dev/null +++ b/test/runtime/samples/dynamic-element-transition/main.svelte @@ -0,0 +1,17 @@ + + +{#if visible} + +{/if} diff --git a/test/runtime/samples/dynamic-element-undefined-tag/_config.js b/test/runtime/samples/dynamic-element-undefined-tag/_config.js new file mode 100644 index 0000000000..d0bd665d3d --- /dev/null +++ b/test/runtime/samples/dynamic-element-undefined-tag/_config.js @@ -0,0 +1,19 @@ +export default { + html: '', + test({ component, target, assert }) { + component.tag = 'h1'; + assert.htmlEqual(target.innerHTML, '

Foo

'); + + component.tag = null; + assert.htmlEqual(target.innerHTML, ''); + + component.tag = 'div'; + assert.htmlEqual(target.innerHTML, '
Foo
'); + + component.tag = false; + assert.htmlEqual(target.innerHTML, ''); + + component.tag = 'span'; + assert.htmlEqual(target.innerHTML, 'Foo'); + } +}; diff --git a/test/runtime/samples/dynamic-element-undefined-tag/main.svelte b/test/runtime/samples/dynamic-element-undefined-tag/main.svelte new file mode 100644 index 0000000000..6aca93ca13 --- /dev/null +++ b/test/runtime/samples/dynamic-element-undefined-tag/main.svelte @@ -0,0 +1,5 @@ + + +Foo diff --git a/test/runtime/samples/dynamic-element-variable/_config.js b/test/runtime/samples/dynamic-element-variable/_config.js new file mode 100644 index 0000000000..20e0fa9418 --- /dev/null +++ b/test/runtime/samples/dynamic-element-variable/_config.js @@ -0,0 +1,20 @@ +export default { + props: { + tag: 'div', + text: 'Foo' + }, + html: '
Foo
', + + test({ assert, component, target }) { + const div = target.firstChild; + component.tag = 'nav'; + component.text = 'Bar'; + + assert.htmlEqual(target.innerHTML, ` + + `); + + const h1 = target.firstChild; + assert.notEqual(div, h1); + } +}; diff --git a/test/runtime/samples/dynamic-element-variable/main.svelte b/test/runtime/samples/dynamic-element-variable/main.svelte new file mode 100644 index 0000000000..d60953bba5 --- /dev/null +++ b/test/runtime/samples/dynamic-element-variable/main.svelte @@ -0,0 +1,6 @@ + + +{text} \ No newline at end of file diff --git a/test/runtime/samples/inline-style-directive/_config.js b/test/runtime/samples/inline-style-directive/_config.js index ec32e157e5..f5732ae0af 100644 --- a/test/runtime/samples/inline-style-directive/_config.js +++ b/test/runtime/samples/inline-style-directive/_config.js @@ -1,6 +1,8 @@ export default { html: ` -

+
+

+
`, test({ assert, target, window }) { diff --git a/test/runtime/samples/inline-style-directive/main.svelte b/test/runtime/samples/inline-style-directive/main.svelte index 1d60aefa6f..ff8acfce68 100644 --- a/test/runtime/samples/inline-style-directive/main.svelte +++ b/test/runtime/samples/inline-style-directive/main.svelte @@ -2,4 +2,6 @@ export let myColor = "red"; -

+

+

+

diff --git a/test/runtime/samples/inline-style/_config.js b/test/runtime/samples/inline-style/_config.js index 3e984d4c69..192659346c 100644 --- a/test/runtime/samples/inline-style/_config.js +++ b/test/runtime/samples/inline-style/_config.js @@ -4,9 +4,9 @@ export default { `, test({ assert, component, target, window }) { - const p = target.querySelector('div'); + const div = target.querySelector('div'); - const styles = window.getComputedStyle(p); + const styles = window.getComputedStyle(div); assert.equal(styles.color, 'red'); } }; diff --git a/test/runtime/samples/key-block-component-slot/Component1.svelte b/test/runtime/samples/key-block-component-slot/Component1.svelte new file mode 100644 index 0000000000..d0ea817d54 --- /dev/null +++ b/test/runtime/samples/key-block-component-slot/Component1.svelte @@ -0,0 +1 @@ + diff --git a/test/runtime/samples/key-block-component-slot/Component2.svelte b/test/runtime/samples/key-block-component-slot/Component2.svelte new file mode 100644 index 0000000000..ca04744936 --- /dev/null +++ b/test/runtime/samples/key-block-component-slot/Component2.svelte @@ -0,0 +1,12 @@ + diff --git a/test/runtime/samples/key-block-component-slot/_config.js b/test/runtime/samples/key-block-component-slot/_config.js new file mode 100644 index 0000000000..8fbbeaec64 --- /dev/null +++ b/test/runtime/samples/key-block-component-slot/_config.js @@ -0,0 +1,18 @@ +const logs = []; + +export default { + html: '', + props: { + logs + }, + async test({ assert, component, target, raf }) { + assert.deepEqual(logs, ['mount']); + + const button = target.querySelector('button'); + + const click = new window.MouseEvent('click'); + await button.dispatchEvent(click); + + assert.deepEqual(logs, ['mount', 'unmount', 'mount']); + } +}; diff --git a/test/runtime/samples/key-block-component-slot/main.svelte b/test/runtime/samples/key-block-component-slot/main.svelte new file mode 100644 index 0000000000..77fde32d9c --- /dev/null +++ b/test/runtime/samples/key-block-component-slot/main.svelte @@ -0,0 +1,17 @@ + + + + {#key reset} + + {/key} + + + \ No newline at end of file diff --git a/test/server-side-rendering/samples/attribute-escaped-quotes/_expected.html b/test/server-side-rendering/samples/attribute-escaped-quotes/_expected.html index c3c9405d7b..e99c5b0f6e 100644 --- a/test/server-side-rendering/samples/attribute-escaped-quotes/_expected.html +++ b/test/server-side-rendering/samples/attribute-escaped-quotes/_expected.html @@ -1,3 +1,4 @@
\ No newline at end of file + foo="">\" + bar="">\" +> diff --git a/test/server-side-rendering/samples/attribute-escaped-quotes/main.svelte b/test/server-side-rendering/samples/attribute-escaped-quotes/main.svelte index ed34f4d129..aeed0f20d1 100644 --- a/test/server-side-rendering/samples/attribute-escaped-quotes/main.svelte +++ b/test/server-side-rendering/samples/attribute-escaped-quotes/main.svelte @@ -1,5 +1,6 @@ -
\ No newline at end of file +
diff --git a/test/server-side-rendering/samples/dynamic-element-string/_expected.html b/test/server-side-rendering/samples/dynamic-element-string/_expected.html new file mode 100644 index 0000000000..cb98432e14 --- /dev/null +++ b/test/server-side-rendering/samples/dynamic-element-string/_expected.html @@ -0,0 +1 @@ +
Foo
diff --git a/test/server-side-rendering/samples/dynamic-element-string/main.svelte b/test/server-side-rendering/samples/dynamic-element-string/main.svelte new file mode 100644 index 0000000000..62d65d5f20 --- /dev/null +++ b/test/server-side-rendering/samples/dynamic-element-string/main.svelte @@ -0,0 +1 @@ +Foo \ No newline at end of file diff --git a/test/server-side-rendering/samples/dynamic-element-variable/_expected.html b/test/server-side-rendering/samples/dynamic-element-variable/_expected.html new file mode 100644 index 0000000000..3ae445f54c --- /dev/null +++ b/test/server-side-rendering/samples/dynamic-element-variable/_expected.html @@ -0,0 +1,2 @@ +

Foo

+
Bar
\ No newline at end of file diff --git a/test/server-side-rendering/samples/dynamic-element-variable/main.svelte b/test/server-side-rendering/samples/dynamic-element-variable/main.svelte new file mode 100644 index 0000000000..9aaba18bf1 --- /dev/null +++ b/test/server-side-rendering/samples/dynamic-element-variable/main.svelte @@ -0,0 +1,7 @@ + + +Foo +Bar \ No newline at end of file diff --git a/test/validator/samples/animation-comment-siblings/errors.json b/test/validator/samples/animation-comment-siblings/errors.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/test/validator/samples/animation-comment-siblings/errors.json @@ -0,0 +1 @@ +[] diff --git a/test/validator/samples/animation-comment-siblings/input.svelte b/test/validator/samples/animation-comment-siblings/input.svelte new file mode 100644 index 0000000000..1c8170950b --- /dev/null +++ b/test/validator/samples/animation-comment-siblings/input.svelte @@ -0,0 +1,9 @@ + + +{#each things as thing (thing)} + +
+{/each} \ No newline at end of file diff --git a/test/validator/samples/dynamic-element-invalid-tag/errors.json b/test/validator/samples/dynamic-element-invalid-tag/errors.json new file mode 100644 index 0000000000..c8d3c52490 --- /dev/null +++ b/test/validator/samples/dynamic-element-invalid-tag/errors.json @@ -0,0 +1,17 @@ +[ + { + "message": "Invalid element definition", + "code": "invalid-element-definition", + "start": { + "line": 2, + "column": 17, + "character": 23 + }, + "end": { + "line": 2, + "column": 17, + "character": 23 + }, + "pos": 23 + } +] diff --git a/test/validator/samples/dynamic-element-invalid-tag/input.svelte b/test/validator/samples/dynamic-element-invalid-tag/input.svelte new file mode 100644 index 0000000000..bc6b8be822 --- /dev/null +++ b/test/validator/samples/dynamic-element-invalid-tag/input.svelte @@ -0,0 +1,3 @@ +
+ foo +
diff --git a/test/validator/samples/dynamic-element-missing-tag/errors.json b/test/validator/samples/dynamic-element-missing-tag/errors.json new file mode 100644 index 0000000000..8243deeb80 --- /dev/null +++ b/test/validator/samples/dynamic-element-missing-tag/errors.json @@ -0,0 +1,15 @@ +[{ + "code": "missing-element-definition", + "message": " must have a 'this' attribute", + "start": { + "line": 2, + "column": 1, + "character": 7 + }, + "end": { + "line": 2, + "column": 1, + "character": 7 + }, + "pos": 7 +}] diff --git a/test/validator/samples/dynamic-element-missing-tag/input.svelte b/test/validator/samples/dynamic-element-missing-tag/input.svelte new file mode 100644 index 0000000000..4b645d25a1 --- /dev/null +++ b/test/validator/samples/dynamic-element-missing-tag/input.svelte @@ -0,0 +1,3 @@ +
+ foo +
diff --git a/test/validator/samples/dynamic-element-this/errors.json b/test/validator/samples/dynamic-element-this/errors.json new file mode 100644 index 0000000000..7d61c20ee2 --- /dev/null +++ b/test/validator/samples/dynamic-element-this/errors.json @@ -0,0 +1,15 @@ +[{ + "code": "unexpected-reserved-word", + "message": "'this' is a reserved word in JavaScript and cannot be used here", + "start": { + "line": 2, + "column": 18, + "character": 24 + }, + "end": { + "line": 2, + "column": 18, + "character": 24 + }, + "pos": 24 + }] diff --git a/test/validator/samples/dynamic-element-this/input.svelte b/test/validator/samples/dynamic-element-this/input.svelte new file mode 100644 index 0000000000..1a5079b924 --- /dev/null +++ b/test/validator/samples/dynamic-element-this/input.svelte @@ -0,0 +1,3 @@ +
+ foo +
diff --git a/test/validator/samples/unreferenced-variables/input.svelte b/test/validator/samples/unreferenced-variables/input.svelte index 8c9e0b15f3..cebd861985 100644 --- a/test/validator/samples/unreferenced-variables/input.svelte +++ b/test/validator/samples/unreferenced-variables/input.svelte @@ -1,25 +1,48 @@ + + -{$q} +{$q2} diff --git a/test/validator/samples/unreferenced-variables/warnings.json b/test/validator/samples/unreferenced-variables/warnings.json index dfac58ebdb..4097ba023b 100644 --- a/test/validator/samples/unreferenced-variables/warnings.json +++ b/test/validator/samples/unreferenced-variables/warnings.json @@ -2,76 +2,76 @@ { "code": "unused-export-let", "end": { - "character": 103, - "column": 12, - "line": 8 + "character": 519, + "column": 13, + "line": 31 }, - "message": "Component has unused export property 'd'. If it is for external reference only, please consider using `export const d`", - "pos": 102, + "message": "Component has unused export property 'd2'. If it is for external reference only, please consider using `export const d2`", + "pos": 517, "start": { - "character": 102, + "character": 517, "column": 11, - "line": 8 + "line": 31 } }, { "code": "unused-export-let", "end": { - "character": 106, - "column": 15, - "line": 8 + "character": 523, + "column": 17, + "line": 31 }, - "message": "Component has unused export property 'e'. If it is for external reference only, please consider using `export const e`", - "pos": 105, + "message": "Component has unused export property 'e2'. If it is for external reference only, please consider using `export const e2`", + "pos": 521, "start": { - "character": 105, - "column": 14, - "line": 8 + "character": 521, + "column": 15, + "line": 31 } }, { "code": "unused-export-let", "end": { - "character": 130, - "column": 18, - "line": 9 + "character": 549, + "column": 19, + "line": 32 }, - "message": "Component has unused export property 'g'. If it is for external reference only, please consider using `export const g`", - "pos": 125, + "message": "Component has unused export property 'g2'. If it is for external reference only, please consider using `export const g2`", + "pos": 543, "start": { - "character": 125, + "character": 543, "column": 13, - "line": 9 + "line": 32 } }, { "code": "unused-export-let", "end": { - "character": 150, - "column": 18, - "line": 10 + "character": 570, + "column": 19, + "line": 33 }, - "message": "Component has unused export property 'h'. If it is for external reference only, please consider using `export const h`", - "pos": 145, + "message": "Component has unused export property 'h2'. If it is for external reference only, please consider using `export const h2`", + "pos": 564, "start": { - "character": 145, + "character": 564, "column": 13, - "line": 10 + "line": 33 } }, { "code": "unused-export-let", "end": { - "character": 199, - "column": 25, - "line": 12 + "character": 621, + "column": 26, + "line": 35 }, - "message": "Component has unused export property 'j'. If it is for external reference only, please consider using `export const j`", - "pos": 187, + "message": "Component has unused export property 'j2'. If it is for external reference only, please consider using `export const j2`", + "pos": 608, "start": { - "character": 187, + "character": 608, "column": 13, - "line": 12 + "line": 35 } } ]