Fix spread function result side effects

pull/3306/head
Vadim Cebaniuc 5 years ago
parent 8e9bbf90a1
commit 53aed12048

2
package-lock.json generated

@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "3.6.7",
"version": "3.6.9",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

@ -195,11 +195,12 @@ export default class InlineComponentWrapper extends Wrapper {
if (attr.is_spread) {
const value = attr.expression.render(block);
initial_props.push(value);
let value_object_check = value
let value_object = value
if (attr.expression.node.type !== 'ObjectExpression') {
value_object_check = `typeof ${value} === 'object' && ${value} !== null ? ${value} : {}`;
value_object = `@get_spread_object(${value})`;
}
changes.push(condition ? `${condition} && (${value_object_check})` : value_object_check);
changes.push(condition ? `${condition} && ${value_object}` : value_object);
} else {
const obj = `{ ${quote_name_if_necessary(name)}: ${attr.get_value(block)} }`;
initial_props.push(obj);

@ -35,3 +35,7 @@ export function get_spread_update(levels, updates) {
return update;
}
export function get_spread_object(spread_props) {
return typeof spread_props === 'object' && spread_props !== null ? spread_props : {};
}

@ -1,24 +0,0 @@
export default {
props: {
props: {
foo: 'lol',
baz: 40 + 2,
}
},
html: `
<div><p>foo: lol</p>
<p>baz: 42</p>
<p>qux: named</p>
`,
test({ assert, component, target }) {
component.props = true;
assert.htmlEqual(target.innerHTML, `
<div><p>foo: undefined</p>
<p>baz: undefined</p>
<p>qux: named</p>
`);
}
};

@ -1,6 +1,11 @@
<script>
export let foo;
export let baz;
export let qux;
export let corge;
</script>
{foo} {baz}
<p>foo: {foo}</p>
<p>baz: {baz}</p>
<p>qux: {qux}</p>
<p>corge: {corge}</p>

@ -1,10 +1,53 @@
export default {
html: `b baz`,
test({ assert, component, target }) {
component.bar = undefined;
assert.htmlEqual(
target.innerHTML,
`b undefined`
);
props: {
props: {
foo: 'lol',
baz: 40 + 2,
}
},
html: `
<div><p>foo: lol</p>
<p>baz: 42</p>
<p>qux: named</p>
<p>corge: b</p>
`,
test({ assert, component, target }) {
const html = `
<div><p>foo: undefined</p>
<p>baz: undefined</p>
<p>qux: named</p>
<p>corge: b</p>
`;
// test undefined
component.props = undefined;
assert.htmlEqual(target.innerHTML, html);
// set object props
component.props = this.props.props;
assert.htmlEqual(target.innerHTML, this.html);
// test null
component.props = null;
assert.htmlEqual(target.innerHTML, html);
// set object props
component.props = this.props.props;
assert.htmlEqual(target.innerHTML, this.html);
// test boolean
component.props = true;
assert.htmlEqual(target.innerHTML, html);
// set object props
component.props = this.props.props;
assert.htmlEqual(target.innerHTML, this.html);
// test number
component.props = 123;
assert.htmlEqual(target.innerHTML, html);
}
};

@ -1,10 +1,13 @@
<script>
export let foo = false;
import Widget from './Widget.svelte';
export let props;
export let corge = false;
export let a = 'a';
export let b = 'b';
export let bar = { baz: 'baz' };
import Widget from './Widget.svelte';
</script>
<Widget foo={foo ? a : b} {...bar}/>
<div>
<Widget corge={corge ? a : b} {...props} qux="named"/>
</div>

@ -1,9 +0,0 @@
<script>
export let foo;
export let baz;
export let qux;
</script>
<p>foo: {foo}</p>
<p>baz: {baz}</p>
<p>qux: {qux}</p>

@ -1,24 +0,0 @@
export default {
props: {
props: {
foo: 'lol',
baz: 40 + 2,
}
},
html: `
<div><p>foo: lol</p>
<p>baz: 42</p>
<p>qux: named</p>
`,
test({ assert, component, target }) {
component.props = null;
assert.htmlEqual(target.innerHTML, `
<div><p>foo: undefined</p>
<p>baz: undefined</p>
<p>qux: named</p>
`);
}
};

@ -1,9 +0,0 @@
<script>
import Widget from './Widget.svelte';
export let props;
</script>
<div>
<Widget {...props} qux="named"/>
</div>

@ -1,24 +0,0 @@
export default {
props: {
props: {
foo: 'lol',
baz: 40 + 2,
}
},
html: `
<div><p>foo: lol</p>
<p>baz: 42</p>
<p>qux: named</p>
`,
test({ assert, component, target }) {
component.props = 1337;
assert.htmlEqual(target.innerHTML, `
<div><p>foo: undefined</p>
<p>baz: undefined</p>
<p>qux: named</p>
`);
}
};

@ -1,9 +0,0 @@
<script>
import Widget from './Widget.svelte';
export let props;
</script>
<div>
<Widget {...props} qux="named"/>
</div>

@ -1,9 +0,0 @@
<script>
export let foo;
export let baz;
export let qux;
</script>
<p>foo: {foo}</p>
<p>baz: {baz}</p>
<p>qux: {qux}</p>

@ -1,24 +0,0 @@
export default {
props: {
props: {
foo: 'lol',
baz: 40 + 2,
}
},
html: `
<div><p>foo: lol</p>
<p>baz: 42</p>
<p>qux: named</p>
`,
test({ assert, component, target }) {
component.props = undefined;
assert.htmlEqual(target.innerHTML, `
<div><p>foo: undefined</p>
<p>baz: undefined</p>
<p>qux: named</p>
`);
}
};

@ -1,9 +0,0 @@
<script>
import Widget from './Widget.svelte';
export let props;
</script>
<div>
<Widget {...props} qux="named"/>
</div>

@ -0,0 +1,51 @@
export default {
props: {
props: {
foo: 'lol',
baz: 40 + 2,
}
},
html: `
<div><p>foo: lol</p>
<p>baz: 42</p>
<p>qux: named</p>
`,
test({ assert, component, target }) {
const html = `
<div><p>foo: undefined</p>
<p>baz: undefined</p>
<p>qux: named</p>
`;
// test undefined
component.props = undefined;
assert.htmlEqual(target.innerHTML, html);
// set object props
component.props = this.props.props;
assert.htmlEqual(target.innerHTML, this.html);
// test null
component.props = null;
assert.htmlEqual(target.innerHTML, html);
// set object props
component.props = this.props.props;
assert.htmlEqual(target.innerHTML, this.html);
// test boolean
component.props = true;
assert.htmlEqual(target.innerHTML, html);
// set object props
component.props = this.props.props;
assert.htmlEqual(target.innerHTML, this.html);
// test number
component.props = 123;
assert.htmlEqual(target.innerHTML, html);
}
};

@ -1,9 +1,9 @@
<script>
export let i;
export let foo;
export let baz;
export let qux;
</script>
<p>i: {i}</p>
<p>foo: {foo}</p>
<p>baz: {baz}</p>
<p>qux: {qux}</p>

@ -0,0 +1,19 @@
export default {
props: {},
html: `
<div><p>i: 1</p>
<p>foo: foo</p>
<p>qux: named</p>
`,
test({ assert, component, target }) {
component.foo = 'lol';
assert.htmlEqual(target.innerHTML, `
<div><p>i: 2</p>
<p>foo: lol</p>
<p>qux: named</p>
`);
}
};

@ -0,0 +1,16 @@
<script>
import Widget from './Widget.svelte';
export let foo = 'foo';
let i = 0
const getProps = (foo) => {
i += 1;
return { foo, i };
}
</script>
<div>
<Widget {...getProps(foo)} qux="named"/>
</div>
Loading…
Cancel
Save