Skip to content

Commit 6eb80e3

Browse files
authored
Merge pull request #626 from sveltejs/gh-625
Unmount `yield` fragments in parent's unmount method, not destroy
2 parents 7c23579 + a88a56b commit 6eb80e3

File tree

10 files changed

+1566
-51
lines changed

10 files changed

+1566
-51
lines changed

package-lock.json

+1,449
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"babel-plugin-transform-es2015-spread": "^6.22.0",
5858
"babel-preset-env": "^1.2.1",
5959
"babel-register": "^6.23.0",
60+
"chalk": "^1.1.3",
6061
"codecov": "^1.0.1",
6162
"console-group": "^0.3.2",
6263
"css-tree": "1.0.0-alpha16",

src/generators/dom/visitors/YieldTag.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export default function visitYieldTag(
1313
`if ( ${block.component}._yield ) ${block.component}._yield.mount( ${parentNode}, null );`
1414
);
1515

16-
block.builders.destroy.addLine(
16+
block.builders.unmount.addLine(
1717
`if ( ${block.component}._yield ) ${block.component}._yield.unmount();`
1818
);
1919
}

test/helpers.js

+46-28
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
import jsdom from "jsdom";
2-
import assert from "assert";
3-
import * as fs from "fs";
1+
import jsdom from 'jsdom';
2+
import assert from 'assert';
3+
import glob from 'glob';
4+
import fs from 'fs';
5+
import chalk from 'chalk';
46

5-
import * as consoleGroup from "console-group";
7+
import * as consoleGroup from 'console-group';
68
consoleGroup.install();
79

8-
import * as sourceMapSupport from "source-map-support";
10+
import * as sourceMapSupport from 'source-map-support';
911
sourceMapSupport.install();
1012

