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 b93603be55..950b9a3712 100644
--- a/src/generators/dom/index.ts
+++ b/src/generators/dom/index.ts
@@ -294,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 0d0b0e1b4a..0ce676d6ce 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)
- );
+ fs.writeFileSync(`test/css/samples/${dir}/_actual.html`, html);
- // ssr
- const component = eval(`(function () { ${ssr.code}; return SvelteComponent; }())`);
+ // dom
+ assert.equal(
+ normalizeHtml(window, html).replace(/svelte-\d+/g, 'svelte-xyz'),
+ normalizeHtml(window, expected.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/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}}