diff --git a/.eslintignore b/.eslintignore index effb19af45..bc31435419 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,5 +1,6 @@ src/shared shared.js test/test.js +test/setup.js **/_actual.js **/expected.js \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 9eb0f07397..862286e395 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: node_js node_js: - - "4" - "6" - "node" env: diff --git a/mocha.coverage.opts b/mocha.coverage.opts index 1513d44a4b..9c3738a2df 100644 --- a/mocha.coverage.opts +++ b/mocha.coverage.opts @@ -1,5 +1,4 @@ --require babel-register ---require reify --recursive ./**/__test__.js test/*/index.js diff --git a/package.json b/package.json index 6241b9e2f3..ece5b03b8b 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "build": "node src/shared/_build.js && rollup -c", "dev": "node src/shared/_build.js && rollup -c -w", "pretest": "npm run build", - "prepublish": "npm run build && npm run lint", + "prepublishOnly": "npm run build && npm run lint", "prettier": "prettier --use-tabs --single-quote --trailing-comma es5 --write \"src/**/*.ts\"" }, "repository": { @@ -40,44 +40,31 @@ "homepage": "https://github.com/sveltejs/svelte#README", "devDependencies": { "@types/mocha": "^2.2.41", - "@types/node": "^7.0.22", - "acorn": "^4.0.4", - "babel": "^6.23.0", - "babel-core": "^6.23.1", - "babel-plugin-istanbul": "^3.0.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-preset-env": "^1.2.1", - "babel-register": "^6.23.0", - "chalk": "^1.1.3", - "codecov": "^1.0.1", + "@types/node": "^8.0.17", + "acorn": "^5.1.1", + "chalk": "^2.0.1", + "codecov": "^2.2.0", "console-group": "^0.3.2", "css-tree": "1.0.0-alpha16", - "eslint": "^3.12.2", + "eslint": "^4.3.0", "eslint-plugin-html": "^3.0.0", "eslint-plugin-import": "^2.2.0", "estree-walker": "^0.5.0", - "fuzzyset.js": "0.0.1", "glob": "^7.1.1", - "jsdom": "^9.9.1", + "jsdom": "^11.1.0", "locate-character": "^2.0.0", "magic-string": "^0.22.3", "mocha": "^3.2.0", "node-resolve": "^1.3.3", - "nyc": "^10.0.0", + "nyc": "^11.1.0", "prettier": "^1.4.1", - "reify": "^0.4.4", - "rollup": "^0.43.0", + "rollup": "^0.45.2", "rollup-plugin-buble": "^0.15.0", - "rollup-plugin-commonjs": "^7.0.0", + "rollup-plugin-commonjs": "^8.0.2", "rollup-plugin-json": "^2.1.0", - "rollup-plugin-node-resolve": "^2.0.0", + "rollup-plugin-node-resolve": "^3.0.0", "rollup-plugin-typescript": "^0.8.1", - "rollup-watch": "^3.2.2", + "rollup-watch": "^4.3.1", "source-map": "^0.5.6", "source-map-support": "^0.4.8", "typescript": "^2.3.2" @@ -91,15 +78,5 @@ "src/**/__test__.js", "src/shared/**" ] - }, - "babel": { - "plugins": [ - "transform-es2015-arrow-functions", - "transform-es2015-block-scoping", - "transform-es2015-spread", - "transform-es2015-parameters", - "transform-es2015-destructuring", - "transform-es2015-modules-commonjs" - ] } } diff --git a/src/generators/dom/index.ts b/src/generators/dom/index.ts index 03cdd0d7bd..950b9a3712 100644 --- a/src/generators/dom/index.ts +++ b/src/generators/dom/index.ts @@ -211,7 +211,7 @@ export default function dom( this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; ${generator.stylesheet.hasStyles && options.css !== false && `if ( !document.getElementById( '${generator.stylesheet.id}-style' ) ) @add_css();`} @@ -264,6 +264,7 @@ export default function dom( }; ${name}.prototype.teardown = ${name}.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return${options.dev && ` console.warn( 'Component was already destroyed' )`}; this.fire( 'destroy' ); ${templateProperties.ondestroy && `@template.ondestroy.call( this );`} @@ -272,7 +273,7 @@ export default function dom( this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; `); @@ -293,21 +294,32 @@ export default function dom( }); if (sharedPath) { - if (format !== 'es') { - throw new Error( - `Components with shared helpers must be compiled to ES2015 modules (format: 'es')` - ); + const used = Array.from(usedHelpers).sort(); + if (format === 'es') { + const names = used.map(name => { + const alias = generator.alias(name); + return name !== alias ? `${name} as ${alias}` : name; + }); + + result = + `import { ${names.join(', ')} } from ${stringify(sharedPath)};\n\n` + + result; } - const names = Array.from(usedHelpers).sort().map(name => { - return name !== generator.alias(name) - ? `${name} as ${generator.alias(name)}` - : name; - }); + else if (format === 'cjs') { + const SHARED = '__shared'; + let requires = `var ${SHARED} = require( ${stringify(sharedPath)} );`; + used.forEach(name => { + const alias = generator.alias(name); + requires += `\nvar ${alias} = ${SHARED}.${name};`; + }); - result = - `import { ${names.join(', ')} } from ${stringify(sharedPath)};\n\n` + - result; + result = `${requires}\n\n${result}`; + } + + else { + throw new Error(`Components with shared helpers must be compiled with \`format: 'es'\` or \`format: 'cjs'\``); + } } else { usedHelpers.forEach(key => { const str = shared[key]; diff --git a/test/css/index.js b/test/css/index.js index d595d5766d..460512929d 100644 --- a/test/css/index.js +++ b/test/css/index.js @@ -73,29 +73,29 @@ describe("css", () => { // verify that the right elements have scoping selectors if (expected.html !== null) { - return env().then(window => { - const Component = eval(`(function () { ${dom.code}; return SvelteComponent; }())`); - const target = window.document.querySelector("main"); + const window = env(); - new Component({ target, data: config.data }); - const html = target.innerHTML; + const Component = eval(`(function () { ${dom.code}; return SvelteComponent; }())`); + const target = window.document.querySelector("main"); - fs.writeFileSync(`test/css/samples/${dir}/_actual.html`, html); + new Component({ target, data: config.data }); + const html = target.innerHTML; - // dom - assert.equal( - normalizeHtml(window, html.replace(/svelte-\d+/g, 'svelte-xyz')), - normalizeHtml(window, expected.html) - ); + // dom + assert.equal( + normalizeHtml(window, html.replace(/svelte-\d+/g, 'svelte-xyz')), + normalizeHtml(window, expected.html) + ); - // ssr - const component = eval(`(function () { ${ssr.code}; return SvelteComponent; }())`); + fs.writeFileSync(`test/css/samples/${dir}/_actual.html`, html); - assert.equal( - normalizeHtml(window, component.render(config.data).replace(/svelte-\d+/g, 'svelte-xyz')), - normalizeHtml(window, expected.html) - ); - }); + // ssr + const component = eval(`(function () { ${ssr.code}; return SvelteComponent; }())`); + + assert.equal( + normalizeHtml(window, component.render(config.data).replace(/svelte-\d+/g, 'svelte-xyz')), + normalizeHtml(window, expected.html) + ); } }); }); diff --git a/test/formats/index.js b/test/formats/index.js index 9d62bb712f..b69bde817a 100644 --- a/test/formats/index.js +++ b/test/formats/index.js @@ -3,84 +3,80 @@ import { svelte, deindent, env, setupHtmlEqual } from "../helpers.js"; function testAmd(code, expectedId, dependencies, html) { const fn = new Function("define", code); + const window = env(); - return env().then(window => { - function define(id, deps, factory) { - assert.equal(id, expectedId); - assert.deepEqual(deps, Object.keys(dependencies)); + function define(id, deps, factory) { + assert.equal(id, expectedId); + assert.deepEqual(deps, Object.keys(dependencies)); - const SvelteComponent = factory( - ...Object.keys(dependencies).map(key => dependencies[key]) - ); + const SvelteComponent = factory( + ...Object.keys(dependencies).map(key => dependencies[key]) + ); - const main = window.document.body.querySelector("main"); - const component = new SvelteComponent({ target: main }); + const main = window.document.body.querySelector("main"); + const component = new SvelteComponent({ target: main }); - assert.htmlEqual(main.innerHTML, html); + assert.htmlEqual(main.innerHTML, html); - component.destroy(); - } + component.destroy(); + } - define.amd = true; + define.amd = true; - fn(define); - }); + fn(define); } function testCjs(code, dependencyById, html) { const fn = new Function("module", "exports", "require", code); + const window = env(); - return env().then(window => { - const module = { exports: {} }; - const require = id => { - return dependencyById[id]; - }; + const module = { exports: {} }; + const require = id => { + return dependencyById[id]; + }; - fn(module, module.exports, require); + fn(module, module.exports, require); - const SvelteComponent = module.exports; + const SvelteComponent = module.exports; - const main = window.document.body.querySelector("main"); - const component = new SvelteComponent({ target: main }); + const main = window.document.body.querySelector("main"); + const component = new SvelteComponent({ target: main }); - assert.htmlEqual(main.innerHTML, html); + assert.htmlEqual(main.innerHTML, html); - component.destroy(); - }); + component.destroy(); } function testIife(code, name, globals, html) { const fn = new Function(Object.keys(globals), `${code}\n\nreturn ${name};`); + const window = env(); - return env().then(window => { - const SvelteComponent = fn( - ...Object.keys(globals).map(key => globals[key]) - ); + const SvelteComponent = fn( + ...Object.keys(globals).map(key => globals[key]) + ); - const main = window.document.body.querySelector("main"); - const component = new SvelteComponent({ target: main }); + const main = window.document.body.querySelector("main"); + const component = new SvelteComponent({ target: main }); - assert.htmlEqual(main.innerHTML, html); + assert.htmlEqual(main.innerHTML, html); - component.destroy(); - }); + component.destroy(); } function testEval(code, name, globals, html) { const fn = new Function(Object.keys(globals), `return ${code};`); + const window = env(); - return env().then(window => { - const SvelteComponent = fn( - ...Object.keys(globals).map(key => globals[key]) - ); + const SvelteComponent = fn( + ...Object.keys(globals).map(key => globals[key]) + ); - const main = window.document.body.querySelector("main"); - const component = new SvelteComponent({ target: main }); + const main = window.document.body.querySelector("main"); + const component = new SvelteComponent({ target: main }); - assert.htmlEqual(main.innerHTML, html); + assert.htmlEqual(main.innerHTML, html); - component.destroy(); - }); + component.destroy(); } describe("formats", () => { @@ -190,9 +186,9 @@ describe("formats", () => { } }); - return testAmd(code, "foo", { answer: 42 }, `
42
`) - .then(() => testCjs(code, { answer: 42 }, `
42
`)) - .then(() => testIife(code, "Foo", { answer: 42 }, `
42
`)); + testAmd(code, "foo", { answer: 42 }, `
42
`); + testCjs(code, { answer: 42 }, `
42
`); + testIife(code, "Foo", { answer: 42 }, `
42
`); }); }); diff --git a/test/helpers.js b/test/helpers.js index 0dfa43fa54..f4be292ef4 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -1,16 +1,10 @@ -import jsdom from 'jsdom'; +import { JSDOM } from 'jsdom'; import assert from 'assert'; import glob from 'glob'; import fs from 'fs'; import path from 'path'; import chalk from 'chalk'; -import * as consoleGroup from 'console-group'; -consoleGroup.install(); - -import * as sourceMapSupport from 'source-map-support'; -sourceMapSupport.install(); - // for coverage purposes, we need to test source files, // but for sanity purposes, we need to test dist files export function loadSvelte(test) { @@ -53,17 +47,14 @@ export function tryToReadFile(file) { } } +const { window } = new JSDOM('
'); +global.document = window.document; + export function env() { - return new Promise((fulfil, reject) => { - jsdom.env('
', (err, window) => { - if (err) { - reject(err); - } else { - global.document = window.document; - fulfil(window); - } - }); - }); + window._svelteTransitionManager = null; + window.document.body.innerHTML = '
'; + + return window; } function cleanChildren(node) { @@ -138,22 +129,24 @@ export function normalizeHtml(window, html) { } export function setupHtmlEqual() { - return env().then(window => { - assert.htmlEqual = (actual, expected, message) => { - assert.deepEqual( - normalizeHtml(window, actual), - normalizeHtml(window, expected), - message - ); - }; - }); + const window = env(); + + assert.htmlEqual = (actual, expected, message) => { + assert.deepEqual( + normalizeHtml(window, actual), + normalizeHtml(window, expected), + message + ); + }; } export function loadConfig(file) { try { const resolved = require.resolve(file); delete require.cache[resolved]; - return require(resolved).default; + + const config = require(resolved); + return config.default || config; } catch (err) { if (err.code === 'MODULE_NOT_FOUND') { return {}; diff --git a/test/hydration/index.js b/test/hydration/index.js index 1e291ed6b1..922ff23de8 100644 --- a/test/hydration/index.js +++ b/test/hydration/index.js @@ -17,22 +17,17 @@ function getName(filename) { return base[0].toUpperCase() + base.slice(1); } -const nodeVersionMatch = /^v(\d)/.exec(process.version); -const legacy = +nodeVersionMatch[1] < 6; -const babelrc = require('../../package.json').babel; - describe('hydration', () => { before(() => { const svelte = loadSvelte(); require.extensions['.html'] = function(module, filename) { const options = Object.assign( - { filename, name: getName(filename), hydratable: true }, + { filename, name: getName(filename), hydratable: true, format: 'cjs' }, compileOptions ); - let { code } = svelte.compile(fs.readFileSync(filename, 'utf-8'), options); - if (legacy) code = require('babel-core').transform(code, babelrc).code; + const { code } = svelte.compile(fs.readFileSync(filename, 'utf-8'), options); return module._compile(code, filename); }; @@ -57,45 +52,44 @@ describe('hydration', () => { compileOptions.dev = config.dev; compileOptions.hydrate = true; - return env() - .then(window => { - global.window = window; - - let SvelteComponent; + const window = env(); - try { - SvelteComponent = require(`${cwd}/main.html`).default; - } catch (err) { - throw err; - } + try { + global.window = window; - const target = window.document.body; - target.innerHTML = fs.readFileSync(`${cwd}/_before.html`, 'utf-8'); + let SvelteComponent; - const snapshot = config.snapshot ? config.snapshot(target) : {}; + try { + SvelteComponent = require(`${cwd}/main.html`); + } catch (err) { + throw err; + } - const component = new SvelteComponent({ - target, - hydrate: true, - data: config.data - }); + const target = window.document.body; + target.innerHTML = fs.readFileSync(`${cwd}/_before.html`, 'utf-8'); - assert.htmlEqual(target.innerHTML, fs.readFileSync(`${cwd}/_after.html`, 'utf-8')); + const snapshot = config.snapshot ? config.snapshot(target) : {}; - if (config.test) { - config.test(assert, target, snapshot, component, window); - } else { - component.destroy(); - assert.equal(target.innerHTML, ''); - } - }) - .catch(err => { - showOutput(cwd, { shared: 'svelte/shared.js' }); // eslint-disable-line no-console - throw err; - }) - .then(() => { - if (config.show) showOutput(cwd, { shared: 'svelte/shared.js' }); + const component = new SvelteComponent({ + target, + hydrate: true, + data: config.data }); + + assert.htmlEqual(target.innerHTML, fs.readFileSync(`${cwd}/_after.html`, 'utf-8')); + + if (config.test) { + config.test(assert, target, snapshot, component, window); + } else { + component.destroy(); + assert.equal(target.innerHTML, ''); + } + } catch (err) { + showOutput(cwd, { shared: 'svelte/shared.js' }); // eslint-disable-line no-console + throw err; + } + + if (config.show) showOutput(cwd, { shared: 'svelte/shared.js' }); }); } diff --git a/test/js/index.js b/test/js/index.js index 512cba41fa..d6497b6b75 100644 --- a/test/js/index.js +++ b/test/js/index.js @@ -52,8 +52,9 @@ describe("js", () => { } ] }).then(bundle => { - const actualBundle = bundle.generate({ format: "es" }).code; - fs.writeFileSync(`${dir}/_actual-bundle.js`, actualBundle); + return bundle.generate({ format: "es" }) + }).then(({ code }) => { + fs.writeFileSync(`${dir}/_actual-bundle.js`, code); assert.equal( actual.trim().replace(/^\s+$/gm, ""), @@ -61,7 +62,7 @@ describe("js", () => { ); assert.equal( - actualBundle.trim().replace(/^\s+$/gm, ""), + code.trim().replace(/^\s+$/gm, ""), expectedBundle.trim().replace(/^\s+$/gm, "") ); }); diff --git a/test/js/samples/collapses-text-around-comments/expected-bundle.js b/test/js/samples/collapses-text-around-comments/expected-bundle.js index b290fd4f00..c9fa1ef590 100644 --- a/test/js/samples/collapses-text-around-comments/expected-bundle.js +++ b/test/js/samples/collapses-text-around-comments/expected-bundle.js @@ -201,7 +201,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; if ( !document.getElementById( 'svelte-3590263702-style' ) ) add_css(); this._fragment = create_main_fragment( this._state, this ); @@ -223,6 +223,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); if ( detach !== false ) this._fragment.unmount(); @@ -230,7 +231,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; diff --git a/test/js/samples/collapses-text-around-comments/expected.js b/test/js/samples/collapses-text-around-comments/expected.js index e02f2581d9..a5dc4d5d58 100644 --- a/test/js/samples/collapses-text-around-comments/expected.js +++ b/test/js/samples/collapses-text-around-comments/expected.js @@ -66,7 +66,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; if ( !document.getElementById( 'svelte-3590263702-style' ) ) add_css(); this._fragment = create_main_fragment( this._state, this ); @@ -88,6 +88,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); if ( detach !== false ) this._fragment.unmount(); @@ -95,7 +96,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/computed-collapsed-if/expected-bundle.js b/test/js/samples/computed-collapsed-if/expected-bundle.js index 547cb5e958..35825f465d 100644 --- a/test/js/samples/computed-collapsed-if/expected-bundle.js +++ b/test/js/samples/computed-collapsed-if/expected-bundle.js @@ -155,7 +155,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; this._fragment = create_main_fragment( this._state, this ); @@ -176,6 +176,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); if ( detach !== false ) this._fragment.unmount(); @@ -183,7 +184,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; diff --git a/test/js/samples/computed-collapsed-if/expected.js b/test/js/samples/computed-collapsed-if/expected.js index e16d023bfb..bb2b420c84 100644 --- a/test/js/samples/computed-collapsed-if/expected.js +++ b/test/js/samples/computed-collapsed-if/expected.js @@ -44,7 +44,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; this._fragment = create_main_fragment( this._state, this ); @@ -65,6 +65,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); if ( detach !== false ) this._fragment.unmount(); @@ -72,7 +73,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/css-media-query/expected-bundle.js b/test/js/samples/css-media-query/expected-bundle.js index 831bbd2b23..ebbfffd1ec 100644 --- a/test/js/samples/css-media-query/expected-bundle.js +++ b/test/js/samples/css-media-query/expected-bundle.js @@ -181,7 +181,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; if ( !document.getElementById( 'svelte-2363328337-style' ) ) add_css(); this._fragment = create_main_fragment( this._state, this ); @@ -202,6 +202,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); if ( detach !== false ) this._fragment.unmount(); @@ -209,7 +210,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; diff --git a/test/js/samples/css-media-query/expected.js b/test/js/samples/css-media-query/expected.js index 960b737412..d9af1bfe54 100644 --- a/test/js/samples/css-media-query/expected.js +++ b/test/js/samples/css-media-query/expected.js @@ -50,7 +50,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; if ( !document.getElementById( 'svelte-2363328337-style' ) ) add_css(); this._fragment = create_main_fragment( this._state, this ); @@ -71,6 +71,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); if ( detach !== false ) this._fragment.unmount(); @@ -78,7 +79,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/each-block-changed-check/expected-bundle.js b/test/js/samples/each-block-changed-check/expected-bundle.js index 47d43b2aea..9afe02d871 100644 --- a/test/js/samples/each-block-changed-check/expected-bundle.js +++ b/test/js/samples/each-block-changed-check/expected-bundle.js @@ -301,7 +301,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; this._fragment = create_main_fragment( this._state, this ); @@ -322,6 +322,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); if ( detach !== false ) this._fragment.unmount(); @@ -329,7 +330,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; diff --git a/test/js/samples/each-block-changed-check/expected.js b/test/js/samples/each-block-changed-check/expected.js index 4fa7680a77..6072df4896 100644 --- a/test/js/samples/each-block-changed-check/expected.js +++ b/test/js/samples/each-block-changed-check/expected.js @@ -157,7 +157,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; this._fragment = create_main_fragment( this._state, this ); @@ -178,6 +178,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); if ( detach !== false ) this._fragment.unmount(); @@ -185,7 +186,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/event-handlers-custom/expected-bundle.js b/test/js/samples/event-handlers-custom/expected-bundle.js index c916b10078..fa20cbc9ef 100644 --- a/test/js/samples/event-handlers-custom/expected-bundle.js +++ b/test/js/samples/event-handlers-custom/expected-bundle.js @@ -190,7 +190,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; this._fragment = create_main_fragment( this._state, this ); @@ -210,6 +210,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); if ( detach !== false ) this._fragment.unmount(); @@ -217,7 +218,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; diff --git a/test/js/samples/event-handlers-custom/expected.js b/test/js/samples/event-handlers-custom/expected.js index 882bc08e85..abbfef0f91 100644 --- a/test/js/samples/event-handlers-custom/expected.js +++ b/test/js/samples/event-handlers-custom/expected.js @@ -61,7 +61,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; this._fragment = create_main_fragment( this._state, this ); @@ -81,6 +81,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); if ( detach !== false ) this._fragment.unmount(); @@ -88,7 +89,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/if-block-no-update/expected-bundle.js b/test/js/samples/if-block-no-update/expected-bundle.js index 39ea6622f5..51895c4d5b 100644 --- a/test/js/samples/if-block-no-update/expected-bundle.js +++ b/test/js/samples/if-block-no-update/expected-bundle.js @@ -236,7 +236,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; this._fragment = create_main_fragment( this._state, this ); @@ -257,6 +257,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); if ( detach !== false ) this._fragment.unmount(); @@ -264,7 +265,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; diff --git a/test/js/samples/if-block-no-update/expected.js b/test/js/samples/if-block-no-update/expected.js index fdedd6e4a7..2d8972ad5e 100644 --- a/test/js/samples/if-block-no-update/expected.js +++ b/test/js/samples/if-block-no-update/expected.js @@ -101,7 +101,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; this._fragment = create_main_fragment( this._state, this ); @@ -122,6 +122,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); if ( detach !== false ) this._fragment.unmount(); @@ -129,7 +130,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/if-block-simple/expected-bundle.js b/test/js/samples/if-block-simple/expected-bundle.js index 382c2fd8d3..2ce85c33e6 100644 --- a/test/js/samples/if-block-simple/expected-bundle.js +++ b/test/js/samples/if-block-simple/expected-bundle.js @@ -212,7 +212,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; this._fragment = create_main_fragment( this._state, this ); @@ -233,6 +233,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); if ( detach !== false ) this._fragment.unmount(); @@ -240,7 +241,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; diff --git a/test/js/samples/if-block-simple/expected.js b/test/js/samples/if-block-simple/expected.js index 548938d59c..efd23dc55d 100644 --- a/test/js/samples/if-block-simple/expected.js +++ b/test/js/samples/if-block-simple/expected.js @@ -77,7 +77,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; this._fragment = create_main_fragment( this._state, this ); @@ -98,6 +98,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); if ( detach !== false ) this._fragment.unmount(); @@ -105,7 +106,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/non-imported-component/expected-bundle.js b/test/js/samples/non-imported-component/expected-bundle.js index 91a8b8c292..c37d2f042a 100644 --- a/test/js/samples/non-imported-component/expected-bundle.js +++ b/test/js/samples/non-imported-component/expected-bundle.js @@ -182,7 +182,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; if ( !options._root ) { this._oncreate = []; @@ -216,6 +216,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); if ( detach !== false ) this._fragment.unmount(); @@ -223,7 +224,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; diff --git a/test/js/samples/non-imported-component/expected.js b/test/js/samples/non-imported-component/expected.js index 787e62c54b..195fb2b7b1 100644 --- a/test/js/samples/non-imported-component/expected.js +++ b/test/js/samples/non-imported-component/expected.js @@ -61,7 +61,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; if ( !options._root ) { this._oncreate = []; @@ -95,6 +95,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); if ( detach !== false ) this._fragment.unmount(); @@ -102,7 +103,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/onrender-onteardown-rewritten/expected-bundle.js b/test/js/samples/onrender-onteardown-rewritten/expected-bundle.js index 25fae9ba8c..eb9a6cdd4f 100644 --- a/test/js/samples/onrender-onteardown-rewritten/expected-bundle.js +++ b/test/js/samples/onrender-onteardown-rewritten/expected-bundle.js @@ -146,7 +146,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; var oncreate = template.oncreate.bind( this ); @@ -178,6 +178,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); template.ondestroy.call( this ); @@ -186,7 +187,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; diff --git a/test/js/samples/onrender-onteardown-rewritten/expected.js b/test/js/samples/onrender-onteardown-rewritten/expected.js index 1a1c10f7d6..e35b716595 100644 --- a/test/js/samples/onrender-onteardown-rewritten/expected.js +++ b/test/js/samples/onrender-onteardown-rewritten/expected.js @@ -35,7 +35,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; var oncreate = template.oncreate.bind( this ); @@ -67,6 +67,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); template.ondestroy.call( this ); @@ -75,7 +76,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/use-elements-as-anchors/expected-bundle.js b/test/js/samples/use-elements-as-anchors/expected-bundle.js index 32cd0203c2..b969e80971 100644 --- a/test/js/samples/use-elements-as-anchors/expected-bundle.js +++ b/test/js/samples/use-elements-as-anchors/expected-bundle.js @@ -396,7 +396,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; this._fragment = create_main_fragment( this._state, this ); @@ -417,6 +417,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); if ( detach !== false ) this._fragment.unmount(); @@ -424,7 +425,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; diff --git a/test/js/samples/use-elements-as-anchors/expected.js b/test/js/samples/use-elements-as-anchors/expected.js index 524372861e..046bf7fcbc 100644 --- a/test/js/samples/use-elements-as-anchors/expected.js +++ b/test/js/samples/use-elements-as-anchors/expected.js @@ -261,7 +261,7 @@ function SvelteComponent ( options ) { this._root = options._root || this; this._yield = options._yield; - this._torndown = false; + this._destroyed = false; this._fragment = create_main_fragment( this._state, this ); @@ -282,6 +282,7 @@ SvelteComponent.prototype._set = function _set ( newState ) { }; SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) { + if ( this._destroyed ) return; this.fire( 'destroy' ); if ( detach !== false ) this._fragment.unmount(); @@ -289,7 +290,7 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio this._fragment = null; this._state = {}; - this._torndown = true; + this._destroyed = true; }; export default SvelteComponent; \ No newline at end of file diff --git a/test/runtime/index.js b/test/runtime/index.js index dea60082a3..ce30be761b 100644 --- a/test/runtime/index.js +++ b/test/runtime/index.js @@ -22,10 +22,6 @@ function getName(filename) { return base[0].toUpperCase() + base.slice(1); } -const nodeVersionMatch = /^v(\d)/.exec(process.version); -const legacy = +nodeVersionMatch[1] < 6; -const babelrc = require("../../package.json").babel; - const Object_assign = Object.assign; describe("runtime", () => { @@ -34,12 +30,11 @@ describe("runtime", () => { require.extensions[".html"] = function(module, filename) { const options = Object.assign( - { filename, name: getName(filename) }, + { filename, name: getName(filename), format: 'cjs' }, compileOptions ); - let { code } = svelte.compile(fs.readFileSync(filename, "utf-8"), options); - if (legacy) code = require('babel-core').transform(code, babelrc).code; + const { code } = svelte.compile(fs.readFileSync(filename, "utf-8"), options); return module._compile(code, filename); }; @@ -103,111 +98,110 @@ describe("runtime", () => { let unintendedError = null; - return env() - .then(window => { - // set of hacks to support transition tests - transitionManager.running = false; - transitionManager.transitions = []; - - const raf = { - time: 0, - callback: null, - tick: now => { - raf.time = now; - if (raf.callback) raf.callback(); + const window = env(); + + try { + // set of hacks to support transition tests + transitionManager.running = false; + transitionManager.transitions = []; + + const raf = { + time: 0, + callback: null, + tick: now => { + raf.time = now; + if (raf.callback) raf.callback(); + } + }; + window.performance = { now: () => raf.time }; + global.requestAnimationFrame = cb => { + let called = false; + raf.callback = () => { + if (!called) { + called = true; + cb(); } }; - window.performance = { now: () => raf.time }; - global.requestAnimationFrame = cb => { - let called = false; - raf.callback = () => { - if (!called) { - called = true; - cb(); - } - }; - }; + }; - global.window = window; + global.window = window; - try { - SvelteComponent = require(`./samples/${dir}/main.html`).default; - } catch (err) { - showOutput(cwd, { shared }); // eslint-disable-line no-console - throw err; - } + try { + SvelteComponent = require(`./samples/${dir}/main.html`); + } catch (err) { + showOutput(cwd, { shared }); // eslint-disable-line no-console + throw err; + } - let usedObjectAssign = false; - Object.assign = () => { - usedObjectAssign = true; - }; + let usedObjectAssign = false; + Object.assign = () => { + usedObjectAssign = true; + }; - global.window = window; + global.window = window; - // Put the constructor on window for testing - window.SvelteComponent = SvelteComponent; + // Put the constructor on window for testing + window.SvelteComponent = SvelteComponent; - const target = window.document.querySelector("main"); + const target = window.document.querySelector("main"); - const warnings = []; - const warn = console.warn; - console.warn = warning => { - warnings.push(warning); - }; + const warnings = []; + const warn = console.warn; + console.warn = warning => { + warnings.push(warning); + }; - const component = new SvelteComponent({ - target, - hydrate, - data: config.data - }); + const component = new SvelteComponent({ + target, + hydrate, + data: config.data + }); - Object.assign = Object_assign; + Object.assign = Object_assign; - console.warn = warn; + console.warn = warn; - if (config.error) { - unintendedError = true; - throw new Error("Expected a runtime error"); - } + if (config.error) { + unintendedError = true; + throw new Error("Expected a runtime error"); + } - if (config.warnings) { - assert.deepEqual(warnings, config.warnings); - } else if (warnings.length) { - unintendedError = true; - throw new Error("Received unexpected warnings"); - } + if (config.warnings) { + assert.deepEqual(warnings, config.warnings); + } else if (warnings.length) { + unintendedError = true; + throw new Error("Received unexpected warnings"); + } - if (config.html) { - assert.htmlEqual(target.innerHTML, config.html); - } + if (config.html) { + assert.htmlEqual(target.innerHTML, config.html); + } - if (config.test) { - config.test(assert, component, target, window, raf); - } else { - component.destroy(); - assert.equal(target.innerHTML, ""); - } + if (config.test) { + config.test(assert, component, target, window, raf); + } else { + component.destroy(); + assert.equal(target.innerHTML, ""); + } - if (usedObjectAssign) { - throw new Error( - "cannot use Object.assign in generated code, as it is not supported everywhere" - ); - } - }) - .catch(err => { - Object.assign = Object_assign; - - if (config.error && !unintendedError) { - config.error(assert, err); - } else { - failed.add(dir); - showOutput(cwd, { shared }); // eslint-disable-line no-console - throw err; - } - }) - .then(() => { - if (config.show) showOutput(cwd, { shared }); - }); + if (usedObjectAssign) { + throw new Error( + "cannot use Object.assign in generated code, as it is not supported everywhere" + ); + } + } catch (err) { + Object.assign = Object_assign; + + if (config.error && !unintendedError) { + config.error(assert, err); + } else { + failed.add(dir); + showOutput(cwd, { shared }); // eslint-disable-line no-console + throw err; + } + } + + if (config.show) showOutput(cwd, { shared }); }); } diff --git a/test/runtime/samples/deconflict-builtins/get.js b/test/runtime/samples/deconflict-builtins/get.js index 865e2b1c43..cd846d9be9 100644 --- a/test/runtime/samples/deconflict-builtins/get.js +++ b/test/runtime/samples/deconflict-builtins/get.js @@ -1,3 +1,3 @@ -export default function get () { +export function get () { return 'got'; } \ No newline at end of file diff --git a/test/runtime/samples/deconflict-builtins/main.html b/test/runtime/samples/deconflict-builtins/main.html index eb9de7d15f..db26b1ed70 100644 --- a/test/runtime/samples/deconflict-builtins/main.html +++ b/test/runtime/samples/deconflict-builtins/main.html @@ -1,7 +1,7 @@ {{foo}}