1113
// for coverage purposes, we need to test source files,
@@ -14,8 +16,8 @@ export function loadSvelte(test) {
1416
if (test) global.__svelte_test = true;
1517

1618
const resolved = process.env.COVERAGE
17-
? require.resolve("../src/index.js")
18-
: require.resolve("../compiler/svelte.js");
19+
? require.resolve('../src/index.js')
20+
: require.resolve('../compiler/svelte.js');
1921

2022
delete require.cache[resolved];
2123
return require(resolved);
@@ -36,23 +38,23 @@ export function tryToLoadJson(file) {
3638
try {
3739
return JSON.parse(fs.readFileSync(file));
3840
} catch (err) {
39-
if (err.code !== "ENOENT") throw err;
41+
if (err.code !== 'ENOENT') throw err;
4042
return null;
4143
}
4244
}
4345

4446
export function tryToReadFile(file) {
4547
try {
46-
return fs.readFileSync(file, "utf-8");
48+
return fs.readFileSync(file, 'utf-8');
4749
} catch (err) {
48-
if (err.code !== "ENOENT") throw err;
50+
if (err.code !== 'ENOENT') throw err;
4951
return null;
5052
}
5153
}
5254

5355
export function env() {
5456
return new Promise((fulfil, reject) => {
55-
jsdom.env("<main></main>", (err, window) => {
57+
jsdom.env('<main></main>', (err, window) => {
5658
if (err) {
5759
reject(err);
5860
} else {
@@ -75,19 +77,19 @@ function cleanChildren(node) {
7577

7678
if (child.nodeType === 3) {
7779
if (
78-
node.namespaceURI === "http://www.w3.org/2000/svg" &&
79-
node.tagName !== "text" &&
80-
node.tagName !== "tspan"
80+
node.namespaceURI === 'http://www.w3.org/2000/svg' &&
81+
node.tagName !== 'text' &&
82+
node.tagName !== 'tspan'
8183
) {
8284
node.removeChild(child);
8385
}
8486

85-
child.data = child.data.replace(/\s{2,}/, "\n");
87+
child.data = child.data.replace(/\s{2,}/, '\n');
8688

8789
// text
8890
if (previous && previous.nodeType === 3) {
8991
previous.data += child.data;
90-
previous.data = previous.data.replace(/\s{2,}/, "\n");
92+
previous.data = previous.data.replace(/\s{2,}/, '\n');
9193

9294
node.removeChild(child);
9395
child = previous;
@@ -101,12 +103,12 @@ function cleanChildren(node) {
101103

102104
// collapse whitespace
103105
if (node.firstChild && node.firstChild.nodeType === 3) {
104-
node.firstChild.data = node.firstChild.data.replace(/^\s+/, "");
106+
node.firstChild.data = node.firstChild.data.replace(/^\s+/, '');
105107
if (!node.firstChild.data) node.removeChild(node.firstChild);
106108
}
107109

108110
if (node.lastChild && node.lastChild.nodeType === 3) {
109-
node.lastChild.data = node.lastChild.data.replace(/\s+$/, "");
111+
node.lastChild.data = node.lastChild.data.replace(/\s+$/, '');
110112
if (!node.lastChild.data) node.removeChild(node.lastChild);
111113
}
112114
}
@@ -115,15 +117,15 @@ export function setupHtmlEqual() {
115117
return env().then(window => {
116118
assert.htmlEqual = (actual, expected, message) => {
117119
window.document.body.innerHTML = actual
118-
.replace(/>[\s\r\n]+</g, "><")
120+
.replace(/>[\s\r\n]+</g, '><')
119121
.trim();
120-
cleanChildren(window.document.body, "");
122+
cleanChildren(window.document.body, '');
121123
actual = window.document.body.innerHTML;
122124

123125
window.document.body.innerHTML = expected
124-
.replace(/>[\s\r\n]+</g, "><")
126+
.replace(/>[\s\r\n]+</g, '><')
125127
.trim();
126-
cleanChildren(window.document.body, "");
128+
cleanChildren(window.document.body, '');
127129
expected = window.document.body.innerHTML;
128130

129131
assert.deepEqual(actual, expected, message);
@@ -137,7 +139,7 @@ export function loadConfig(file) {
137139
delete require.cache[resolved];
138140
return require(resolved).default;
139141
} catch (err) {
140-
if (err.code === "E_NOT_FOUND") {
142+
if (err.code === 'E_NOT_FOUND') {
141143
return {};
142144
}
143145

@@ -147,16 +149,32 @@ export function loadConfig(file) {
147149

148150
export function addLineNumbers(code) {
149151
return code
150-
.split("\n")
152+
.split('\n')
151153
.map((line, i) => {
152154
i = String(i + 1);
153155
while (i.length < 3) i = ` ${i}`;
154156

155-
return `${i}: ${line.replace(/^\t+/, match =>
156-
match.split("\t").join(" ")
157-
)}`;
157+
return (
158+
chalk.grey(` ${i}: `) +
159+
line.replace(/^\t+/, match => match.split('\t').join(' '))
160+
);
158161
})
159-
.join("\n");
162+
.join('\n');
163+
}
164+
165+
export function showOutput(cwd, shared) {
166+
glob.sync('**/*.html', { cwd }).forEach(file => {
167+
const { code } = svelte.compile(
168+
fs.readFileSync(`${cwd}/${file}`, 'utf-8'),
169+
{
170+
shared
171+
}
172+
);
173+
174+
console.log( // eslint-disable-line no-console
175+
`\n>> ${chalk.cyan.bold(file)}\n${addLineNumbers(code)}\n<< ${chalk.cyan.bold(file)}`
176+
);
177+
});
160178
}
161179

162180
const start = /\n(\t+)/;

test/runtime/index.js

+25-22
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ import assert from "assert";
22
import * as path from "path";
33
import * as fs from "fs";
44
import * as acorn from "acorn";
5-
import * as babel from "babel-core";
65
import { transitionManager } from "../../shared.js";
76

87
import {
9-
addLineNumbers,
8+
showOutput,
109
loadConfig,
1110
loadSvelte,
1211
env,
@@ -16,7 +15,6 @@ import {
1615

1716
let svelte;
1817

19-
let showCompiledCode = false;
2018
let compileOptions = null;
2119

2220
function getName(filename) {
@@ -35,9 +33,7 @@ require.extensions[".html"] = function(module, filename) {
3533
);
3634
let { code } = svelte.compile(fs.readFileSync(filename, "utf-8"), options);
3735

38-
if (showCompiledCode) console.log(addLineNumbers(code)); // eslint-disable-line no-console
39-
40-
if (legacy) code = babel.transform(code, babelrc).code;
36+
if (legacy) code = require('babel-core').transform(code, babelrc).code;
4137

4238
return module._compile(code, filename);
4339
};
@@ -50,6 +46,8 @@ describe("runtime", () => {
5046
return setupHtmlEqual();
5147
});
5248

49+
const failed = new Set();
50+
5351
function runTest(dir, shared) {
5452
if (dir[0] === ".") return;
5553

@@ -59,10 +57,15 @@ describe("runtime", () => {
5957
throw new Error("Forgot to remove `solo: true` from test");
6058
}
6159

62-
(config.skip ? it.skip : config.solo ? it.only : it)(dir, () => {
60+
(config.skip ? it.skip : config.solo ? it.only : it)(`${dir} (${shared ? 'shared' : 'inline'} helpers`, () => {
61+
if (failed.has(dir)) {
62+
// this makes debugging easier, by only printing compiled output once
63+
throw new Error('skipping inline helpers test');
64+
}
65+
66+
const cwd = path.resolve(`test/runtime/samples/${dir}`);
6367
let compiled;
6468

65-
showCompiledCode = config.show;
6669
compileOptions = config.compileOptions || {};
6770
compileOptions.shared = shared;
6871
compileOptions.dev = config.dev;
@@ -78,6 +81,8 @@ describe("runtime", () => {
7881
config.compileError(err);
7982
return;
8083
} else {
84+
failed.add(dir);
85+
showOutput(cwd, shared);
8186
throw err;
8287
}
8388
}
@@ -91,11 +96,12 @@ describe("runtime", () => {
9196
if (startIndex === -1)
9297
throw new Error("missing create_main_fragment");
9398
const es5 =
94-
spaces(startIndex) +
99+
code.slice(0, startIndex).split('\n').map(x => spaces(x.length)).join('\n') +
95100
code.slice(startIndex).replace(/export default .+/, "");
96101
acorn.parse(es5, { ecmaVersion: 5 });
97102
} catch (err) {
98-
if (!config.show) console.log(addLineNumbers(code)); // eslint-disable-line no-console
103+
failed.add(dir);
104+
showOutput(cwd, shared); // eslint-disable-line no-console
99105
throw err;
100106
}
101107
}
@@ -140,7 +146,7 @@ describe("runtime", () => {
140146
try {
141147
SvelteComponent = require(`./samples/${dir}/main.html`).default;
142148
} catch (err) {
143-
if (!config.show) console.log(addLineNumbers(code)); // eslint-disable-line no-console
149+
showOutput(cwd, shared); // eslint-disable-line no-console
144150
throw err;
145151
}
146152

@@ -203,24 +209,21 @@ describe("runtime", () => {
203209
if (config.error && !unintendedError) {
204210
config.error(assert, err);
205211
} else {
206-
if (!config.show) console.log(addLineNumbers(code)); // eslint-disable-line no-console
212+
failed.add(dir);
213+
showOutput(cwd, shared); // eslint-disable-line no-console
207214
throw err;
208215
}
216+
})
217+
.then(() => {
218+
if (config.show) showOutput(cwd, shared);
209219
});
210220
});
211221
}
212222

213-
describe("inline helpers", () => {
214-
fs.readdirSync("test/runtime/samples").forEach(dir => {
215-
runTest(dir, null);
216-
});
217-
});
218-
219223
const shared = path.resolve("shared.js");
220-
describe("shared helpers", () => {
221-
fs.readdirSync("test/runtime/samples").forEach(dir => {
222-
runTest(dir, shared);
223-
});
224+
fs.readdirSync("test/runtime/samples").forEach(dir => {
225+
runTest(dir, shared);
226+
runTest(dir, null);
224227
});
225228

226229
it("fails if options.target is missing in dev mode", () => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Level2>
2+
<Level3 />
3+
</Level2>
4+
5+
<script>
6+
import Level2 from './Level2.html';
7+
import Level3 from './Level3.html';
8+
9+
export default {
10+
components: {
11+
Level2,
12+
Level3
13+
}
14+
}
15+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<span>level 2</span>
2+
{{yield}}
3+
4+
<script>
5+
import Level3 from './Level3.html';
6+
7+
export default {
8+
components: {
9+
Level3
10+
}
11+
};
12+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<span>level 3</span>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default {
2+
test(assert, component) {
3+
component.refs.l1.destroy();
4+
}
5+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<Level1 ref:l1 />
2+
3+
<script>
4+
import Level1 from './Level1.html';
5+
6+
export default {
7+
components: {
8+
Level1
9+
}
10+
}
11+
</script>

0 commit comments

Comments
 (0)