Merge branch 'master' into pr/4487

pull/4487/head
Conduitry 6 years ago
commit 0163a278e4

@ -2,7 +2,10 @@
## Unreleased ## Unreleased
* In `vars` array, correctly indicate whether `module` variables are `mutated` or `reassigned` ([#3215](https://github.com/sveltejs/svelte/issues/3215))
* 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)) * 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 ## 3.19.1

@ -32,6 +32,8 @@ cd svelte
npm install 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 `<LF>`. On Windows, you can ensure this by cloning with: > Many tests depend on newlines being preserved as `<LF>`. On Windows, you can ensure this by cloning with:
> ```bash > ```bash
> git -c core.autocrlf=false clone https://github.com/sveltejs/svelte.git > git -c core.autocrlf=false clone https://github.com/sveltejs/svelte.git

111
package-lock.json generated

@ -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": { "@types/eslint-visitor-keys": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
@ -609,16 +615,16 @@
} }
}, },
"codecov": { "codecov": {
"version": "3.5.0", "version": "3.6.5",
"resolved": "https://registry.npmjs.org/codecov/-/codecov-3.5.0.tgz", "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.6.5.tgz",
"integrity": "sha512-/OsWOfIHaQIr7aeZ4pY0UC1PZT6kimoKFOFYFNb6wxo3iw12nRrh+mNGH72rnXxNsq6SGfesVPizm/6Q3XqcFQ==", "integrity": "sha512-v48WuDMUug6JXwmmfsMzhCHRnhUf8O3duqXvltaYJKrO1OekZWpB/eH6iIoaxMl8Qli0+u3OxptdsBOYiD7VAQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"argv": "^0.0.2", "argv": "0.0.2",
"ignore-walk": "^3.0.1", "ignore-walk": "3.0.3",
"js-yaml": "^3.13.1", "js-yaml": "3.13.1",
"teeny-request": "^3.11.3", "teeny-request": "6.0.1",
"urlgrey": "^0.4.4" "urlgrey": "0.4.4"
} }
}, },
"color-convert": { "color-convert": {
@ -1670,6 +1676,37 @@
"whatwg-encoding": "^1.0.1" "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": { "http-signature": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
@ -1707,9 +1744,9 @@
"dev": true "dev": true
}, },
"ignore-walk": { "ignore-walk": {
"version": "3.0.1", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz",
"integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==",
"dev": true, "dev": true,
"requires": { "requires": {
"minimatch": "^3.0.4" "minimatch": "^3.0.4"
@ -3362,6 +3399,15 @@
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
"dev": true "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": { "string-width": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
@ -3409,6 +3455,12 @@
"integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
"dev": true "dev": true
}, },
"stubs": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz",
"integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=",
"dev": true
},
"sucrase": { "sucrase": {
"version": "3.10.1", "version": "3.10.1",
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.10.1.tgz", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.10.1.tgz",
@ -3449,14 +3501,43 @@
} }
}, },
"teeny-request": { "teeny-request": {
"version": "3.11.3", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-6.0.1.tgz",
"integrity": "sha512-CKncqSF7sH6p4rzCgkb/z/Pcos5efl0DmolzvlqRQUNcpRIruOhY9+T1FsIlyEbfWd7MsFpodROOwHYh2BaXzw==", "integrity": "sha512-TAK0c9a00ELOqLrZ49cFxvPVogMUFaWY8dUsQc/0CuQPGF+BOxOQzXfE413BAk2kLomwNplvdtMpeaeGWmoc2g==",
"dev": true, "dev": true,
"requires": { "requires": {
"https-proxy-agent": "^2.2.1", "http-proxy-agent": "^4.0.0",
"https-proxy-agent": "^4.0.0",
"node-fetch": "^2.2.0", "node-fetch": "^2.2.0",
"stream-events": "^1.0.5",
"uuid": "^3.3.2" "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": { "test-exclude": {

@ -113,7 +113,8 @@ const {
* `module` is `true` if the value is declared in a `context="module"` script * `module` is `true` if the value is declared in a `context="module"` script
* `mutated` is `true` if the value's properties are assigned to inside the component * `mutated` is `true` if the value's properties are assigned to inside the component
* `reassigned` is `true` if the value is reassigned inside the component * `reassigned` is `true` if the value is reassigned inside the component
* `referenced` is `true` if the value is used outside the declaration * `referenced` is `true` if the value is used in the template
* `referenced_from_script` is `true` if the value is used in the `<script>` outside the declaration
* `writable` is `true` if the value was declared with `let` or `var` (but not `const`, `class` or `function`) * `writable` is `true` if the value was declared with `let` or `var` (but not `const`, `class` or `function`)
* `stats` is an object used by the Svelte developer team for diagnosing the compiler. Avoid relying on it to stay the same! * `stats` is an object used by the Svelte developer team for diagnosing the compiler. Avoid relying on it to stay the same!
@ -144,6 +145,7 @@ compiled: {
mutated: boolean, mutated: boolean,
reassigned: boolean, reassigned: boolean,
referenced: boolean, referenced: boolean,
referenced_from_script: boolean,
writable: boolean writable: boolean
}>, }>,
stats: { stats: {

@ -239,7 +239,7 @@ export default class Component {
const program: any = { type: 'Program', body: result.js }; const program: any = { type: 'Program', body: result.js };
walk(program, { walk(program, {
enter: (node, parent, key) => { enter: (node: Node, parent: Node, key) => {
if (node.type === 'Identifier') { if (node.type === 'Identifier') {
if (node.name[0] === '@') { if (node.name[0] === '@') {
if (node.name[1] === '_') { if (node.name[1] === '_') {
@ -526,7 +526,7 @@ export default class Component {
if (!script) return; if (!script) return;
walk(script.content, { walk(script.content, {
enter(node) { enter(node: Node) {
if (node.type === 'LabeledStatement' && node.label.name === '$') { if (node.type === 'LabeledStatement' && node.label.name === '$') {
component.warn(node as any, { component.warn(node as any, {
code: 'module-script-reactive-declaration', code: 'module-script-reactive-declaration',
@ -715,7 +715,7 @@ export default class Component {
let scope_updated = false; let scope_updated = false;
walk(content, { walk(content, {
enter(node, parent, prop, index) { enter(node: Node, parent, prop, index) {
if (map.has(node)) { if (map.has(node)) {
scope = map.get(node); scope = map.get(node);
} }
@ -741,7 +741,7 @@ export default class Component {
component.warn_on_undefined_store_value_references(node, parent, scope); component.warn_on_undefined_store_value_references(node, parent, scope);
}, },
leave(node) { leave(node: Node) {
// do it on leave, to prevent infinite loop // do it on leave, to prevent infinite loop
if (component.compile_options.dev && component.compile_options.loopGuardTimeout > 0) { if (component.compile_options.dev && component.compile_options.loopGuardTimeout > 0) {
const to_replace_for_loop_protect = component.loop_protect(node, scope, component.compile_options.loopGuardTimeout); const to_replace_for_loop_protect = component.loop_protect(node, scope, component.compile_options.loopGuardTimeout);
@ -780,12 +780,12 @@ export default class Component {
const component = this; const component = this;
const { content } = script; const { content } = script;
const { instance_scope, instance_scope_map: map } = this; const { instance_scope, module_scope, instance_scope_map: map } = this;
let scope = instance_scope; let scope = instance_scope;
walk(content, { walk(content, {
enter(node, parent) { enter(node: Node, parent: Node) {
if (map.has(node)) { if (map.has(node)) {
scope = map.get(node); scope = map.get(node);
} }
@ -797,7 +797,12 @@ export default class Component {
const deep = assignee.type === 'MemberExpression'; const deep = assignee.type === 'MemberExpression';
names.forEach(name => { names.forEach(name => {
if (scope.find_owner(name) === instance_scope) { const scope_owner = scope.find_owner(name);
if (
scope_owner !== null
? scope_owner === instance_scope
: module_scope && module_scope.has(name)
) {
const variable = component.var_lookup.get(name); const variable = component.var_lookup.get(name);
variable[deep ? 'mutated' : 'reassigned'] = true; variable[deep ? 'mutated' : 'reassigned'] = true;
} }
@ -813,7 +818,7 @@ export default class Component {
} }
}, },
leave(node) { leave(node: Node) {
if (map.has(node)) { if (map.has(node)) {
scope = scope.parent; scope = scope.parent;
} }
@ -881,7 +886,7 @@ export default class Component {
let scope = instance_scope; let scope = instance_scope;
walk(this.ast.instance.content, { walk(this.ast.instance.content, {
enter(node, parent, key, index) { enter(node: Node, parent, key, index) {
if (/Function/.test(node.type)) { if (/Function/.test(node.type)) {
return this.skip(); return this.skip();
} }
@ -958,7 +963,7 @@ export default class Component {
} }
}, },
leave(node, parent, _key, index) { leave(node: Node, parent, _key, index) {
if (map.has(node)) { if (map.has(node)) {
scope = scope.parent; scope = scope.parent;
} }
@ -1059,7 +1064,7 @@ export default class Component {
walking.add(fn_declaration); walking.add(fn_declaration);
walk(fn_declaration, { walk(fn_declaration, {
enter(node, parent) { enter(node: Node, parent) {
if (!hoistable) return this.skip(); if (!hoistable) return this.skip();
if (map.has(node)) { if (map.has(node)) {
@ -1107,7 +1112,7 @@ export default class Component {
} }
}, },
leave(node) { leave(node: Node) {
if (map.has(node)) { if (map.has(node)) {
scope = scope.parent; scope = scope.parent;
} }
@ -1150,7 +1155,7 @@ export default class Component {
const map = this.instance_scope_map; const map = this.instance_scope_map;
walk(node.body, { walk(node.body, {
enter(node, parent) { enter(node: Node, parent) {
if (map.has(node)) { if (map.has(node)) {
scope = map.get(node); scope = map.get(node);
} }
@ -1190,7 +1195,7 @@ export default class Component {
} }
}, },
leave(node) { leave(node: Node) {
if (map.has(node)) { if (map.has(node)) {
scope = scope.parent; scope = scope.parent;
} }

@ -1,7 +1,7 @@
import Node from './shared/Node'; import Node from './shared/Node';
import Component from '../Component'; import Component from '../Component';
import { walk } from 'estree-walker'; import { walk } from 'estree-walker';
import { Identifier } from 'estree'; import { BasePattern, Identifier } from 'estree';
const applicable = new Set(['Identifier', 'ObjectExpression', 'ArrayExpression', 'Property']); const applicable = new Set(['Identifier', 'ObjectExpression', 'ArrayExpression', 'Property']);
@ -22,7 +22,7 @@ export default class Let extends Node {
this.value = info.expression; this.value = info.expression;
walk(info.expression, { walk(info.expression, {
enter(node) { enter(node: Identifier|BasePattern) {
if (!applicable.has(node.type)) { if (!applicable.has(node.type)) {
component.error(node as any, { component.error(node as any, {
code: 'invalid-let', code: 'invalid-let',
@ -31,16 +31,16 @@ export default class Let extends Node {
} }
if (node.type === 'Identifier') { if (node.type === 'Identifier') {
names.push(node.name); names.push((node as Identifier).name);
} }
// slightly unfortunate hack // slightly unfortunate hack
if (node.type === 'ArrayExpression') { if (node.type === 'ArrayExpression') {
(node as any).type = 'ArrayPattern'; node.type = 'ArrayPattern';
} }
if (node.type === 'ObjectExpression') { if (node.type === 'ObjectExpression') {
(node as any).type = 'ObjectPattern'; node.type = 'ObjectPattern';
} }
} }
}); });

@ -143,7 +143,7 @@ export default class Expression {
} }
}, },
leave(node) { leave(node: Node) {
if (map.has(node)) { if (map.has(node)) {
scope = scope.parent; scope = scope.parent;
} }
@ -338,7 +338,7 @@ export default class Expression {
}); });
} }
return (this.manipulated = node); return (this.manipulated = node as Node);
} }
} }

@ -200,7 +200,7 @@ export default function dom(
let execution_context: Node | null = null; let execution_context: Node | null = null;
walk(component.ast.instance.content, { walk(component.ast.instance.content, {
enter(node) { enter(node: Node) {
if (map.has(node)) { if (map.has(node)) {
scope = map.get(node) as Scope; scope = map.get(node) as Scope;
@ -212,7 +212,7 @@ export default function dom(
} }
}, },
leave(node) { leave(node: Node) {
if (map.has(node)) { if (map.has(node)) {
scope = scope.parent; scope = scope.parent;
} }
@ -259,6 +259,9 @@ export default function dom(
inject_state; inject_state;
if (has_invalidate) { if (has_invalidate) {
args.push(x`$$props`, x`$$invalidate`); args.push(x`$$props`, x`$$invalidate`);
} else if (component.compile_options.dev) {
// $$props arg is still needed for unknown prop check
args.push(x`$$props`);
} }
const has_create_fragment = block.has_content(); const has_create_fragment = block.has_content();
@ -300,6 +303,7 @@ export default function dom(
const initial_context = renderer.context.slice(0, i + 1); const initial_context = renderer.context.slice(0, i + 1);
const has_definition = ( const has_definition = (
component.compile_options.dev ||
(instance_javascript && instance_javascript.length > 0) || (instance_javascript && instance_javascript.length > 0) ||
filtered_props.length > 0 || filtered_props.length > 0 ||
uses_props || uses_props ||
@ -379,7 +383,7 @@ export default function dom(
}); });
let unknown_props_check; let unknown_props_check;
if (component.compile_options.dev && !component.var_lookup.has('$$props') && writable_props.length) { if (component.compile_options.dev && !component.var_lookup.has('$$props')) {
unknown_props_check = b` unknown_props_check = b`
const writable_props = [${writable_props.map(prop => x`'${prop.export_name}'`)}]; const writable_props = [${writable_props.map(prop => x`'${prop.export_name}'`)}];
@_Object.keys($$props).forEach(key => { @_Object.keys($$props).forEach(key => {

@ -83,7 +83,11 @@ export function get_slot_changes(definition, $$scope, dirty, fn) {
if (definition[2] && fn) { if (definition[2] && fn) {
const lets = definition[2](fn(dirty)); const lets = definition[2](fn(dirty));
if (typeof $$scope.dirty === 'object') { if ($$scope.dirty === undefined) {
return lets;
}
if (typeof lets === 'object') {
const merged = []; const merged = [];
const len = Math.max($$scope.dirty.length, lets.length); const len = Math.max($$scope.dirty.length, lets.length);
for (let i = 0; i < len; i += 1) { for (let i = 0; i < len; i += 1) {

@ -50,6 +50,12 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) { function instance($$self, $$props, $$invalidate) {
let obj = { x: 5 }; let obj = { x: 5 };
let kobzol = 5; let kobzol = 5;
const writable_props = [];
Object.keys($$props).forEach(key => {
if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<Component> was created with unknown prop '${key}'`);
});
$$self.$capture_state = () => ({ obj, kobzol }); $$self.$capture_state = () => ({ obj, kobzol });
$$self.$inject_state = $$props => { $$self.$inject_state = $$props => {

@ -134,10 +134,20 @@ function create_fragment(ctx) {
return block; 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(`<Component> was created with unknown prop '${key}'`);
});
return [];
}
class Component extends SvelteComponentDev { class Component extends SvelteComponentDev {
constructor(options) { constructor(options) {
super(options); super(options);
init(this, options, null, create_fragment, safe_not_equal, {}); init(this, options, instance, create_fragment, safe_not_equal, {});
dispatch_dev("SvelteRegisterComponent", { dispatch_dev("SvelteRegisterComponent", {
component: this, component: this,

@ -6,6 +6,7 @@ import {
detach_dev, detach_dev,
dispatch_dev, dispatch_dev,
element, element,
globals,
init, init,
insert_dev, insert_dev,
loop_guard, loop_guard,
@ -13,6 +14,7 @@ import {
safe_not_equal safe_not_equal
} from "svelte/internal"; } from "svelte/internal";
const { console: console_1 } = globals;
const file = undefined; const file = undefined;
function create_fragment(ctx) { function create_fragment(ctx) {
@ -102,6 +104,12 @@ function instance($$self, $$props, $$invalidate) {
} while (true); } while (true);
} }
const writable_props = [];
Object.keys($$props).forEach(key => {
if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console_1.warn(`<Component> was created with unknown prop '${key}'`);
});
function div_binding($$value) { function div_binding($$value) {
binding_callbacks[$$value ? "unshift" : "push"](() => { binding_callbacks[$$value ? "unshift" : "push"](() => {
$$invalidate(0, node = $$value); $$invalidate(0, node = $$value);

@ -0,0 +1,9 @@
<script>
let dummy = 0;
function increment () {
dummy = 1;
}
</script>
<slot dummy={dummy}></slot>
<button on:click={increment}></button>

@ -0,0 +1,30 @@
export default {
html: `
<p>_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</p>
<p>0</p>
<button></button>
`,
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, `
<p>_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</p>
<p>1</p>
<button></button>
`);
// change from outside
component._0 = 'a';
component._40 = 'b';
assert.htmlEqual(target.innerHTML, `
<p>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</p>
<p>1</p>
<button></button>
`);
}
};

@ -0,0 +1,11 @@
<script>
import Echo from './Echo.svelte';
export let _0 = '_0', _1 = '_1', _2 = '_2', _3 = '_3', _4 = '_4', _5 = '_5', _6 = '_6', _7 = '_7', _8 = '_8', _9 = '_9', _10 = '_10', _11 = '_11', _12 = '_12', _13 = '_13', _14 = '_14', _15 = '_15', _16 = '_16', _17 = '_17', _18 = '_18', _19 = '_19', _20 = '_20', _21 = '_21', _22 = '_22', _23 = '_23', _24 = '_24', _25 = '_25', _26 = '_26', _27 = '_27', _28 = '_28', _29 = '_29', _30 = '_30', _31 = '_31', _32 = '_32', _33 = '_33', _34 = '_34', _35 = '_35', _36 = '_36', _37 = '_37', _38 = '_38', _39 = '_39', _40 = '_40';
</script>
<Echo let:dummy>
<p>{_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}</p>
<p>{dummy}</p>
</Echo>

@ -0,0 +1,11 @@
<script>
export let _0 = '_0', _1 = '_1', _2 = '_2', _3 = '_3', _4 = '_4', _5 = '_5', _6 = '_6', _7 = '_7', _8 = '_8', _9 = '_9', _10 = '_10', _11 = '_11', _12 = '_12', _13 = '_13', _14 = '_14', _15 = '_15', _16 = '_16', _17 = '_17', _18 = '_18', _19 = '_19', _20 = '_20', _21 = '_21', _22 = '_22', _23 = '_23', _24 = '_24', _25 = '_25', _26 = '_26', _27 = '_27', _28 = '_28', _29 = '_29', _30 = '_30', _31 = '_31', _32 = '_32', _33 = '_33', _34 = '_34', _35 = '_35', _36 = '_36', _37 = '_37', _38 = '_38', _39 = '_39', _40 = '_40';
let dummy = 0;
function increment () {
dummy = 1;
}
</script>
<p>{_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}</p>
<slot dummy={dummy}></slot>
<button on:click={increment}></button>

@ -0,0 +1,41 @@
export default {
html: `
<p>_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</p>
<p>0</p>
<p>0</p>
<button></button>
`,
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, `
<p>_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</p>
<p>0</p>
<p>1</p>
<button></button>
`);
// change from outside
component._0 = 'a';
assert.htmlEqual(target.innerHTML, `
<p>_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</p>
<p>a</p>
<p>1</p>
<button></button>
`);
// change from outside through props
component._40 = 'b';
assert.htmlEqual(target.innerHTML, `
<p>_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</p>
<p>a</p>
<p>1</p>
<button></button>
`);
}
};

@ -0,0 +1,12 @@
<script>
import Echo from './Echo.svelte';
export let _0 = 0, _40;
</script>
<Echo _40={_40} let:dummy>
<p>{_0}</p>
<p>{dummy}</p>
</Echo>

@ -0,0 +1,13 @@
<script>
export let _0 = '_0', _1 = '_1', _2 = '_2', _3 = '_3', _4 = '_4', _5 = '_5', _6 = '_6', _7 = '_7', _8 = '_8', _9 = '_9', _10 = '_10', _11 = '_11', _12 = '_12', _13 = '_13', _14 = '_14', _15 = '_15', _16 = '_16', _17 = '_17', _18 = '_18', _19 = '_19', _20 = '_20', _21 = '_21', _22 = '_22', _23 = '_23', _24 = '_24', _25 = '_25', _26 = '_26', _27 = '_27', _28 = '_28', _29 = '_29', _30 = '_30', _31 = '_31', _32 = '_32', _33 = '_33', _34 = '_34', _35 = '_35', _36 = '_36', _37 = '_37', _38 = '_38', _39 = '_39', _40 = '_40';
export let b = 'b';
let dummy = 0;
function increment () {
dummy = 1;
}
</script>
<p>{_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}</p>
<p>{b}</p>
<slot dummy={dummy}></slot>
<button on:click={increment}></button>

@ -0,0 +1,49 @@
export default {
html: `
<p>_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</p>
<p>b</p>
<p>-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</p>
<p>0</p>
<p>0</p>
<button></button>
`,
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, `
<p>_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</p>
<p>b</p>
<p>-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</p>
<p>0</p>
<p>1</p>
<button></button>
`);
// change from outside
component.a = 'AA';
assert.htmlEqual(target.innerHTML, `
<p>_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</p>
<p>b</p>
<p>-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</p>
<p>AA</p>
<p>1</p>
<button></button>
`);
// change from outside through props
component.b = 'BB';
assert.htmlEqual(target.innerHTML, `
<p>_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</p>
<p>BB</p>
<p>-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</p>
<p>AA</p>
<p>1</p>
<button></button>
`);
}
};

@ -0,0 +1,13 @@
<script>
import Echo from './Echo.svelte';
export let _0 = '-0', _1 = '-1', _2 = '-2', _3 = '-3', _4 = '-4', _5 = '-5', _6 = '-6', _7 = '-7', _8 = '-8', _9 = '-9', _10 = '-10', _11 = '-11', _12 = '-12', _13 = '-13', _14 = '-14', _15 = '-15', _16 = '-16', _17 = '-17', _18 = '-18', _19 = '-19', _20 = '-20', _21 = '-21', _22 = '-22', _23 = '-23', _24 = '-24', _25 = '-25', _26 = '-26', _27 = '-27', _28 = '-28', _29 = '-29', _30 = '-30', _31 = '-31', _32 = '-32', _33 = '-33', _34 = '-34', _35 = '-35', _36 = '-36', _37 = '-37', _38 = '-38', _39 = '-39', _40 = '-40';
export let a = 0, b;
</script>
<Echo b={b} let:dummy>
<p>{_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}</p>
<p>{a}</p>
<p>{dummy}</p>
</Echo>

@ -0,0 +1,9 @@
export default {
compileOptions: {
dev: true
},
warnings: [
`<Foo> was created with unknown prop 'fo'`
]
};

@ -0,0 +1,5 @@
<script>
import Foo from './Foo.svelte';
</script>
<Foo fo="sho"/>

@ -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
}
]);
}
};

@ -0,0 +1,18 @@
<script context='module'>
let a = {};
let b = {};
let c = {};
let d = {};
</script>
<script>
let c = {};
a = 1;
b.x = 1;
function foo() {
let d = {};
c = 1;
d.x = 1;
}
</script>
Loading…
Cancel
Save