pull/4886/head
pushkine 5 years ago
parent 25488772e2
commit c358c498ff

@ -1 +0,0 @@
test/test.js

2437
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -23,9 +23,10 @@
}, },
"types": "types/runtime/index.d.ts", "types": "types/runtime/index.d.ts",
"scripts": { "scripts": {
"test": "mocha --opts mocha.opts", "test": "mocha",
"test:unit": "mocha --require sucrase/register --recursive src/**/__test__.ts", "test:unit": "mocha -r sucrase/register --recursive src/**/__test__.ts",
"quicktest": "mocha --opts mocha.opts", "quicktest": "mocha",
"update-expected": "node -r sucrase/register ./test/js/update.ts && node -r sucrase/register ./test/parser/update.ts",
"precoverage": "c8 mocha --opts mocha.coverage.opts", "precoverage": "c8 mocha --opts mocha.coverage.opts",
"coverage": "c8 report --reporter=text-lcov > coverage.lcov && c8 report --reporter=html", "coverage": "c8 report --reporter=text-lcov > coverage.lcov && c8 report --reporter=html",
"codecov": "codecov", "codecov": "codecov",
@ -39,6 +40,12 @@
"tsd": "tsc -p src/compiler --emitDeclarationOnly && tsc -p src/runtime --emitDeclarationOnly", "tsd": "tsc -p src/compiler --emitDeclarationOnly && tsc -p src/runtime --emitDeclarationOnly",
"lint": "eslint \"{src,test}/**/*.{ts,js}\"" "lint": "eslint \"{src,test}/**/*.{ts,js}\""
}, },
"mocha": {
"file": "./test/test.ts",
"require": "sucrase/register",
"bail": true,
"timeout": "10000"
},
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/sveltejs/svelte.git" "url": "https://github.com/sveltejs/svelte.git"
@ -56,41 +63,42 @@
}, },
"homepage": "https://github.com/sveltejs/svelte#README", "homepage": "https://github.com/sveltejs/svelte#README",
"devDependencies": { "devDependencies": {
"@rollup/plugin-commonjs": "^11.0.0", "@rollup/plugin-commonjs": "^11.1.0",
"@rollup/plugin-json": "^4.0.1", "@rollup/plugin-json": "^4.0.3",
"@rollup/plugin-node-resolve": "^6.0.0", "@rollup/plugin-node-resolve": "^7.1.3",
"@rollup/plugin-replace": "^2.3.0", "@rollup/plugin-replace": "^2.3.2",
"@rollup/plugin-sucrase": "^3.0.0", "@rollup/plugin-sucrase": "^3.0.1",
"@rollup/plugin-typescript": "^2.0.1", "@rollup/plugin-typescript": "^4.1.1",
"@rollup/plugin-virtual": "^2.0.0", "@rollup/plugin-virtual": "^2.0.2",
"@types/mocha": "^5.2.7", "@types/jsdom": "^16.2.2",
"@types/node": "^8.10.53", "@types/mocha": "^7.0.2",
"@types/node": "^14.0.1",
"@types/puppeteer": "^2.1.0",
"@typescript-eslint/eslint-plugin": "^1.13.0", "@typescript-eslint/eslint-plugin": "^1.13.0",
"@typescript-eslint/parser": "^2.1.0", "@typescript-eslint/parser": "^2.1.0",
"acorn": "^7.1.0", "acorn": "^7.2.0",
"agadoo": "^1.1.0", "agadoo": "^2.0.0",
"c8": "^5.0.1", "c8": "^7.1.2",
"code-red": "0.1.1", "code-red": "0.1.1",
"codecov": "^3.5.0", "codecov": "^3.6.5",
"css-tree": "1.0.0-alpha22", "css-tree": "1.0.0-alpha22",
"eslint": "^6.3.0", "eslint": "^6.3.0",
"eslint-plugin-import": "^2.18.2", "eslint-plugin-import": "^2.18.2",
"eslint-plugin-svelte3": "^2.7.3", "eslint-plugin-svelte3": "^2.7.3",
"estree-walker": "^1.0.0", "estree-walker": "^2.0.1",
"is-reference": "^1.1.4", "is-reference": "^1.1.4",
"jsdom": "^15.1.1", "jsdom": "^16.2.2",
"kleur": "^3.0.3", "kleur": "^3.0.3",
"locate-character": "^2.0.5", "locate-character": "^2.0.5",
"magic-string": "^0.25.3", "magic-string": "^0.25.3",
"mocha": "^6.2.0", "mocha": "^7.1.2",
"periscopic": "^2.0.1", "periscopic": "^2.0.1",
"puppeteer": "^1.19.0", "puppeteer": "^3.1.0",
"rollup": "^1.27.14", "rollup": "^2.10.5",
"source-map-support": "^0.5.19",
"source-map": "^0.7.3", "source-map": "^0.7.3",
"source-map-support": "^0.5.13", "tslib": "^2.0.0",
"tiny-glob": "^0.2.6", "typescript": "^3.9.2"
"tslib": "^1.10.0",
"typescript": "^3.5.3"
}, },
"nyc": { "nyc": {
"include": [ "include": [
@ -100,4 +108,5 @@
"sourceMap": true, "sourceMap": true,
"instrument": true "instrument": true
} }
} }

@ -65,7 +65,7 @@ export default [
}), }),
ts_plugin, ts_plugin,
{ {
writeBundle(bundle) { writeBundle(_options, bundle) {
if (dir === 'internal') { if (dir === 'internal') {
const mod = bundle['index.mjs']; const mod = bundle['index.mjs'];
if (mod) { if (mod) {

@ -1,5 +1,7 @@
{ {
"rules": { "rules": {
"no-console": "off" "no-console": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-namespace": "off"
} }
} }

@ -0,0 +1,13 @@
import jsdom from 'jsdom';
export {};
declare global {
namespace NodeJS {
interface Global {
document: Document;
window: jsdom.DOMWindow;
navigator: Navigator;
getComputedStyle: jsdom.DOMWindow['getComputedStyle'];
requestAnimationFrame: any;
}
}
}

@ -1,6 +1,6 @@
import * as assert from 'assert'; import { assert } from '../test';
import * as fs from 'fs'; import { readFileSync, writeFileSync, readdirSync } from 'fs';
import { env, svelte, setupHtmlEqual, shouldUpdateExpected } from '../helpers.js'; import { env, svelte, setupHtmlEqual, shouldUpdateExpected } from '../helpers';
function try_require(file) { function try_require(file) {
try { try {
@ -13,12 +13,12 @@ function try_require(file) {
} }
function normalize_warning(warning) { function normalize_warning(warning) {
warning.frame = warning.frame warning.frame = warning.frame.replace(/^\n/, '').replace(/^\t+/gm, '').replace(/\s+$/gm, '');
.replace(/^\n/, '')
.replace(/^\t+/gm, '')
.replace(/\s+$/gm, '');
delete warning.filename; delete warning.filename;
delete warning.toString; delete warning.toString;
delete warning.start;
delete warning.end;
delete warning.pos;
return warning; return warning;
} }
@ -26,7 +26,7 @@ function create(code) {
const fn = new Function('module', 'exports', 'require', code); const fn = new Function('module', 'exports', 'require', code);
const module = { exports: {} }; const module = { exports: {} };
fn(module, module.exports, id => { fn(module, module.exports, (id) => {
if (id === 'svelte') return require('../../index.js'); if (id === 'svelte') return require('../../index.js');
if (id.startsWith('svelte/')) return require(id.replace('svelte', '../../')); if (id.startsWith('svelte/')) return require(id.replace('svelte', '../../'));
@ -41,7 +41,7 @@ describe('css', () => {
setupHtmlEqual(); setupHtmlEqual();
}); });
fs.readdirSync(`${__dirname}/samples`).forEach(dir => { readdirSync(`${__dirname}/samples`).forEach((dir) => {
if (dir[0] === '.') return; if (dir[0] === '.') return;
// add .solo to a sample directory name to only run that test // add .solo to a sample directory name to only run that test
@ -54,21 +54,13 @@ describe('css', () => {
(solo ? it.only : skip ? it.skip : it)(dir, () => { (solo ? it.only : skip ? it.skip : it)(dir, () => {
const config = try_require(`./samples/${dir}/_config.js`) || {}; const config = try_require(`./samples/${dir}/_config.js`) || {};
const input = fs const input = readFileSync(`${__dirname}/samples/${dir}/input.svelte`, 'utf-8').replace(/\s+$/, '');
.readFileSync(`${__dirname}/samples/${dir}/input.svelte`, 'utf-8')
.replace(/\s+$/, '');
const expected_warnings = (config.warnings || []).map(normalize_warning); const expected_warnings = (config.warnings || []).map(normalize_warning);
const dom = svelte.compile( const dom = svelte.compile(input, Object.assign(config.compileOptions || {}, { format: 'cjs' }));
input,
Object.assign(config.compileOptions || {}, { format: 'cjs' })
);
const ssr = svelte.compile( const ssr = svelte.compile(input, Object.assign(config.compileOptions || {}, { format: 'cjs', generate: 'ssr' }));
input,
Object.assign(config.compileOptions || {}, { format: 'cjs', generate: 'ssr' })
);
assert.equal(dom.css.code, ssr.css.code); assert.equal(dom.css.code, ssr.css.code);
@ -78,18 +70,18 @@ describe('css', () => {
assert.deepEqual(dom_warnings, ssr_warnings); assert.deepEqual(dom_warnings, ssr_warnings);
assert.deepEqual(dom_warnings.map(normalize_warning), expected_warnings); assert.deepEqual(dom_warnings.map(normalize_warning), expected_warnings);
fs.writeFileSync(`${__dirname}/samples/${dir}/_actual.css`, dom.css.code); writeFileSync(`${__dirname}/samples/${dir}/_actual.css`, dom.css.code);
const expected = { const expected = {
html: read(`${__dirname}/samples/${dir}/expected.html`), html: read(`${__dirname}/samples/${dir}/expected.html`),
css: read(`${__dirname}/samples/${dir}/expected.css`) css: read(`${__dirname}/samples/${dir}/expected.css`),
}; };
const actual_css = dom.css.code.replace(/svelte(-ref)?-[a-z0-9]+/g, (m, $1) => $1 ? m : 'svelte-xyz'); const actual_css = dom.css.code.replace(/svelte(-ref)?-[a-z0-9]+/g, (m, $1) => ($1 ? m : 'svelte-xyz'));
try { try {
assert.equal(actual_css, expected.css); assert.equal(actual_css, expected.css);
} catch (error) { } catch (error) {
if (shouldUpdateExpected()) { if (shouldUpdateExpected()) {
fs.writeFileSync(`${__dirname}/samples/${dir}/expected.css`, actual_css); writeFileSync(`${__dirname}/samples/${dir}/expected.css`, actual_css);
console.log(`Updated ${dir}/expected.css.`); console.log(`Updated ${dir}/expected.css.`);
} else { } else {
throw error; throw error;
@ -126,9 +118,9 @@ describe('css', () => {
new ClientComponent({ target, props: config.props }); new ClientComponent({ target, props: config.props });
const html = target.innerHTML; const html = target.innerHTML;
fs.writeFileSync(`${__dirname}/samples/${dir}/_actual.html`, html); writeFileSync(`${__dirname}/samples/${dir}/_actual.html`, html);
const actual_html = html.replace(/svelte(-ref)?-[a-z0-9]+/g, (m, $1) => $1 ? m : 'svelte-xyz'); const actual_html = html.replace(/svelte(-ref)?-[a-z0-9]+/g, (m, $1) => ($1 ? m : 'svelte-xyz'));
assert.htmlEqual(actual_html, expected.html); assert.htmlEqual(actual_html, expected.html);
window.document.head.innerHTML = ''; // remove added styles window.document.head.innerHTML = ''; // remove added styles
@ -139,7 +131,9 @@ describe('css', () => {
// ssr // ssr
try { try {
const actual_ssr = ServerComponent.render(config.props).html.replace(/svelte(-ref)?-[a-z0-9]+/g, (m, $1) => $1 ? m : 'svelte-xyz'); const actual_ssr = ServerComponent.render(config.props).html.replace(/svelte(-ref)?-[a-z0-9]+/g, (m, $1) =>
$1 ? m : 'svelte-xyz'
);
assert.htmlEqual(actual_ssr, expected.html); assert.htmlEqual(actual_ssr, expected.html);
} catch (err) { } catch (err) {
console.log(ssr.js.code); console.log(ssr.js.code);
@ -152,7 +146,7 @@ describe('css', () => {
function read(file) { function read(file) {
try { try {
return fs.readFileSync(file, 'utf-8'); return readFileSync(file, 'utf-8');
} catch (err) { } catch (err) {
return null; return null;
} }

@ -1,10 +1,10 @@
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
import * as http from 'http'; import * as http from 'http';
import { rollup } from 'rollup'; const { rollup } = require('rollup');
import * as virtual from '@rollup/plugin-virtual'; const virtual = require('@rollup/plugin-virtual');
import * as puppeteer from 'puppeteer'; const puppeteer = require('puppeteer');
import { addLineNumbers, loadConfig, loadSvelte } from "../helpers.js"; import { addLineNumbers, loadConfig, loadSvelte } from '../helpers';
import { deepEqual } from 'assert'; import { deepEqual } from 'assert';
const page = ` const page = `
@ -16,7 +16,7 @@ const page = `
const assert = fs.readFileSync(`${__dirname}/assert.js`, 'utf-8'); const assert = fs.readFileSync(`${__dirname}/assert.js`, 'utf-8');
describe('custom-elements', function() { describe('custom-elements', function () {
this.timeout(10000); this.timeout(10000);
let svelte; let svelte;
@ -53,7 +53,7 @@ describe('custom-elements', function() {
await browser.close(); await browser.close();
}); });
fs.readdirSync(`${__dirname}/samples`).forEach(dir => { fs.readdirSync(`${__dirname}/samples`).forEach((dir) => {
if (dir[0] === '.') return; if (dir[0] === '.') return;
const solo = /\.solo$/.test(dir); const solo = /\.solo$/.test(dir);
@ -84,20 +84,19 @@ describe('custom-elements', function() {
if (id.endsWith('.svelte')) { if (id.endsWith('.svelte')) {
const compiled = svelte.compile(code, { const compiled = svelte.compile(code, {
customElement: true, customElement: true,
dev: config.dev dev: config.dev,
}); });
compiled.warnings.forEach(w => warnings.push(w)); compiled.warnings.forEach((w) => warnings.push(w));
return compiled.js; return compiled.js;
} }
}
}, },
},
virtual({ virtual({
assert assert,
}) }),
] ],
}); });
const result = await bundle.generate({ format: 'iife', name: 'test' }); const result = await bundle.generate({ format: 'iife', name: 'test' });
@ -109,7 +108,7 @@ describe('custom-elements', function() {
console[type](...args); console[type](...args);
}); });
page.on('error', error => { page.on('error', (error) => {
console.log('>>> an error happened'); console.log('>>> an error happened');
console.error(error); console.error(error);
}); });
@ -124,13 +123,22 @@ describe('custom-elements', function() {
throw err; throw err;
} finally { } finally {
if (expected_warnings) { if (expected_warnings) {
deepEqual(warnings.map(w => ({ deepEqual(
warnings.map((w) => ({
code: w.code,
message: w.message,
// pos: w.pos,
// start: w.start,
// end: w.end,
})),
expected_warnings.map((w) => ({
code: w.code, code: w.code,
message: w.message, message: w.message,
pos: w.pos, // pos: w.pos,
start: w.start, // start: w.start,
end: w.end // end: w.end,
})), expected_warnings); }))
);
} }
} }
}); });

@ -1,13 +1,13 @@
import * as jsdom from 'jsdom'; import * as jsdom from 'jsdom';
import * as assert from 'assert';
import * as glob from 'tiny-glob/sync.js';
import * as path from 'path'; import * as path from 'path';
import * as fs from 'fs'; import * as fs from 'fs';
import * as colors from 'kleur'; import * as colors from 'kleur';
import { glob } from './tiny-glob';
import { assert } from './test';
// for coverage purposes, we need to test source files, // for coverage purposes, we need to test source files,
// but for sanity purposes, we need to test dist files // but for sanity purposes, we need to test dist files
export function loadSvelte(test) { export function loadSvelte(test?) {
process.env.TEST = test ? 'true' : ''; process.env.TEST = test ? 'true' : '';
const resolved = require.resolve('../compiler.js'); const resolved = require.resolve('../compiler.js');
@ -16,7 +16,7 @@ export function loadSvelte(test) {
return require(resolved); return require(resolved);
} }
export const svelte = loadSvelte(); export const svelte = loadSvelte(false);
export function exists(path) { export function exists(path) {
try { try {
@ -47,14 +47,15 @@ export function tryToReadFile(file) {
export function cleanRequireCache() { export function cleanRequireCache() {
Object.keys(require.cache) Object.keys(require.cache)
.filter(x => x.endsWith('.svelte')) .filter((x) => x.endsWith('.svelte'))
.forEach(file => delete require.cache[file]); .forEach((file) => delete require.cache[file]);
} }
const virtualConsole = new jsdom.VirtualConsole(); const virtualConsole = new jsdom.VirtualConsole();
virtualConsole.sendTo(console); virtualConsole.sendTo(console);
const window = new jsdom.JSDOM('<main></main>', {virtualConsole}).window; const { window } = new jsdom.JSDOM('<main></main>', { virtualConsole });
global.document = window.document; global.document = window.document;
global.navigator = window.navigator; global.navigator = window.navigator;
global.getComputedStyle = window.getComputedStyle; global.getComputedStyle = window.getComputedStyle;
@ -63,11 +64,11 @@ global.window = window;
// add missing ecmascript globals to window // add missing ecmascript globals to window
for (const key of Object.getOwnPropertyNames(global)) { for (const key of Object.getOwnPropertyNames(global)) {
window[key] = window[key] || global[key]; if (!(key in window)) window[key] = global[key];
} }
// implement mock scroll // implement mock scroll
window.scrollTo = function(pageXOffset, pageYOffset) { window.scrollTo = function (pageXOffset, pageYOffset) {
window.pageXOffset = pageXOffset; window.pageXOffset = pageXOffset;
window.pageYOffset = pageYOffset; window.pageYOffset = pageYOffset;
}; };
@ -79,8 +80,8 @@ export function env() {
return window; return window;
} }
const is_TextNode = (n: any): n is Text => n.nodeType === 3;
function cleanChildren(node) { function cleanChildren(node: Element) {
let previous = null; let previous = null;
// sort attributes // sort attributes
@ -88,23 +89,18 @@ function cleanChildren(node) {
return a.name < b.name ? -1 : 1; return a.name < b.name ? -1 : 1;
}); });
attributes.forEach(attr => { attributes.forEach((attr) => {
node.removeAttribute(attr.name); node.removeAttribute(attr.name);
}); });
attributes.forEach(attr => { attributes.forEach((attr) => {
node.setAttribute(attr.name, attr.value); node.setAttribute(attr.name, attr.value);
}); });
// recurse // recurse
[...node.childNodes].forEach(child => { Array.from(node.childNodes).forEach((child) => {
if (child.nodeType === 3) { if (is_TextNode(child)) {
// text if (node.namespaceURI === 'http://www.w3.org/2000/svg' && node.tagName !== 'text' && node.tagName !== 'tspan') {
if (
node.namespaceURI === 'http://www.w3.org/2000/svg' &&
node.tagName !== 'text' &&
node.tagName !== 'tspan'
) {
node.removeChild(child); node.removeChild(child);
} }
@ -118,19 +114,19 @@ function cleanChildren(node) {
child = previous; child = previous;
} }
} else { } else {
cleanChildren(child); cleanChildren(child as Element);
} }
previous = child; previous = child;
}); });
// collapse whitespace // collapse whitespace
if (node.firstChild && node.firstChild.nodeType === 3) { if (node.firstChild && is_TextNode(node.firstChild)) {
node.firstChild.data = node.firstChild.data.replace(/^\s+/, ''); node.firstChild.data = node.firstChild.data.replace(/^\s+/, '');
if (!node.firstChild.data) node.removeChild(node.firstChild); if (!node.firstChild.data) node.removeChild(node.firstChild);
} }
if (node.lastChild && node.lastChild.nodeType === 3) { if (node.lastChild && is_TextNode(node.lastChild)) {
node.lastChild.data = node.lastChild.data.replace(/\s+$/, ''); node.lastChild.data = node.lastChild.data.replace(/\s+$/, '');
if (!node.lastChild.data) node.removeChild(node.lastChild); if (!node.lastChild.data) node.removeChild(node.lastChild);
} }
@ -149,16 +145,11 @@ export function normalizeHtml(window, html) {
throw new Error(`Failed to normalize HTML:\n${html}`); throw new Error(`Failed to normalize HTML:\n${html}`);
} }
} }
export function setupHtmlEqual() { export function setupHtmlEqual() {
const window = env(); const window = env();
assert.htmlEqual = (actual, expected, message) => { assert.htmlEqual = function (actual, expected, message) {
assert.deepEqual( assert.deepEqual(normalizeHtml(window, actual), normalizeHtml(window, expected), message);
normalizeHtml(window, actual),
normalizeHtml(window, expected),
message
);
}; };
} }
@ -184,28 +175,25 @@ export function addLineNumbers(code) {
.map((line, i) => { .map((line, i) => {
i = String(i + 1); i = String(i + 1);
while (i.length < 3) i = ` ${i}`; while (i.length < 3) i = ` ${i}`;
return colors.gray(` ${i}: `) + line.replace(/^\t+/, (match) => match.split('\t').join(' '));
return (
colors.gray(` ${i}: `) +
line.replace(/^\t+/, match => match.split('\t').join(' '))
);
}) })
.join('\n'); .join('\n');
} }
export function showOutput(cwd, options = {}, compile = svelte.compile) { export function showOutput(cwd, options = {}, compile = svelte.compile) {
glob('**/*.svelte', { cwd }).forEach(file => { glob('**/*.svelte', { cwd }).forEach((file) => {
if (file[0] === '_') return; if (file[0] === '_') return;
try { try {
const { js } = compile( const { js } = compile(
fs.readFileSync(`${cwd}/${file}`, 'utf-8'), fs.readFileSync(`${cwd}/${file}`, 'utf-8'),
Object.assign(options, { Object.assign(options, {
filename: file filename: file,
}) })
); );
console.log( // eslint-disable-line no-console console.log(
// eslint-disable-line no-console
`\n>> ${colors.cyan().bold(file)}\n${addLineNumbers(js.code)}\n<< ${colors.cyan().bold(file)}` `\n>> ${colors.cyan().bold(file)}\n${addLineNumbers(js.code)}\n<< ${colors.cyan().bold(file)}`
); );
} catch (err) { } catch (err) {
@ -218,31 +206,25 @@ export function shouldUpdateExpected() {
return process.argv.includes('--update'); return process.argv.includes('--update');
} }
export function spaces(i) {
let result = '';
while (i--) result += ' ';
return result;
}
// fake timers // fake timers
const original_set_timeout = global.setTimeout; const original_set_timeout = global.setTimeout;
export function useFakeTimers() { export function useFakeTimers() {
const callbacks = []; const callbacks = [];
global.setTimeout = function(fn) { global.setTimeout = function (fn) {
callbacks.push(fn); callbacks.push(fn);
}; } as (callback: (...args: any[]) => void, ms: number, ...args: any[]) => any;
return { return {
flush() { flush() {
callbacks.forEach(fn => fn()); callbacks.forEach((fn) => fn());
callbacks.splice(0, callbacks.length); callbacks.splice(0, callbacks.length);
}, },
removeFakeTimers() { removeFakeTimers() {
callbacks.splice(0, callbacks.length); callbacks.splice(0, callbacks.length);
global.setTimeout = original_set_timeout; global.setTimeout = original_set_timeout;
} },
}; };
} }

@ -1,15 +1,8 @@
import * as assert from 'assert';
import * as path from 'path'; import * as path from 'path';
import * as fs from 'fs'; import * as fs from 'fs';
import { import { showOutput, loadConfig, loadSvelte, env, setupHtmlEqual, shouldUpdateExpected } from '../helpers';
showOutput, import { assert } from '../test';
loadConfig,
loadSvelte,
env,
setupHtmlEqual,
shouldUpdateExpected
} from '../helpers.js';
let compileOptions = null; let compileOptions = null;
@ -19,13 +12,13 @@ describe('hydration', () => {
before(() => { before(() => {
const svelte = loadSvelte(); const svelte = loadSvelte();
require.extensions['.svelte'] = function(module, filename) { require.extensions['.svelte'] = function (module, filename) {
const options = Object.assign( const options = Object.assign(
{ {
filename, filename,
hydratable: true, hydratable: true,
format: 'cjs', format: 'cjs',
sveltePath sveltePath,
}, },
compileOptions compileOptions
); );
@ -58,13 +51,11 @@ describe('hydration', () => {
try { try {
global.window = window; global.window = window;
let SvelteComponent; // try {
const SvelteComponent = require(`${cwd}/main.svelte`).default;
try { // } catch (err) {
SvelteComponent = require(`${cwd}/main.svelte`).default; // throw err;
} catch (err) { // }
throw err;
}
const target = window.document.body; const target = window.document.body;
const head = window.document.head; const head = window.document.head;
@ -75,14 +66,16 @@ describe('hydration', () => {
try { try {
before_head = fs.readFileSync(`${cwd}/_before_head.html`, 'utf-8'); before_head = fs.readFileSync(`${cwd}/_before_head.html`, 'utf-8');
head.innerHTML = before_head; head.innerHTML = before_head;
} catch (err) {} } catch (_err) {
//
}
const snapshot = config.snapshot ? config.snapshot(target) : {}; const snapshot = config.snapshot ? config.snapshot(target) : {};
const component = new SvelteComponent({ const component = new SvelteComponent({
target, target,
hydrate: true, hydrate: true,
props: config.props props: config.props,
}); });
try { try {
@ -117,18 +110,19 @@ describe('hydration', () => {
} }
} catch (err) { } catch (err) {
showOutput(cwd, { showOutput(cwd, {
hydratable: true hydratable: true,
}); });
throw err; throw err;
} }
if (config.show) showOutput(cwd, { if (config.show)
hydratable: true showOutput(cwd, {
hydratable: true,
}); });
}); });
} }
fs.readdirSync(`${__dirname}/samples`).forEach(dir => { fs.readdirSync(`${__dirname}/samples`).forEach((dir) => {
runTest(dir, null); runTest(dir, null);
}); });
}); });

@ -1,4 +1,4 @@
<title>Some Title</title> <title>Some Title</title>
<link rel="canonical" href="/" data-svelte="svelte-1s8aodm"> <link rel="canonical" href="/" data-svelte="svelte-1t0pfk9">
<meta name="description" content="some description" data-svelte="svelte-1s8aodm"> <meta name="description" content="some description" data-svelte="svelte-1t0pfk9">
<meta name="keywords" content="some keywords" data-svelte="svelte-1s8aodm"> <meta name="keywords" content="some keywords" data-svelte="svelte-1t0pfk9">

@ -1,72 +0,0 @@
import * as assert from "assert";
import * as fs from "fs";
import * as path from "path";
import * as colors from "kleur";
import { loadConfig, svelte, shouldUpdateExpected } from "../helpers.js";
describe("js", () => {
fs.readdirSync(`${__dirname}/samples`).forEach(dir => {
if (dir[0] === ".") return;
// add .solo to a sample directory name to only run that test
const solo = /\.solo/.test(dir);
if (solo && process.env.CI) {
throw new Error("Forgot to remove `solo: true` from test");
}
const resolved = path.resolve(`${__dirname}/samples`, dir);
if (!fs.existsSync(`${resolved}/input.svelte`)) {
console.log(colors.red().bold(`Missing file ${dir}/input.svelte. If you recently switched branches you may need to delete this directory`));
return;
}
(solo ? it.only : it)(dir, () => {
const config = loadConfig(`${resolved}/_config.js`);
const input = fs.readFileSync(`${resolved}/input.svelte`, "utf-8").replace(/\s+$/, "");
let actual;
try {
const options = Object.assign(config.options || {});
actual = svelte.compile(input, options).js.code.replace(/generated by Svelte v\d+\.\d+\.\d+(-\w+\.\d+)?/, 'generated by Svelte vX.Y.Z');
} catch (err) {
console.log(err.frame);
throw err;
}
const output = `${resolved}/_actual.js`;
fs.writeFileSync(output, actual);
const expectedPath = `${resolved}/expected.js`;
let expected = '';
try {
expected = fs.readFileSync(expectedPath, "utf-8");
} catch (error) {
console.log(error);
if (error.code === 'ENOENT') {
// missing expected.js
fs.writeFileSync(expectedPath, actual);
}
}
try {
assert.equal(
actual.trim().replace(/^[ \t]+$/gm, ""),
expected.trim().replace(/^[ \t]+$/gm, "")
);
} catch (error) {
if (shouldUpdateExpected()) {
fs.writeFileSync(expectedPath, actual);
console.log(`Updated ${expectedPath}.`);
} else {
throw error;
}
}
});
});
});

@ -0,0 +1,78 @@
import * as fs from 'fs';
import * as path from 'path';
import * as colors from 'kleur';
import { loadConfig, svelte, shouldUpdateExpected } from '../helpers';
import { assert } from '../test';
describe('js', () => {
fs.readdirSync(`${__dirname}/samples`).forEach((dir) => {
if (dir[0] === '.') return;
// add .solo to a sample directory name to only run that test
const solo = /\.solo/.test(dir);
const skip = /\.skip$/.test(dir);
if (solo && process.env.CI) {
throw new Error('Forgot to remove `solo: true` from test');
}
const resolved = path.resolve(`${__dirname}/samples`, dir);
if (!fs.existsSync(`${resolved}/input.svelte`)) {
console.log(
colors
.red()
.bold(
`Missing file ${dir}/input.svelte. If you recently switched branches you may need to delete this directory`
)
);
return;
}
(skip ? it.skip : solo ? it.only : it)(dir, () => {
const config = loadConfig(`${resolved}/_config.js`);
const input = fs.readFileSync(`${resolved}/input.svelte`, 'utf-8').replace(/\s+$/, '');
let actual;
try {
const options = Object.assign(config.options || {});
actual = svelte
.compile(input, options)
.js.code.replace(/generated by Svelte v\d+\.\d+\.\d+(-\w+\.\d+)?/, 'generated by Svelte vX.Y.Z');
} catch (err) {
console.log(err.frame);
throw err;
}
const output = `${resolved}/_actual.js`;
fs.writeFileSync(output, actual);
const expectedPath = `${resolved}/expected.js`;
let expected = '';
try {
expected = fs.readFileSync(expectedPath, 'utf-8');
} catch (error) {
console.log(error);
if (error.code === 'ENOENT') {
// missing expected.js
fs.writeFileSync(expectedPath, actual);
}
}
try {
assert.equal(actual.trim().replace(/^[ \t]+$/gm, '').replace(/\r/g, ''), expected.trim().replace(/^[ \t]+$/gm, '').replace(/\r/g, ''));
} catch (error) {
if (shouldUpdateExpected()) {
fs.writeFileSync(expectedPath, actual);
console.log(`Updated ${expectedPath}.`);
} else {
throw error;
}
}
});
});
});

@ -48,7 +48,7 @@ function create_fragment(ctx) {
t8 = text(/*$prop*/ ctx[2]); t8 = text(/*$prop*/ ctx[2]);
t9 = space(); t9 = space();
t10 = text(/*shadowedByModule*/ ctx[4]); t10 = text(/*shadowedByModule*/ ctx[4]);
add_location(p, file, 22, 0, 430); add_location(p, file, 22, 0, 452);
}, },
l: function claim(nodes) { l: function claim(nodes) {
throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");

@ -15,8 +15,8 @@ import {
function add_css() { function add_css() {
var style = element("style"); var style = element("style");
style.id = "svelte-1a7i8ec-style"; style.id = "svelte-1o8xv48-style";
style.textContent = "p.svelte-1a7i8ec{color:red}"; style.textContent = "p.svelte-1o8xv48{color:red}";
append(document.head, style); append(document.head, style);
} }
@ -28,7 +28,7 @@ function create_fragment(ctx) {
c() { c() {
p = element("p"); p = element("p");
t = text(/*foo*/ ctx[0]); t = text(/*foo*/ ctx[0]);
attr(p, "class", "svelte-1a7i8ec"); attr(p, "class", "svelte-1o8xv48");
}, },
m(target, anchor) { m(target, anchor) {
insert(target, p, anchor); insert(target, p, anchor);
@ -58,7 +58,7 @@ function instance($$self, $$props, $$invalidate) {
class Component extends SvelteComponent { class Component extends SvelteComponent {
constructor(options) { constructor(options) {
super(); super();
if (!document.getElementById("svelte-1a7i8ec-style")) add_css(); if (!document.getElementById("svelte-1o8xv48-style")) add_css();
init(this, options, instance, create_fragment, safe_not_equal, { foo: 0 }); init(this, options, instance, create_fragment, safe_not_equal, { foo: 0 });
} }
} }

@ -13,8 +13,8 @@ import {
function add_css() { function add_css() {
var style = element("style"); var style = element("style");
style.id = "svelte-1slhpfn-style"; style.id = "svelte-8exri5-style";
style.textContent = "@media(min-width: 1px){div.svelte-1slhpfn{color:red}}"; style.textContent = "@media(min-width: 1px){div.svelte-8exri5{color:red}}";
append(document.head, style); append(document.head, style);
} }
@ -24,7 +24,7 @@ function create_fragment(ctx) {
return { return {
c() { c() {
div = element("div"); div = element("div");
attr(div, "class", "svelte-1slhpfn"); attr(div, "class", "svelte-8exri5");
}, },
m(target, anchor) { m(target, anchor) {
insert(target, div, anchor); insert(target, div, anchor);
@ -41,7 +41,7 @@ function create_fragment(ctx) {
class Component extends SvelteComponent { class Component extends SvelteComponent {
constructor(options) { constructor(options) {
super(); super();
if (!document.getElementById("svelte-1slhpfn-style")) add_css(); if (!document.getElementById("svelte-8exri5-style")) add_css();
init(this, options, null, create_fragment, safe_not_equal, {}); init(this, options, null, create_fragment, safe_not_equal, {});
} }
} }

@ -33,7 +33,7 @@ function create_fragment(ctx) {
t2 = text("!"); t2 = text("!");
t3 = space(); t3 = space();
debugger; debugger;
add_location(h1, file, 4, 0, 38); add_location(h1, file, 4, 0, 42);
}, },
l: function claim(nodes) { l: function claim(nodes) {
throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");

@ -48,7 +48,7 @@ function create_each_block(ctx) {
debugger; debugger;
} }
add_location(span, file, 8, 1, 116); add_location(span, file, 8, 1, 124);
}, },
m: function mount(target, anchor) { m: function mount(target, anchor) {
insert_dev(target, span, anchor); insert_dev(target, span, anchor);
@ -107,7 +107,7 @@ function create_fragment(ctx) {
p = element("p"); p = element("p");
t1 = text("foo: "); t1 = text("foo: ");
t2 = text(/*foo*/ ctx[1]); t2 = text(/*foo*/ ctx[1]);
add_location(p, file, 12, 0, 182); add_location(p, file, 12, 0, 194);
}, },
l: function claim(nodes) { l: function claim(nodes) {
throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");

@ -45,7 +45,7 @@ function create_each_block(ctx) {
debugger; debugger;
} }
add_location(span, file, 6, 1, 82); add_location(span, file, 6, 1, 88);
}, },
m: function mount(target, anchor) { m: function mount(target, anchor) {
insert_dev(target, span, anchor); insert_dev(target, span, anchor);
@ -101,7 +101,7 @@ function create_fragment(ctx) {
p = element("p"); p = element("p");
t1 = text("foo: "); t1 = text("foo: ");
t2 = text(/*foo*/ ctx[1]); t2 = text(/*foo*/ ctx[1]);
add_location(p, file, 10, 0, 131); add_location(p, file, 10, 0, 141);
}, },
l: function claim(nodes) { l: function claim(nodes) {
throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");

@ -31,7 +31,7 @@ function create_fragment(ctx) {
t0 = text(t0_value); t0 = text(t0_value);
t1 = space(); t1 = space();
t2 = text(/*bar*/ ctx[1]); t2 = text(/*bar*/ ctx[1]);
add_location(p, file, 7, 0, 67); add_location(p, file, 7, 0, 74);
}, },
l: function claim(nodes) { l: function claim(nodes) {
throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");

@ -24,7 +24,7 @@ function create_fragment(ctx) {
const block = { const block = {
c: function create() { c: function create() {
div = element("div"); div = element("div");
add_location(div, file, 22, 0, 288); add_location(div, file, 22, 0, 310);
}, },
l: function claim(nodes) { l: function claim(nodes) {
throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");

@ -1,13 +0,0 @@
// this file will replace all the expected.js files with their _actual
// equivalents. Only use it when you're sure that you haven't
// broken anything!
const fs = require("fs");
const glob = require("tiny-glob/sync.js");
glob("samples/*/_actual.js", { cwd: __dirname }).forEach(file => {
const actual = fs.readFileSync(`${__dirname}/${file}`, "utf-8");
fs.writeFileSync(
`${__dirname}/${file.replace("_actual.js", "expected.js")}`,
actual
);
});

@ -0,0 +1,39 @@
import { readFileSync, writeFileSync } from 'fs';
import { resolve } from 'path';
// this file will replace all the expected.js files with their _actual
// equivalents. Only use it when you're sure that you haven't
// broken anything!
const svelte = (function loadSvelte(test) {
process.env.TEST = test ? 'true' : '';
const resolved = require.resolve('../../compiler.js');
delete require.cache[resolved];
return require(resolved);
})(false);
function loadConfig(file) {
try {
const resolved = require.resolve(file);
delete require.cache[resolved];
const config = require(resolved);
return config.default || config;
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') {
return {};
}
throw err;
}
}
require(resolve(__dirname, '../tiny-glob.ts'))
.glob('samples/*/input.svelte', { cwd: __dirname })
.forEach((file) => {
writeFileSync(
`${__dirname}/${file.replace('input.svelte', 'expected.js')}`,
svelte
.compile(
readFileSync(`${__dirname}/${file}`, 'utf-8').replace(/\s+$/, ''),
loadConfig(`${__dirname}/${file.replace('input.svelte', '_config.js')}`).options
)
.js.code.replace(/generated by Svelte v\d+\.\d+\.\d+(-\w+\.\d+)?/, 'generated by Svelte vX.Y.Z')
);
});

@ -1,4 +1,4 @@
import * as assert from 'assert'; import { assert } from '../test';
import { get } from '../../store'; import { get } from '../../store';
import { spring, tweened } from '../../motion'; import { spring, tweened } from '../../motion';
@ -23,7 +23,7 @@ describe('motion', () => {
it('sets immediately when duration is 0', () => { it('sets immediately when duration is 0', () => {
const size = tweened(0); const size = tweened(0);
size.set(100, { duration : 0 }); size.set(100, { duration: 0 });
assert.equal(get(size), 100); assert.equal(get(size), 100);
}); });
}); });

@ -1,18 +1,16 @@
import * as assert from 'assert';
import * as fs from 'fs'; import * as fs from 'fs';
import { svelte, tryToLoadJson, shouldUpdateExpected } from '../helpers.js'; import { svelte, tryToLoadJson } from '../helpers';
import { assert } from '../test';
describe('parse', () => { describe('parser', () => {
fs.readdirSync(`${__dirname}/samples`).forEach(dir => { fs.readdirSync(`${__dirname}/samples`).forEach((dir) => {
if (dir[0] === '.') return; if (dir[0] === '.') return;
// add .solo to a sample directory name to only run that test // add .solo to a sample directory name to only run that test
const solo = /\.solo$/.test(dir); const solo = /\.solo$/.test(dir);
if (solo && process.env.CI) { if (solo && process.env.CI) {
throw new Error( throw new Error(`Forgot to remove '.solo' from test parser/samples/${dir}`);
`Forgot to remove '.solo' from test parser/samples/${dir}`
);
} }
const skip = !fs.existsSync(`${__dirname}/samples/${dir}/input.svelte`); const skip = !fs.existsSync(`${__dirname}/samples/${dir}/input.svelte`);
@ -25,9 +23,12 @@ describe('parse', () => {
const expectedError = tryToLoadJson(`${__dirname}/samples/${dir}/error.json`); const expectedError = tryToLoadJson(`${__dirname}/samples/${dir}/error.json`);
try { try {
const { ast } = svelte.compile(input, Object.assign(options, { const { ast } = svelte.compile(
generate: false input,
})); Object.assign(options, {
generate: false,
})
);
fs.writeFileSync(`${__dirname}/samples/${dir}/_actual.json`, JSON.stringify(ast, null, '\t')); fs.writeFileSync(`${__dirname}/samples/${dir}/_actual.json`, JSON.stringify(ast, null, '\t'));
@ -36,19 +37,8 @@ describe('parse', () => {
assert.deepEqual(ast.instance, expectedOutput.instance); assert.deepEqual(ast.instance, expectedOutput.instance);
assert.deepEqual(ast.module, expectedOutput.module); assert.deepEqual(ast.module, expectedOutput.module);
} catch (err) { } catch (err) {
if (err.name !== 'ParseError') throw err; if (err.name !== 'ParseError' || !expectedError) throw err;
if (!expectedError) throw err; assert.deepEqual(JSON.parse(JSON.stringify({ ...err, message: err.message })), expectedError);
try {
assert.equal(err.code, expectedError.code);
assert.equal(err.message, expectedError.message);
assert.deepEqual(err.start, expectedError.start);
assert.equal(err.pos, expectedError.pos);
assert.equal(err.toString().split('\n')[0], `${expectedError.message} (${expectedError.start.line}:${expectedError.start.column})`);
} catch (err2) {
const e = err2.code === 'MODULE_NOT_FOUND' ? err : err2;
throw e;
}
} }
}); });
}); });

@ -1,12 +1,12 @@
{ {
"html": { "html": {
"start": 0, "start": 0,
"end": 70, "end": 72,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 0, "start": 0,
"end": 70, "end": 72,
"type": "EachBlock", "type": "EachBlock",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
@ -26,14 +26,14 @@
}, },
"children": [ "children": [
{ {
"start": 33, "start": 34,
"end": 62, "end": 63,
"type": "Element", "type": "Element",
"name": "div", "name": "div",
"attributes": [ "attributes": [
{ {
"start": 38, "start": 39,
"end": 50, "end": 51,
"type": "Animation", "type": "Animation",
"name": "flip", "name": "flip",
"modifiers": [], "modifiers": [],
@ -42,8 +42,8 @@
], ],
"children": [ "children": [
{ {
"start": 51, "start": 52,
"end": 56, "end": 57,
"type": "Text", "type": "Text",
"raw": "flips", "raw": "flips",
"data": "flips" "data": "flips"
@ -52,10 +52,10 @@
} }
], ],
"context": { "context": {
"start": 17,
"end": 22,
"type": "Identifier", "type": "Identifier",
"name": "thing" "name": "thing",
"start": 17,
"end": 22
}, },
"key": { "key": {
"type": "Identifier", "type": "Identifier",

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "duplicate-attribute", "code": "duplicate-attribute",
"message": "Attributes need to be unique",
"start": { "start": {
"line": 1, "line": 1,
"column": 17, "column": 17,
"character": 17 "character": 17
}, },
"pos": 17 "end": {
"line": 1,
"column": 17,
"character": 17
},
"pos": 17,
"frame": "1: <Widget foo={42} bind:foo/>\n ^",
"message": "Attributes need to be unique"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "duplicate-attribute", "code": "duplicate-attribute",
"message": "Attributes need to be unique",
"start": { "start": {
"line": 1, "line": 1,
"column": 17, "column": 17,
"character": 17 "character": 17
}, },
"pos": 17 "end": {
"line": 1,
"column": 17,
"character": 17
},
"pos": 17,
"frame": "1: <div class='foo' class='bar'></div>\n ^",
"message": "Attributes need to be unique"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "duplicate-attribute", "code": "duplicate-attribute",
"message": "Attributes need to be unique",
"start": { "start": {
"line": 1, "line": 1,
"column": 17, "column": 17,
"character": 17 "character": 17
}, },
"pos": 17 "end": {
"line": 1,
"column": 17,
"character": 17
},
"pos": 17,
"frame": "1: <div title='foo' {title}></div>\n ^",
"message": "Attributes need to be unique"
} }

@ -1,12 +1,12 @@
{ {
"html": { "html": {
"start": 0, "start": 0,
"end": 99, "end": 103,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 0, "start": 0,
"end": 99, "end": 103,
"type": "AwaitBlock", "type": "AwaitBlock",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
@ -26,33 +26,33 @@
}, },
"value": null, "value": null,
"error": { "error": {
"start": 47,
"end": 55,
"type": "Identifier", "type": "Identifier",
"name": "theError" "name": "theError",
"start": 49,
"end": 57
}, },
"pending": { "pending": {
"start": 19, "start": 19,
"end": 39, "end": 41,
"type": "PendingBlock", "type": "PendingBlock",
"children": [ "children": [
{ {
"start": 19, "start": 19,
"end": 21, "end": 22,
"type": "Text", "type": "Text",
"raw": "\n\t", "raw": "\r\n\t",
"data": "\n\t" "data": "\r\n\t"
}, },
{ {
"start": 21, "start": 22,
"end": 38, "end": 39,
"type": "Element", "type": "Element",
"name": "p", "name": "p",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 24, "start": 25,
"end": 34, "end": 35,
"type": "Text", "type": "Text",
"raw": "loading...", "raw": "loading...",
"data": "loading..." "data": "loading..."
@ -60,11 +60,11 @@
] ]
}, },
{ {
"start": 38, "start": 39,
"end": 39, "end": 41,
"type": "Text", "type": "Text",
"raw": "\n", "raw": "\r\n",
"data": "\n" "data": "\r\n"
} }
], ],
"skip": false "skip": false
@ -77,39 +77,39 @@
"skip": true "skip": true
}, },
"catch": { "catch": {
"start": 39, "start": 41,
"end": 91, "end": 95,
"type": "CatchBlock", "type": "CatchBlock",
"children": [ "children": [
{ {
"start": 56, "start": 58,
"end": 58, "end": 61,
"type": "Text", "type": "Text",
"raw": "\n\t", "raw": "\r\n\t",
"data": "\n\t" "data": "\r\n\t"
}, },
{ {
"start": 58, "start": 61,
"end": 90, "end": 93,
"type": "Element", "type": "Element",
"name": "p", "name": "p",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 61, "start": 64,
"end": 68, "end": 71,
"type": "Text", "type": "Text",
"raw": "oh no! ", "raw": "oh no! ",
"data": "oh no! " "data": "oh no! "
}, },
{ {
"start": 68, "start": 71,
"end": 86, "end": 89,
"type": "MustacheTag", "type": "MustacheTag",
"expression": { "expression": {
"type": "MemberExpression", "type": "MemberExpression",
"start": 69, "start": 72,
"end": 85, "end": 88,
"loc": { "loc": {
"start": { "start": {
"line": 4, "line": 4,
@ -122,8 +122,8 @@
}, },
"object": { "object": {
"type": "Identifier", "type": "Identifier",
"start": 69, "start": 72,
"end": 77, "end": 80,
"loc": { "loc": {
"start": { "start": {
"line": 4, "line": 4,
@ -138,8 +138,8 @@
}, },
"property": { "property": {
"type": "Identifier", "type": "Identifier",
"start": 78, "start": 81,
"end": 85, "end": 88,
"loc": { "loc": {
"start": { "start": {
"line": 4, "line": 4,
@ -158,11 +158,11 @@
] ]
}, },
{ {
"start": 90, "start": 93,
"end": 91, "end": 95,
"type": "Text", "type": "Text",
"raw": "\n", "raw": "\r\n",
"data": "\n" "data": "\r\n"
} }
], ],
"skip": false "skip": false

@ -1,12 +1,12 @@
{ {
"html": { "html": {
"start": 0, "start": 0,
"end": 148, "end": 154,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 0, "start": 0,
"end": 148, "end": 154,
"type": "AwaitBlock", "type": "AwaitBlock",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
@ -25,39 +25,39 @@
"name": "thePromise" "name": "thePromise"
}, },
"value": { "value": {
"start": 46,
"end": 54,
"type": "Identifier", "type": "Identifier",
"name": "theValue" "name": "theValue",
"start": 48,
"end": 56
}, },
"error": { "error": {
"start": 96,
"end": 104,
"type": "Identifier", "type": "Identifier",
"name": "theError" "name": "theError",
"start": 100,
"end": 108
}, },
"pending": { "pending": {
"start": 19, "start": 19,
"end": 39, "end": 41,
"type": "PendingBlock", "type": "PendingBlock",
"children": [ "children": [
{ {
"start": 19, "start": 19,
"end": 21, "end": 22,
"type": "Text", "type": "Text",
"raw": "\n\t", "raw": "\r\n\t",
"data": "\n\t" "data": "\r\n\t"
}, },
{ {
"start": 21, "start": 22,
"end": 38, "end": 39,
"type": "Element", "type": "Element",
"name": "p", "name": "p",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 24, "start": 25,
"end": 34, "end": 35,
"type": "Text", "type": "Text",
"raw": "loading...", "raw": "loading...",
"data": "loading..." "data": "loading..."
@ -65,49 +65,49 @@
] ]
}, },
{ {
"start": 38, "start": 39,
"end": 39, "end": 41,
"type": "Text", "type": "Text",
"raw": "\n", "raw": "\r\n",
"data": "\n" "data": "\r\n"
} }
], ],
"skip": false "skip": false
}, },
"then": { "then": {
"start": 39, "start": 41,
"end": 88, "end": 92,
"type": "ThenBlock", "type": "ThenBlock",
"children": [ "children": [
{ {
"start": 55, "start": 57,
"end": 57, "end": 60,
"type": "Text", "type": "Text",
"raw": "\n\t", "raw": "\r\n\t",
"data": "\n\t" "data": "\r\n\t"
}, },
{ {
"start": 57, "start": 60,
"end": 87, "end": 90,
"type": "Element", "type": "Element",
"name": "p", "name": "p",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 60, "start": 63,
"end": 73, "end": 76,
"type": "Text", "type": "Text",
"raw": "the value is ", "raw": "the value is ",
"data": "the value is " "data": "the value is "
}, },
{ {
"start": 73, "start": 76,
"end": 83, "end": 86,
"type": "MustacheTag", "type": "MustacheTag",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 74, "start": 77,
"end": 82, "end": 85,
"loc": { "loc": {
"start": { "start": {
"line": 4, "line": 4,
@ -124,49 +124,49 @@
] ]
}, },
{ {
"start": 87, "start": 90,
"end": 88, "end": 92,
"type": "Text", "type": "Text",
"raw": "\n", "raw": "\r\n",
"data": "\n" "data": "\r\n"
} }
], ],
"skip": false "skip": false
}, },
"catch": { "catch": {
"start": 88, "start": 92,
"end": 140, "end": 146,
"type": "CatchBlock", "type": "CatchBlock",
"children": [ "children": [
{ {
"start": 105, "start": 109,
"end": 107, "end": 112,
"type": "Text", "type": "Text",
"raw": "\n\t", "raw": "\r\n\t",
"data": "\n\t" "data": "\r\n\t"
}, },
{ {
"start": 107, "start": 112,
"end": 139, "end": 144,
"type": "Element", "type": "Element",
"name": "p", "name": "p",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 110, "start": 115,
"end": 117, "end": 122,
"type": "Text", "type": "Text",
"raw": "oh no! ", "raw": "oh no! ",
"data": "oh no! " "data": "oh no! "
}, },
{ {
"start": 117, "start": 122,
"end": 135, "end": 140,
"type": "MustacheTag", "type": "MustacheTag",
"expression": { "expression": {
"type": "MemberExpression", "type": "MemberExpression",
"start": 118, "start": 123,
"end": 134, "end": 139,
"loc": { "loc": {
"start": { "start": {
"line": 6, "line": 6,
@ -179,8 +179,8 @@
}, },
"object": { "object": {
"type": "Identifier", "type": "Identifier",
"start": 118, "start": 123,
"end": 126, "end": 131,
"loc": { "loc": {
"start": { "start": {
"line": 6, "line": 6,
@ -195,8 +195,8 @@
}, },
"property": { "property": {
"type": "Identifier", "type": "Identifier",
"start": 127, "start": 132,
"end": 134, "end": 139,
"loc": { "loc": {
"start": { "start": {
"line": 6, "line": 6,
@ -215,11 +215,11 @@
] ]
}, },
{ {
"start": 139, "start": 144,
"end": 140, "end": 146,
"type": "Text", "type": "Text",
"raw": "\n", "raw": "\r\n",
"data": "\n" "data": "\r\n"
} }
], ],
"skip": false "skip": false

@ -1,31 +1,31 @@
{ {
"html": { "html": {
"start": 30, "start": 34,
"end": 48, "end": 52,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 28, "start": 30,
"end": 30, "end": 34,
"type": "Text", "type": "Text",
"raw": "\n\n", "raw": "\r\n\r\n",
"data": "\n\n" "data": "\r\n\r\n"
}, },
{ {
"start": 30, "start": 34,
"end": 48, "end": 52,
"type": "InlineComponent", "type": "InlineComponent",
"name": "Widget", "name": "Widget",
"attributes": [ "attributes": [
{ {
"start": 38, "start": 42,
"end": 46, "end": 50,
"type": "Binding", "type": "Binding",
"name": "foo", "name": "foo",
"modifiers": [], "modifiers": [],
"expression": { "expression": {
"start": 43, "start": 47,
"end": 46, "end": 50,
"type": "Identifier", "type": "Identifier",
"name": "foo" "name": "foo"
} }
@ -38,12 +38,12 @@
"instance": { "instance": {
"type": "Script", "type": "Script",
"start": 0, "start": 0,
"end": 28, "end": 30,
"context": "default", "context": "default",
"content": { "content": {
"type": "Program", "type": "Program",
"start": 8, "start": 8,
"end": 19, "end": 21,
"loc": { "loc": {
"start": { "start": {
"line": 1, "line": 1,
@ -57,8 +57,8 @@
"body": [ "body": [
{ {
"type": "VariableDeclaration", "type": "VariableDeclaration",
"start": 10, "start": 11,
"end": 18, "end": 19,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -72,8 +72,8 @@
"declarations": [ "declarations": [
{ {
"type": "VariableDeclarator", "type": "VariableDeclarator",
"start": 14, "start": 15,
"end": 17, "end": 18,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -86,8 +86,8 @@
}, },
"id": { "id": {
"type": "Identifier", "type": "Identifier",
"start": 14, "start": 15,
"end": 17, "end": 18,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,

@ -1,32 +1,32 @@
{ {
"html": { "html": {
"start": 31, "start": 35,
"end": 56, "end": 60,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 29, "start": 31,
"end": 31, "end": 35,
"type": "Text", "type": "Text",
"raw": "\n\n", "raw": "\r\n\r\n",
"data": "\n\n" "data": "\r\n\r\n"
}, },
{ {
"start": 31, "start": 35,
"end": 56, "end": 60,
"type": "Element", "type": "Element",
"name": "input", "name": "input",
"attributes": [ "attributes": [
{ {
"start": 38, "start": 42,
"end": 55, "end": 59,
"type": "Binding", "type": "Binding",
"name": "value", "name": "value",
"modifiers": [], "modifiers": [],
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 50, "start": 54,
"end": 54, "end": 58,
"loc": { "loc": {
"start": { "start": {
"line": 5, "line": 5,
@ -48,12 +48,12 @@
"instance": { "instance": {
"type": "Script", "type": "Script",
"start": 0, "start": 0,
"end": 29, "end": 31,
"context": "default", "context": "default",
"content": { "content": {
"type": "Program", "type": "Program",
"start": 8, "start": 8,
"end": 20, "end": 22,
"loc": { "loc": {
"start": { "start": {
"line": 1, "line": 1,
@ -67,8 +67,8 @@
"body": [ "body": [
{ {
"type": "VariableDeclaration", "type": "VariableDeclaration",
"start": 10, "start": 11,
"end": 19, "end": 20,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -82,8 +82,8 @@
"declarations": [ "declarations": [
{ {
"type": "VariableDeclarator", "type": "VariableDeclarator",
"start": 14, "start": 15,
"end": 18, "end": 19,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -96,8 +96,8 @@
}, },
"id": { "id": {
"type": "Identifier", "type": "Identifier",
"start": 14, "start": 15,
"end": 18, "end": 19,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,

@ -22,17 +22,17 @@
}, },
{ {
"start": 14, "start": 14,
"end": 16, "end": 18,
"type": "Text", "type": "Text",
"raw": "\n\n", "raw": "\r\n\r\n",
"data": "\n\n" "data": "\r\n\r\n"
} }
] ]
}, },
"css": { "css": {
"type": "Style", "type": "Style",
"start": 16, "start": 18,
"end": 56, "end": 62,
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
@ -46,16 +46,16 @@
{ {
"type": "TypeSelector", "type": "TypeSelector",
"name": "div", "name": "div",
"start": 25, "start": 28,
"end": 28 "end": 31
} }
], ],
"start": 25, "start": 28,
"end": 28 "end": 31
} }
], ],
"start": 25, "start": 28,
"end": 28 "end": 31
}, },
"block": { "block": {
"type": "Block", "type": "Block",
@ -70,28 +70,28 @@
{ {
"type": "Identifier", "type": "Identifier",
"name": "red", "name": "red",
"start": 40, "start": 44,
"end": 43 "end": 47
} }
], ],
"start": 39, "start": 43,
"end": 43 "end": 47
}, },
"start": 33, "start": 37,
"end": 43 "end": 47
} }
], ],
"start": 29, "start": 32,
"end": 47 "end": 52
}, },
"start": 25, "start": 28,
"end": 47 "end": 52
} }
], ],
"content": { "content": {
"start": 23, "start": 25,
"end": 48, "end": 54,
"styles": "\n\tdiv {\n\t\tcolor: red;\n\t}\n" "styles": "\r\n\tdiv {\r\n\t\tcolor: red;\r\n\t}\r\n"
} }
} }
} }

@ -8,12 +8,12 @@
"instance": { "instance": {
"type": "Script", "type": "Script",
"start": 0, "start": 0,
"end": 146, "end": 154,
"context": "default", "context": "default",
"content": { "content": {
"type": "Program", "type": "Program",
"start": 8, "start": 8,
"end": 137, "end": 145,
"loc": { "loc": {
"start": { "start": {
"line": 1, "line": 1,
@ -27,8 +27,8 @@
"body": [ "body": [
{ {
"type": "ImportDeclaration", "type": "ImportDeclaration",
"start": 10, "start": 11,
"end": 43, "end": 44,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -42,8 +42,8 @@
"specifiers": [ "specifiers": [
{ {
"type": "ImportSpecifier", "type": "ImportSpecifier",
"start": 19, "start": 20,
"end": 26, "end": 27,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -56,8 +56,8 @@
}, },
"imported": { "imported": {
"type": "Identifier", "type": "Identifier",
"start": 19, "start": 20,
"end": 26, "end": 27,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -72,8 +72,8 @@
}, },
"local": { "local": {
"type": "Identifier", "type": "Identifier",
"start": 19, "start": 20,
"end": 26, "end": 27,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -90,8 +90,8 @@
], ],
"source": { "source": {
"type": "Literal", "type": "Literal",
"start": 34, "start": 35,
"end": 42, "end": 43,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -108,8 +108,8 @@
}, },
{ {
"type": "ExpressionStatement", "type": "ExpressionStatement",
"start": 46, "start": 49,
"end": 136, "end": 143,
"loc": { "loc": {
"start": { "start": {
"line": 4, "line": 4,
@ -122,8 +122,8 @@
}, },
"expression": { "expression": {
"type": "CallExpression", "type": "CallExpression",
"start": 46, "start": 49,
"end": 135, "end": 142,
"loc": { "loc": {
"start": { "start": {
"line": 4, "line": 4,
@ -136,8 +136,8 @@
}, },
"callee": { "callee": {
"type": "Identifier", "type": "Identifier",
"start": 46, "start": 49,
"end": 53, "end": 56,
"loc": { "loc": {
"start": { "start": {
"line": 4, "line": 4,
@ -153,8 +153,8 @@
"arguments": [ "arguments": [
{ {
"type": "ArrowFunctionExpression", "type": "ArrowFunctionExpression",
"start": 54, "start": 57,
"end": 134, "end": 141,
"loc": { "loc": {
"start": { "start": {
"line": 4, "line": 4,
@ -172,8 +172,8 @@
"params": [], "params": [],
"body": { "body": {
"type": "BlockStatement", "type": "BlockStatement",
"start": 60, "start": 63,
"end": 134, "end": 141,
"loc": { "loc": {
"start": { "start": {
"line": 4, "line": 4,
@ -187,8 +187,8 @@
"body": [ "body": [
{ {
"type": "ExpressionStatement", "type": "ExpressionStatement",
"start": 64, "start": 68,
"end": 131, "end": 137,
"loc": { "loc": {
"start": { "start": {
"line": 5, "line": 5,
@ -201,8 +201,8 @@
}, },
"expression": { "expression": {
"type": "CallExpression", "type": "CallExpression",
"start": 64, "start": 68,
"end": 130, "end": 136,
"loc": { "loc": {
"start": { "start": {
"line": 5, "line": 5,
@ -215,8 +215,8 @@
}, },
"callee": { "callee": {
"type": "MemberExpression", "type": "MemberExpression",
"start": 64, "start": 68,
"end": 87, "end": 91,
"loc": { "loc": {
"start": { "start": {
"line": 5, "line": 5,
@ -229,8 +229,8 @@
}, },
"object": { "object": {
"type": "ImportExpression", "type": "ImportExpression",
"start": 64, "start": 68,
"end": 82, "end": 86,
"loc": { "loc": {
"start": { "start": {
"line": 5, "line": 5,
@ -243,8 +243,8 @@
}, },
"source": { "source": {
"type": "Literal", "type": "Literal",
"start": 71, "start": 75,
"end": 81, "end": 85,
"loc": { "loc": {
"start": { "start": {
"line": 5, "line": 5,
@ -261,8 +261,8 @@
}, },
"property": { "property": {
"type": "Identifier", "type": "Identifier",
"start": 83, "start": 87,
"end": 87, "end": 91,
"loc": { "loc": {
"start": { "start": {
"line": 5, "line": 5,
@ -280,8 +280,8 @@
"arguments": [ "arguments": [
{ {
"type": "ArrowFunctionExpression", "type": "ArrowFunctionExpression",
"start": 88, "start": 92,
"end": 129, "end": 135,
"loc": { "loc": {
"start": { "start": {
"line": 5, "line": 5,
@ -299,8 +299,8 @@
"params": [ "params": [
{ {
"type": "Identifier", "type": "Identifier",
"start": 88, "start": 92,
"end": 91, "end": 95,
"loc": { "loc": {
"start": { "start": {
"line": 5, "line": 5,
@ -316,8 +316,8 @@
], ],
"body": { "body": {
"type": "BlockStatement", "type": "BlockStatement",
"start": 95, "start": 99,
"end": 129, "end": 135,
"loc": { "loc": {
"start": { "start": {
"line": 5, "line": 5,
@ -331,8 +331,8 @@
"body": [ "body": [
{ {
"type": "ExpressionStatement", "type": "ExpressionStatement",
"start": 100, "start": 105,
"end": 125, "end": 130,
"loc": { "loc": {
"start": { "start": {
"line": 6, "line": 6,
@ -345,8 +345,8 @@
}, },
"expression": { "expression": {
"type": "CallExpression", "type": "CallExpression",
"start": 100, "start": 105,
"end": 124, "end": 129,
"loc": { "loc": {
"start": { "start": {
"line": 6, "line": 6,
@ -359,8 +359,8 @@
}, },
"callee": { "callee": {
"type": "MemberExpression", "type": "MemberExpression",
"start": 100, "start": 105,
"end": 111, "end": 116,
"loc": { "loc": {
"start": { "start": {
"line": 6, "line": 6,
@ -373,8 +373,8 @@
}, },
"object": { "object": {
"type": "Identifier", "type": "Identifier",
"start": 100, "start": 105,
"end": 107, "end": 112,
"loc": { "loc": {
"start": { "start": {
"line": 6, "line": 6,
@ -389,8 +389,8 @@
}, },
"property": { "property": {
"type": "Identifier", "type": "Identifier",
"start": 108, "start": 113,
"end": 111, "end": 116,
"loc": { "loc": {
"start": { "start": {
"line": 6, "line": 6,
@ -408,8 +408,8 @@
"arguments": [ "arguments": [
{ {
"type": "MemberExpression", "type": "MemberExpression",
"start": 112, "start": 117,
"end": 123, "end": 128,
"loc": { "loc": {
"start": { "start": {
"line": 6, "line": 6,
@ -422,8 +422,8 @@
}, },
"object": { "object": {
"type": "Identifier", "type": "Identifier",
"start": 112, "start": 117,
"end": 115, "end": 120,
"loc": { "loc": {
"start": { "start": {
"line": 6, "line": 6,
@ -438,8 +438,8 @@
}, },
"property": { "property": {
"type": "Identifier", "type": "Identifier",
"start": 116, "start": 121,
"end": 123, "end": 128,
"loc": { "loc": {
"start": { "start": {
"line": 6, "line": 6,

@ -1,24 +1,24 @@
{ {
"html": { "html": {
"start": 41, "start": 45,
"end": 112, "end": 118,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 39, "start": 41,
"end": 41, "end": 45,
"type": "Text", "type": "Text",
"raw": "\n\n", "raw": "\r\n\r\n",
"data": "\n\n" "data": "\r\n\r\n"
}, },
{ {
"start": 41, "start": 45,
"end": 112, "end": 118,
"type": "EachBlock", "type": "EachBlock",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 48, "start": 52,
"end": 55, "end": 59,
"loc": { "loc": {
"start": { "start": {
"line": 5, "line": 5,
@ -33,20 +33,20 @@
}, },
"children": [ "children": [
{ {
"start": 83, "start": 88,
"end": 104, "end": 109,
"type": "Element", "type": "Element",
"name": "p", "name": "p",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 86, "start": 91,
"end": 91, "end": 96,
"type": "MustacheTag", "type": "MustacheTag",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 87, "start": 92,
"end": 90, "end": 95,
"loc": { "loc": {
"start": { "start": {
"line": 6, "line": 6,
@ -61,20 +61,20 @@
} }
}, },
{ {
"start": 91, "start": 96,
"end": 93, "end": 98,
"type": "Text", "type": "Text",
"raw": ": ", "raw": ": ",
"data": ": " "data": ": "
}, },
{ {
"start": 93, "start": 98,
"end": 100, "end": 105,
"type": "MustacheTag", "type": "MustacheTag",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 94, "start": 99,
"end": 99, "end": 104,
"loc": { "loc": {
"start": { "start": {
"line": 6, "line": 6,
@ -93,8 +93,8 @@
], ],
"context": { "context": {
"type": "ArrayPattern", "type": "ArrayPattern",
"start": 59, "start": 63,
"end": 80, "end": 84,
"loc": { "loc": {
"start": { "start": {
"line": 5, "line": 5,
@ -108,8 +108,8 @@
"elements": [ "elements": [
{ {
"type": "Identifier", "type": "Identifier",
"start": 60, "start": 64,
"end": 63, "end": 67,
"loc": { "loc": {
"start": { "start": {
"line": 5, "line": 5,
@ -124,8 +124,8 @@
}, },
{ {
"type": "Identifier", "type": "Identifier",
"start": 65, "start": 69,
"end": 70, "end": 74,
"loc": { "loc": {
"start": { "start": {
"line": 5, "line": 5,
@ -140,8 +140,8 @@
}, },
{ {
"type": "RestElement", "type": "RestElement",
"start": 72, "start": 76,
"end": 79, "end": 83,
"loc": { "loc": {
"start": { "start": {
"line": 5, "line": 5,
@ -154,8 +154,8 @@
}, },
"argument": { "argument": {
"type": "Identifier", "type": "Identifier",
"start": 75, "start": 79,
"end": 79, "end": 83,
"loc": { "loc": {
"start": { "start": {
"line": 5, "line": 5,
@ -177,12 +177,12 @@
"instance": { "instance": {
"type": "Script", "type": "Script",
"start": 0, "start": 0,
"end": 39, "end": 41,
"context": "default", "context": "default",
"content": { "content": {
"type": "Program", "type": "Program",
"start": 8, "start": 8,
"end": 30, "end": 32,
"loc": { "loc": {
"start": { "start": {
"line": 1, "line": 1,
@ -196,8 +196,8 @@
"body": [ "body": [
{ {
"type": "ExportNamedDeclaration", "type": "ExportNamedDeclaration",
"start": 10, "start": 11,
"end": 29, "end": 30,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -210,8 +210,8 @@
}, },
"declaration": { "declaration": {
"type": "VariableDeclaration", "type": "VariableDeclaration",
"start": 17, "start": 18,
"end": 29, "end": 30,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -225,8 +225,8 @@
"declarations": [ "declarations": [
{ {
"type": "VariableDeclarator", "type": "VariableDeclarator",
"start": 21, "start": 22,
"end": 28, "end": 29,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -239,8 +239,8 @@
}, },
"id": { "id": {
"type": "Identifier", "type": "Identifier",
"start": 21, "start": 22,
"end": 28, "end": 29,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,

@ -1,12 +1,12 @@
{ {
"html": { "html": {
"start": 0, "start": 0,
"end": 77, "end": 81,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 0, "start": 0,
"end": 77, "end": 81,
"type": "EachBlock", "type": "EachBlock",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
@ -26,20 +26,20 @@
}, },
"children": [ "children": [
{ {
"start": 27, "start": 28,
"end": 42, "end": 43,
"type": "Element", "type": "Element",
"name": "p", "name": "p",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 30, "start": 31,
"end": 38, "end": 39,
"type": "MustacheTag", "type": "MustacheTag",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 31, "start": 32,
"end": 37, "end": 38,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -57,26 +57,26 @@
} }
], ],
"context": { "context": {
"start": 18,
"end": 24,
"type": "Identifier", "type": "Identifier",
"name": "animal" "name": "animal",
"start": 18,
"end": 24
}, },
"else": { "else": {
"start": 50, "start": 52,
"end": 70, "end": 74,
"type": "ElseBlock", "type": "ElseBlock",
"children": [ "children": [
{ {
"start": 52, "start": 55,
"end": 69, "end": 72,
"type": "Element", "type": "Element",
"name": "p", "name": "p",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 55, "start": 58,
"end": 65, "end": 68,
"type": "Text", "type": "Text",
"raw": "no animals", "raw": "no animals",
"data": "no animals" "data": "no animals"

@ -1,12 +1,12 @@
{ {
"html": { "html": {
"start": 0, "start": 0,
"end": 58, "end": 60,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 0, "start": 0,
"end": 58, "end": 60,
"type": "EachBlock", "type": "EachBlock",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
@ -26,20 +26,20 @@
}, },
"children": [ "children": [
{ {
"start": 30, "start": 31,
"end": 50, "end": 51,
"type": "Element", "type": "Element",
"name": "p", "name": "p",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 33, "start": 34,
"end": 36, "end": 37,
"type": "MustacheTag", "type": "MustacheTag",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 34, "start": 35,
"end": 35, "end": 36,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -54,20 +54,20 @@
} }
}, },
{ {
"start": 36, "start": 37,
"end": 38, "end": 39,
"type": "Text", "type": "Text",
"raw": ": ", "raw": ": ",
"data": ": " "data": ": "
}, },
{ {
"start": 38, "start": 39,
"end": 46, "end": 47,
"type": "MustacheTag", "type": "MustacheTag",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 39, "start": 40,
"end": 45, "end": 46,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -85,10 +85,10 @@
} }
], ],
"context": { "context": {
"start": 18,
"end": 24,
"type": "Identifier", "type": "Identifier",
"name": "animal" "name": "animal",
"start": 18,
"end": 24
}, },
"index": "i" "index": "i"
} }

@ -1,12 +1,12 @@
{ {
"html": { "html": {
"start": 0, "start": 0,
"end": 54, "end": 56,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 0, "start": 0,
"end": 54, "end": 56,
"type": "EachBlock", "type": "EachBlock",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
@ -26,20 +26,20 @@
}, },
"children": [ "children": [
{ {
"start": 33, "start": 34,
"end": 46, "end": 47,
"type": "Element", "type": "Element",
"name": "p", "name": "p",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 36, "start": 37,
"end": 42, "end": 43,
"type": "MustacheTag", "type": "MustacheTag",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 37, "start": 38,
"end": 41, "end": 42,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -57,10 +57,10 @@
} }
], ],
"context": { "context": {
"start": 16,
"end": 20,
"type": "Identifier", "type": "Identifier",
"name": "todo" "name": "todo",
"start": 16,
"end": 20
}, },
"key": { "key": {
"type": "MemberExpression", "type": "MemberExpression",

@ -1,12 +1,12 @@
{ {
"html": { "html": {
"start": 0, "start": 0,
"end": 50, "end": 52,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 0, "start": 0,
"end": 50, "end": 52,
"type": "EachBlock", "type": "EachBlock",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
@ -26,20 +26,20 @@
}, },
"children": [ "children": [
{ {
"start": 27, "start": 28,
"end": 42, "end": 43,
"type": "Element", "type": "Element",
"name": "p", "name": "p",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 30, "start": 31,
"end": 38, "end": 39,
"type": "MustacheTag", "type": "MustacheTag",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 31, "start": 32,
"end": 37, "end": 38,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -57,10 +57,10 @@
} }
], ],
"context": { "context": {
"start": 18,
"end": 24,
"type": "Identifier", "type": "Identifier",
"name": "animal" "name": "animal",
"start": 18,
"end": 24
} }
} }
] ]

@ -1,6 +1,17 @@
{ {
"name": "ParseError",
"code": "invalid-catch-placement", "code": "invalid-catch-placement",
"message": "Expected to close {#each} block before seeing {:catch} block", "start": {
"start": { "line": 3, "column": 7, "character": 41 }, "line": 3,
"pos": 41 "column": 7,
"character": 43
},
"end": {
"line": 3,
"column": 7,
"character": 43
},
"pos": 43,
"frame": "1: {#await true}\r\n2: {#each foo as bar}\r\n3: {:catch f}\r\n ^\n4: {/await}",
"message": "Expected to close {#each} block before seeing {:catch} block"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "invalid-catch-placement", "code": "invalid-catch-placement",
"message": "Cannot have an {:catch} block outside an {#await ...} block",
"start": { "start": {
"line": 1, "line": 1,
"column": 7, "column": 7,
"character": 7 "character": 7
}, },
"pos": 7 "end": {
"line": 1,
"column": 7,
"character": 7
},
"pos": 7,
"frame": "1: {:catch theValue}\n ^",
"message": "Cannot have an {:catch} block outside an {#await ...} block"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "unexpected-eof", "code": "unexpected-eof",
"message": "comment was left open, expected -->",
"start": { "start": {
"line": 1, "line": 1,
"column": 24, "column": 24,
"character": 24 "character": 24
}, },
"pos": 24 "end": {
"line": 1,
"column": 24,
"character": 24
},
"pos": 24,
"frame": "1: <!-- an unclosed comment\n ^",
"message": "comment was left open, expected -->"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "css-syntax-error", "code": "css-syntax-error",
"message": "LeftCurlyBracket is expected",
"start": { "start": {
"line": 2, "line": 2,
"column": 16, "column": 16,
"character": 24 "character": 25
}, },
"pos": 24 "end": {
"line": 2,
"column": 16,
"character": 25
},
"pos": 25,
"frame": "1: <style>\r\n2: this is not css\r\n ^\n3: </style>",
"message": "LeftCurlyBracket is expected"
} }

@ -1,6 +1,17 @@
{ {
"name": "ParseError",
"code": "invalid-else-placement", "code": "invalid-else-placement",
"message": "Expected to close {#await} block before seeing {:else} block", "start": {
"start": { "line": 3, "column": 6, "character": 29 }, "line": 3,
"pos": 29 "column": 6,
"character": 31
},
"end": {
"line": 3,
"column": 6,
"character": 31
},
"pos": 31,
"frame": "1: {#if true}\r\n2: {#await p}\r\n3: {:else}\r\n ^\n4: {/if}",
"message": "Expected to close {#await} block before seeing {:else} block"
} }

@ -1,6 +1,17 @@
{ {
"name": "ParseError",
"code": "invalid-else-placement", "code": "invalid-else-placement",
"message": "Cannot have an {:else} block outside an {#if ...} or {#each ...} block", "start": {
"start": { "line": 2, "column": 6, "character": 11 }, "line": 2,
"pos": 11 "column": 6,
"character": 12
},
"end": {
"line": 2,
"column": 6,
"character": 12
},
"pos": 12,
"frame": "1: <li>\r\n2: {:else}\n ^",
"message": "Cannot have an {:else} block outside an {#if ...} or {#each ...} block"
} }

@ -1,6 +1,17 @@
{ {
"name": "ParseError",
"code": "invalid-else-placement", "code": "invalid-else-placement",
"message": "Expected to close <li> tag before seeing {:else} block", "start": {
"start": { "line": 3, "column": 6, "character": 23 }, "line": 3,
"pos": 23 "column": 6,
"character": 25
},
"end": {
"line": 3,
"column": 6,
"character": 25
},
"pos": 25,
"frame": "1: {#if true}\r\n2: <li>\r\n3: {:else}\r\n ^\n4: {/if}",
"message": "Expected to close <li> tag before seeing {:else} block"
} }

@ -1,6 +1,17 @@
{ {
"name": "ParseError",
"code": "invalid-elseif-placement", "code": "invalid-elseif-placement",
"message": "Expected to close <p> tag before seeing {:else if ...} block", "start": {
"start": { "line": 3, "column": 9, "character": 25 }, "line": 3,
"pos": 25 "column": 9,
"character": 27
},
"end": {
"line": 3,
"column": 9,
"character": 27
},
"pos": 27,
"frame": "1: {#if true}\r\n2: <p>\r\n3: {:else if false}\r\n ^\n4: {/if}",
"message": "Expected to close <p> tag before seeing {:else if ...} block"
} }

@ -1,6 +1,17 @@
{ {
"name": "ParseError",
"code": "invalid-elseif-placement", "code": "invalid-elseif-placement",
"message": "Expected to close {#await} block before seeing {:else if ...} block", "start": {
"start": { "line": 3, "column": 9, "character": 34 }, "line": 3,
"pos": 34 "column": 9,
"character": 36
},
"end": {
"line": 3,
"column": 9,
"character": 36
},
"pos": 36,
"frame": "1: {#if true}\r\n2: {#await foo}\r\n3: {:else if false}\r\n ^\n4: {/if}",
"message": "Expected to close {#await} block before seeing {:else if ...} block"
} }

@ -1,6 +1,17 @@
{ {
"name": "ParseError",
"code": "invalid-elseif-placement", "code": "invalid-elseif-placement",
"message": "Cannot have an {:else if ...} block outside an {#if ...} block", "start": {
"start": { "line": 3, "column": 10, "character": 35 }, "line": 3,
"pos": 35 "column": 10,
"character": 37
},
"end": {
"line": 3,
"column": 10,
"character": 37
},
"pos": 37,
"frame": "1: {#await foo}\r\n2: {:then bar}\r\n3: {:else if}\r\n ^\n4: {/await}",
"message": "Cannot have an {:else if ...} block outside an {#if ...} block"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "parse-error", "code": "parse-error",
"message": "Assigning to rvalue",
"start": { "start": {
"line": 1, "line": 1,
"column": 1, "column": 1,
"character": 1 "character": 1
}, },
"pos": 1 "end": {
"line": 1,
"column": 1,
"character": 1
},
"pos": 1,
"frame": "1: {42 = nope}\n ^",
"message": "Assigning to rvalue"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "duplicate-style", "code": "duplicate-style",
"message": "You can only have one top-level <style> tag per component",
"start": { "start": {
"line": 9, "line": 9,
"column": 0, "column": 0,
"character": 58 "character": 66
}, },
"pos": 58 "end": {
"line": 9,
"column": 0,
"character": 66
},
"pos": 66,
"frame": " 7: </style>\r\n 8: \r\n 9: <style>\r\n ^\n10: div {\r\n11: color: blue;\r",
"message": "You can only have one top-level <style> tag per component"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "unclosed-script", "code": "unclosed-script",
"message": "<script> must have a closing tag",
"start": { "start": {
"line": 3, "line": 3,
"column": 8, "column": 8,
"character": 32 "character": 34
}, },
"pos": 32 "end": {
"line": 3,
"column": 8,
"character": 34
},
"pos": 34,
"frame": "1: <h1>Hello {name}!</h1>\r\n2: \r\n3: <script>\n ^",
"message": "<script> must have a closing tag"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "invalid-self-placement", "code": "invalid-self-placement",
"message": "<svelte:self> components can only exist inside {#if} blocks, {#each} blocks, or slots passed to components",
"start": { "start": {
"line": 1, "line": 1,
"column": 1, "column": 1,
"character": 1 "character": 1
}, },
"pos": 1 "end": {
"line": 1,
"column": 1,
"character": 1
},
"pos": 1,
"frame": "1: <svelte:self/>\n ^",
"message": "<svelte:self> components can only exist inside {#if} blocks, {#each} blocks, or slots passed to components"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "invalid-tag-name", "code": "invalid-tag-name",
"message": "Valid <svelte:...> tag names are svelte:head, svelte:options, svelte:window, svelte:body, svelte:self or svelte:component",
"pos": 10,
"start": { "start": {
"character": 10,
"line": 2, "line": 2,
"column": 2 "column": 2,
} "character": 11
},
"end": {
"line": 2,
"column": 2,
"character": 11
},
"pos": 11,
"frame": "1: {#if x}\r\n2: <svelte:selfdestructive x=\"{x - 1}\"/>\r\n ^\n3: {/if}",
"message": "Valid <svelte:...> tag names are svelte:head, svelte:options, svelte:window, svelte:body, svelte:self or svelte:component"
} }

@ -1,6 +1,17 @@
{ {
"name": "ParseError",
"code": "invalid-then-placement", "code": "invalid-then-placement",
"message": "Expected to close <li> tag before seeing {:then} block", "start": {
"start": { "line": 3, "column": 6, "character": 26 }, "line": 3,
"pos": 26 "column": 6,
"character": 28
},
"end": {
"line": 3,
"column": 6,
"character": 28
},
"pos": 28,
"frame": "1: {#await true}\r\n2: <li>\r\n3: {:then f}\r\n ^\n4: {/await}",
"message": "Expected to close <li> tag before seeing {:then} block"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "invalid-then-placement", "code": "invalid-then-placement",
"message": "Cannot have an {:then} block outside an {#await ...} block",
"start": { "start": {
"line": 1, "line": 1,
"column": 6, "column": 6,
"character": 6 "character": 6
}, },
"pos": 6 "end": {
"line": 1,
"column": 6,
"character": 6
},
"pos": 6,
"frame": "1: {:then theValue}\n ^",
"message": "Cannot have an {:then} block outside an {#await ...} block"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "unexpected-eof", "code": "unexpected-eof",
"message": "Unexpected end of input",
"start": { "start": {
"line": 1, "line": 1,
"column": 2, "column": 2,
"character": 2 "character": 2
}, },
"pos": 2 "end": {
"line": 1,
"column": 2,
"character": 2
},
"pos": 2,
"frame": "1: <d\n ^",
"message": "Unexpected end of input"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "unexpected-eof", "code": "unexpected-eof",
"message": "Unexpected end of input",
"start": { "start": {
"line": 1, "line": 1,
"column": 1, "column": 1,
"character": 1 "character": 1
}, },
"pos": 1 "end": {
"line": 1,
"column": 1,
"character": 1
},
"pos": 1,
"frame": "1: <\n ^",
"message": "Unexpected end of input"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "unclosed-block", "code": "unclosed-block",
"message": "Block was left open",
"start": { "start": {
"line": 1, "line": 1,
"column": 0, "column": 0,
"character": 0 "character": 0
}, },
"pos": 0 "end": {
"line": 1,
"column": 0,
"character": 0
},
"pos": 0,
"frame": "1: {#if foo}\r\n ^\n2: <p>foo</p>",
"message": "Block was left open"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "unclosed-element", "code": "unclosed-element",
"message": "<div> was left open",
"start": { "start": {
"line": 1, "line": 1,
"column": 0, "column": 0,
"character": 0 "character": 0
}, },
"pos": 0 "end": {
"line": 1,
"column": 0,
"character": 0
},
"pos": 0,
"frame": "1: <div>\n ^",
"message": "<div> was left open"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "invalid-closing-tag", "code": "invalid-closing-tag",
"message": "</div> attempted to close an element that was not open",
"start": { "start": {
"line": 1, "line": 1,
"column": 0, "column": 0,
"character": 0 "character": 0
}, },
"pos": 0 "end": {
"line": 1,
"column": 0,
"character": 0
},
"pos": 0,
"frame": "1: </div>\n ^",
"message": "</div> attempted to close an element that was not open"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "invalid-void-content", "code": "invalid-void-content",
"message": "<input> is a void element and cannot have children, or a closing tag",
"start": { "start": {
"line": 1, "line": 1,
"column": 23, "column": 23,
"character": 23 "character": 23
}, },
"pos": 23 "end": {
"line": 1,
"column": 23,
"character": 23
},
"pos": 23,
"frame": "1: <input>this is illegal!</input>\n ^",
"message": "<input> is a void element and cannot have children, or a closing tag"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "invalid-window-content", "code": "invalid-window-content",
"message": "<svelte:window> cannot have children",
"start": { "start": {
"line": 1, "line": 1,
"column": 15, "column": 15,
"character": 15 "character": 15
}, },
"pos": 15 "end": {
"line": 1,
"column": 15,
"character": 15
},
"pos": 15,
"frame": "1: <svelte:window>contents</svelte:window>\n ^",
"message": "<svelte:window> cannot have children"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "duplicate-window", "code": "duplicate-window",
"message": "A component can only have one <svelte:window> tag",
"start": { "start": {
"line": 2, "line": 2,
"column": 0, "column": 0,
"character": 17 "character": 18
}, },
"pos": 17 "end": {
"line": 2,
"column": 0,
"character": 18
},
"pos": 18,
"frame": "1: <svelte:window/>\r\n2: <svelte:window/>\n ^",
"message": "A component can only have one <svelte:window> tag"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "invalid-window-placement", "code": "invalid-window-placement",
"message": "<svelte:window> tags cannot be inside elements or blocks",
"start": { "start": {
"line": 2, "line": 2,
"column": 1, "column": 1,
"character": 11 "character": 12
}, },
"pos": 11 "end": {
"line": 2,
"column": 1,
"character": 12
},
"pos": 12,
"frame": "1: {#if foo}\r\n2: <svelte:window/>\r\n ^\n3: {/if}",
"message": "<svelte:window> tags cannot be inside elements or blocks"
} }

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "invalid-window-placement", "code": "invalid-window-placement",
"message": "<svelte:window> tags cannot be inside elements or blocks",
"start": { "start": {
"line": 2, "line": 2,
"column": 1, "column": 1,
"character": 7 "character": 8
}, },
"pos": 7 "end": {
"line": 2,
"column": 1,
"character": 8
},
"pos": 8,
"frame": "1: <div>\r\n2: <svelte:window/>\r\n ^\n3: </div>",
"message": "<svelte:window> tags cannot be inside elements or blocks"
} }

@ -1,7 +1,7 @@
{ {
"html": { "html": {
"start": 0, "start": 0,
"end": 97, "end": 101,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
@ -115,19 +115,19 @@
}, },
{ {
"start": 61, "start": 61,
"end": 63, "end": 65,
"type": "Text", "type": "Text",
"raw": "\n\n", "raw": "\r\n\r\n",
"data": "\n\n" "data": "\r\n\r\n"
}, },
{ {
"start": 63, "start": 65,
"end": 97, "end": 101,
"type": "IfBlock", "type": "IfBlock",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 68, "start": 70,
"end": 75, "end": 77,
"loc": { "loc": {
"start": { "start": {
"line": 3, "line": 3,
@ -142,15 +142,15 @@
}, },
"children": [ "children": [
{ {
"start": 78, "start": 81,
"end": 91, "end": 94,
"type": "Element", "type": "Element",
"name": "p", "name": "p",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 81, "start": 84,
"end": 87, "end": 90,
"type": "Text", "type": "Text",
"raw": "hello!", "raw": "hello!",
"data": "hello!" "data": "hello!"

@ -1,12 +1,12 @@
{ {
"html": { "html": {
"start": 0, "start": 0,
"end": 51, "end": 55,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 0, "start": 0,
"end": 51, "end": 55,
"type": "IfBlock", "type": "IfBlock",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
@ -26,15 +26,15 @@
}, },
"children": [ "children": [
{ {
"start": 11, "start": 12,
"end": 21, "end": 22,
"type": "Element", "type": "Element",
"name": "p", "name": "p",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 14, "start": 15,
"end": 17, "end": 18,
"type": "Text", "type": "Text",
"raw": "foo", "raw": "foo",
"data": "foo" "data": "foo"
@ -43,20 +43,20 @@
} }
], ],
"else": { "else": {
"start": 29, "start": 31,
"end": 46, "end": 50,
"type": "ElseBlock", "type": "ElseBlock",
"children": [ "children": [
{ {
"start": 31, "start": 34,
"end": 45, "end": 48,
"type": "Element", "type": "Element",
"name": "p", "name": "p",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 34, "start": 37,
"end": 41, "end": 44,
"type": "Text", "type": "Text",
"raw": "not foo", "raw": "not foo",
"data": "not foo" "data": "not foo"

@ -1,12 +1,12 @@
{ {
"html": { "html": {
"start": 0, "start": 0,
"end": 89, "end": 93,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 0, "start": 0,
"end": 89, "end": 93,
"type": "IfBlock", "type": "IfBlock",
"expression": { "expression": {
"type": "BinaryExpression", "type": "BinaryExpression",
@ -59,15 +59,15 @@
}, },
"children": [ "children": [
{ {
"start": 14, "start": 15,
"end": 41, "end": 42,
"type": "Element", "type": "Element",
"name": "p", "name": "p",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 17, "start": 18,
"end": 37, "end": 38,
"type": "Text", "type": "Text",
"raw": "x is greater than 10", "raw": "x is greater than 10",
"data": "x is greater than 10" "data": "x is greater than 10"
@ -76,19 +76,19 @@
} }
], ],
"else": { "else": {
"start": 58, "start": 60,
"end": 84, "end": 88,
"type": "ElseBlock", "type": "ElseBlock",
"children": [ "children": [
{ {
"start": 58, "start": 60,
"end": 89, "end": 93,
"type": "IfBlock", "type": "IfBlock",
"elseif": true, "elseif": true,
"expression": { "expression": {
"type": "BinaryExpression", "type": "BinaryExpression",
"start": 52, "start": 54,
"end": 57, "end": 59,
"loc": { "loc": {
"start": { "start": {
"line": 3, "line": 3,
@ -101,8 +101,8 @@
}, },
"left": { "left": {
"type": "Identifier", "type": "Identifier",
"start": 52, "start": 54,
"end": 53, "end": 55,
"loc": { "loc": {
"start": { "start": {
"line": 3, "line": 3,
@ -118,8 +118,8 @@
"operator": "<", "operator": "<",
"right": { "right": {
"type": "Literal", "type": "Literal",
"start": 56, "start": 58,
"end": 57, "end": 59,
"loc": { "loc": {
"start": { "start": {
"line": 3, "line": 3,
@ -136,15 +136,15 @@
}, },
"children": [ "children": [
{ {
"start": 60, "start": 63,
"end": 83, "end": 86,
"type": "Element", "type": "Element",
"name": "p", "name": "p",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 63, "start": 66,
"end": 79, "end": 82,
"type": "Text", "type": "Text",
"raw": "x is less than 5", "raw": "x is less than 5",
"data": "x is less than 5" "data": "x is less than 5"

@ -1,45 +1,45 @@
{ {
"html": { "html": {
"start": 0, "start": 0,
"end": 51, "end": 57,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 0, "start": 0,
"end": 51, "end": 57,
"type": "Element", "type": "Element",
"name": "ul", "name": "ul",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 4, "start": 4,
"end": 6, "end": 7,
"type": "Text", "type": "Text",
"raw": "\n\t", "raw": "\r\n\t",
"data": "\n\t" "data": "\r\n\t"
}, },
{ {
"start": 6, "start": 7,
"end": 40, "end": 45,
"type": "Element", "type": "Element",
"name": "li", "name": "li",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 10, "start": 11,
"end": 13, "end": 15,
"type": "Text", "type": "Text",
"raw": "a\n\t", "raw": "a\r\n\t",
"data": "a\n\t" "data": "a\r\n\t"
}, },
{ {
"start": 13, "start": 15,
"end": 38, "end": 42,
"type": "IfBlock", "type": "IfBlock",
"expression": { "expression": {
"type": "Literal", "type": "Literal",
"start": 18, "start": 20,
"end": 22, "end": 24,
"loc": { "loc": {
"start": { "start": {
"line": 3, "line": 3,
@ -55,45 +55,45 @@
}, },
"children": [ "children": [
{ {
"start": 26, "start": 29,
"end": 33, "end": 37,
"type": "Element", "type": "Element",
"name": "li", "name": "li",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 30, "start": 33,
"end": 33, "end": 37,
"type": "Text", "type": "Text",
"raw": "b\n\t", "raw": "b\r\n\t",
"data": "b\n\t" "data": "b\r\n\t"
} }
] ]
} }
] ]
}, },
{ {
"start": 38, "start": 42,
"end": 40, "end": 45,
"type": "Text", "type": "Text",
"raw": "\n\t", "raw": "\r\n\t",
"data": "\n\t" "data": "\r\n\t"
} }
] ]
}, },
{ {
"start": 40, "start": 45,
"end": 46, "end": 52,
"type": "Element", "type": "Element",
"name": "li", "name": "li",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 44, "start": 49,
"end": 46, "end": 52,
"type": "Text", "type": "Text",
"raw": "c\n", "raw": "c\r\n",
"data": "c\n" "data": "c\r\n"
} }
] ]
} }

@ -1,68 +1,68 @@
{ {
"html": { "html": {
"start": 0, "start": 0,
"end": 31, "end": 35,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 0, "start": 0,
"end": 31, "end": 35,
"type": "Element", "type": "Element",
"name": "ul", "name": "ul",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 4, "start": 4,
"end": 6, "end": 7,
"type": "Text", "type": "Text",
"raw": "\n\t", "raw": "\r\n\t",
"data": "\n\t" "data": "\r\n\t"
}, },
{ {
"start": 6, "start": 7,
"end": 13, "end": 15,
"type": "Element", "type": "Element",
"name": "li", "name": "li",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 10, "start": 11,
"end": 13, "end": 15,
"type": "Text", "type": "Text",
"raw": "a\n\t", "raw": "a\r\n\t",
"data": "a\n\t" "data": "a\r\n\t"
} }
] ]
}, },
{ {
"start": 13, "start": 15,
"end": 20, "end": 23,
"type": "Element", "type": "Element",
"name": "li", "name": "li",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 17, "start": 19,
"end": 20, "end": 23,
"type": "Text", "type": "Text",
"raw": "b\n\t", "raw": "b\r\n\t",
"data": "b\n\t" "data": "b\r\n\t"
} }
] ]
}, },
{ {
"start": 20, "start": 23,
"end": 26, "end": 30,
"type": "Element", "type": "Element",
"name": "li", "name": "li",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 24, "start": 27,
"end": 26, "end": 30,
"type": "Text", "type": "Text",
"raw": "c\n", "raw": "c\r\n",
"data": "c\n" "data": "c\r\n"
} }
] ]
} }

@ -1,12 +1,12 @@
{ {
"html": { "html": {
"start": 0, "start": 0,
"end": 148, "end": 166,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 0, "start": 0,
"end": 33, "end": 36,
"type": "IfBlock", "type": "IfBlock",
"expression": { "expression": {
"type": "Literal", "type": "Literal",
@ -27,8 +27,8 @@
}, },
"children": [ "children": [
{ {
"start": 12, "start": 13,
"end": 19, "end": 20,
"type": "Element", "type": "Element",
"name": "input", "name": "input",
"attributes": [], "attributes": [],
@ -36,27 +36,27 @@
} }
], ],
"else": { "else": {
"start": 27, "start": 29,
"end": 28, "end": 31,
"type": "ElseBlock", "type": "ElseBlock",
"children": [] "children": []
} }
}, },
{ {
"start": 33, "start": 36,
"end": 35, "end": 40,
"type": "Text", "type": "Text",
"raw": "\n\n", "raw": "\r\n\r\n",
"data": "\n\n" "data": "\r\n\r\n"
}, },
{ {
"start": 35, "start": 40,
"end": 65, "end": 73,
"type": "IfBlock", "type": "IfBlock",
"expression": { "expression": {
"type": "Literal", "type": "Literal",
"start": 40, "start": 45,
"end": 44, "end": 49,
"loc": { "loc": {
"start": { "start": {
"line": 6, "line": 6,
@ -72,8 +72,8 @@
}, },
"children": [ "children": [
{ {
"start": 47, "start": 53,
"end": 51, "end": 57,
"type": "Element", "type": "Element",
"name": "br", "name": "br",
"attributes": [], "attributes": [],
@ -81,27 +81,27 @@
} }
], ],
"else": { "else": {
"start": 59, "start": 66,
"end": 60, "end": 68,
"type": "ElseBlock", "type": "ElseBlock",
"children": [] "children": []
} }
}, },
{ {
"start": 65, "start": 73,
"end": 67, "end": 77,
"type": "Text", "type": "Text",
"raw": "\n\n", "raw": "\r\n\r\n",
"data": "\n\n" "data": "\r\n\r\n"
}, },
{ {
"start": 67, "start": 77,
"end": 108, "end": 121,
"type": "AwaitBlock", "type": "AwaitBlock",
"expression": { "expression": {
"type": "Literal", "type": "Literal",
"start": 75, "start": 85,
"end": 79, "end": 89,
"loc": { "loc": {
"start": { "start": {
"line": 11, "line": 11,
@ -116,53 +116,53 @@
"raw": "true" "raw": "true"
}, },
"value": { "value": {
"start": 97,
"end": 98,
"type": "Identifier", "type": "Identifier",
"name": "f" "name": "f",
"start": 109,
"end": 110
}, },
"error": null, "error": null,
"pending": { "pending": {
"start": 80, "start": 90,
"end": 90, "end": 102,
"type": "PendingBlock", "type": "PendingBlock",
"children": [ "children": [
{ {
"start": 80, "start": 90,
"end": 82, "end": 93,
"type": "Text", "type": "Text",
"raw": "\n\t", "raw": "\r\n\t",
"data": "\n\t" "data": "\r\n\t"
}, },
{ {
"start": 82, "start": 93,
"end": 89, "end": 100,
"type": "Element", "type": "Element",
"name": "input", "name": "input",
"attributes": [], "attributes": [],
"children": [] "children": []
}, },
{ {
"start": 89, "start": 100,
"end": 90, "end": 102,
"type": "Text", "type": "Text",
"raw": "\n", "raw": "\r\n",
"data": "\n" "data": "\r\n"
} }
], ],
"skip": false "skip": false
}, },
"then": { "then": {
"start": 90, "start": 102,
"end": 100, "end": 113,
"type": "ThenBlock", "type": "ThenBlock",
"children": [ "children": [
{ {
"start": 99, "start": 111,
"end": 100, "end": 113,
"type": "Text", "type": "Text",
"raw": "\n", "raw": "\r\n",
"data": "\n" "data": "\r\n"
} }
], ],
"skip": false "skip": false
@ -176,20 +176,20 @@
} }
}, },
{ {
"start": 108, "start": 121,
"end": 110, "end": 125,
"type": "Text", "type": "Text",
"raw": "\n\n", "raw": "\r\n\r\n",
"data": "\n\n" "data": "\r\n\r\n"
}, },
{ {
"start": 110, "start": 125,
"end": 148, "end": 166,
"type": "AwaitBlock", "type": "AwaitBlock",
"expression": { "expression": {
"type": "Literal", "type": "Literal",
"start": 118, "start": 133,
"end": 122, "end": 137,
"loc": { "loc": {
"start": { "start": {
"line": 16, "line": 16,
@ -204,53 +204,53 @@
"raw": "true" "raw": "true"
}, },
"value": { "value": {
"start": 137,
"end": 138,
"type": "Identifier", "type": "Identifier",
"name": "f" "name": "f",
"start": 154,
"end": 155
}, },
"error": null, "error": null,
"pending": { "pending": {
"start": 123, "start": 138,
"end": 130, "end": 147,
"type": "PendingBlock", "type": "PendingBlock",
"children": [ "children": [
{ {
"start": 123, "start": 138,
"end": 125, "end": 141,
"type": "Text", "type": "Text",
"raw": "\n\t", "raw": "\r\n\t",
"data": "\n\t" "data": "\r\n\t"
}, },
{ {
"start": 125, "start": 141,
"end": 129, "end": 145,
"type": "Element", "type": "Element",
"name": "br", "name": "br",
"attributes": [], "attributes": [],
"children": [] "children": []
}, },
{ {
"start": 129, "start": 145,
"end": 130, "end": 147,
"type": "Text", "type": "Text",
"raw": "\n", "raw": "\r\n",
"data": "\n" "data": "\r\n"
} }
], ],
"skip": false "skip": false
}, },
"then": { "then": {
"start": 130, "start": 147,
"end": 140, "end": 158,
"type": "ThenBlock", "type": "ThenBlock",
"children": [ "children": [
{ {
"start": 139, "start": 156,
"end": 140, "end": 158,
"type": "Text", "type": "Text",
"raw": "\n", "raw": "\r\n",
"data": "\n" "data": "\r\n"
} }
], ],
"skip": false "skip": false

@ -1,10 +1,17 @@
{ {
"name": "ParseError",
"code": "missing-whitespace", "code": "missing-whitespace",
"message": "Expected whitespace",
"start": { "start": {
"line": 1, "line": 1,
"column": 6, "column": 6,
"character": 6 "character": 6
}, },
"pos": 6 "end": {
"line": 1,
"column": 6,
"character": 6
},
"pos": 6,
"frame": "1: {@htmlfoo}\n ^",
"message": "Expected whitespace"
} }

@ -1,32 +1,32 @@
{ {
"html": { "html": {
"start": 30, "start": 34,
"end": 63, "end": 67,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 28, "start": 30,
"end": 30, "end": 34,
"type": "Text", "type": "Text",
"raw": "\n\n", "raw": "\r\n\r\n",
"data": "\n\n" "data": "\r\n\r\n"
}, },
{ {
"start": 30, "start": 34,
"end": 63, "end": 67,
"type": "Element", "type": "Element",
"name": "canvas", "name": "canvas",
"attributes": [ "attributes": [
{ {
"start": 38, "start": 42,
"end": 53, "end": 57,
"type": "Binding", "type": "Binding",
"name": "this", "name": "this",
"modifiers": [], "modifiers": [],
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 49, "start": 53,
"end": 52, "end": 56,
"loc": { "loc": {
"start": { "start": {
"line": 5, "line": 5,
@ -48,12 +48,12 @@
"instance": { "instance": {
"type": "Script", "type": "Script",
"start": 0, "start": 0,
"end": 28, "end": 30,
"context": "default", "context": "default",
"content": { "content": {
"type": "Program", "type": "Program",
"start": 8, "start": 8,
"end": 19, "end": 21,
"loc": { "loc": {
"start": { "start": {
"line": 1, "line": 1,
@ -67,8 +67,8 @@
"body": [ "body": [
{ {
"type": "VariableDeclaration", "type": "VariableDeclaration",
"start": 10, "start": 11,
"end": 18, "end": 19,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -82,8 +82,8 @@
"declarations": [ "declarations": [
{ {
"type": "VariableDeclarator", "type": "VariableDeclarator",
"start": 14, "start": 15,
"end": 17, "end": 18,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -96,8 +96,8 @@
}, },
"id": { "id": {
"type": "Identifier", "type": "Identifier",
"start": 14, "start": 15,
"end": 17, "end": 18,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,

@ -1,19 +1,19 @@
{ {
"html": { "html": {
"start": 45, "start": 49,
"end": 56, "end": 60,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 43, "start": 45,
"end": 45, "end": 49,
"type": "Text", "type": "Text",
"raw": "\n\n", "raw": "\r\n\r\n",
"data": "\n\n" "data": "\r\n\r\n"
}, },
{ {
"start": 45, "start": 49,
"end": 56, "end": 60,
"type": "Element", "type": "Element",
"name": "div", "name": "div",
"attributes": [], "attributes": [],
@ -24,12 +24,12 @@
"instance": { "instance": {
"type": "Script", "type": "Script",
"start": 0, "start": 0,
"end": 43, "end": 45,
"context": "default", "context": "default",
"content": { "content": {
"type": "Program", "type": "Program",
"start": 8, "start": 8,
"end": 34, "end": 36,
"loc": { "loc": {
"start": { "start": {
"line": 1, "line": 1,
@ -46,8 +46,8 @@
{ {
"type": "Line", "type": "Line",
"value": " TODO write some code", "value": " TODO write some code",
"start": 10, "start": 11,
"end": 33 "end": 34
} }
] ]
} }

@ -1,38 +1,38 @@
{ {
"html": { "html": {
"start": 79, "start": 87,
"end": 101, "end": 109,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 77, "start": 83,
"end": 79, "end": 87,
"type": "Text", "type": "Text",
"raw": "\n\n", "raw": "\r\n\r\n",
"data": "\n\n" "data": "\r\n\r\n"
}, },
{ {
"start": 79, "start": 87,
"end": 101, "end": 109,
"type": "Element", "type": "Element",
"name": "h1", "name": "h1",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 83, "start": 91,
"end": 89, "end": 97,
"type": "Text", "type": "Text",
"raw": "Hello ", "raw": "Hello ",
"data": "Hello " "data": "Hello "
}, },
{ {
"start": 89, "start": 97,
"end": 95, "end": 103,
"type": "MustacheTag", "type": "MustacheTag",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 90, "start": 98,
"end": 94, "end": 102,
"loc": { "loc": {
"start": { "start": {
"line": 9, "line": 9,
@ -47,8 +47,8 @@
} }
}, },
{ {
"start": 95, "start": 103,
"end": 96, "end": 104,
"type": "Text", "type": "Text",
"raw": "!", "raw": "!",
"data": "!" "data": "!"
@ -60,12 +60,12 @@
"instance": { "instance": {
"type": "Script", "type": "Script",
"start": 0, "start": 0,
"end": 77, "end": 83,
"context": "default", "context": "default",
"content": { "content": {
"type": "Program", "type": "Program",
"start": 8, "start": 8,
"end": 68, "end": 74,
"loc": { "loc": {
"start": { "start": {
"line": 1, "line": 1,
@ -79,8 +79,8 @@
"body": [ "body": [
{ {
"type": "VariableDeclaration", "type": "VariableDeclaration",
"start": 10, "start": 11,
"end": 29, "end": 30,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -94,8 +94,8 @@
"declarations": [ "declarations": [
{ {
"type": "VariableDeclarator", "type": "VariableDeclarator",
"start": 14, "start": 15,
"end": 28, "end": 29,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -108,8 +108,8 @@
}, },
"id": { "id": {
"type": "Identifier", "type": "Identifier",
"start": 14, "start": 15,
"end": 18, "end": 19,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -124,8 +124,8 @@
}, },
"init": { "init": {
"type": "Literal", "type": "Literal",
"start": 21, "start": 22,
"end": 28, "end": 29,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -148,9 +148,9 @@
"trailingComments": [ "trailingComments": [
{ {
"type": "Block", "type": "Block",
"value": "\n\ttrailing multiline comment\n", "value": "\r\n\ttrailing multiline comment\r\n",
"start": 32, "start": 35,
"end": 67 "end": 72
} }
] ]
} }

@ -1,38 +1,38 @@
{ {
"html": { "html": {
"start": 68, "start": 74,
"end": 90, "end": 96,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 66, "start": 70,
"end": 68, "end": 74,
"type": "Text", "type": "Text",
"raw": "\n\n", "raw": "\r\n\r\n",
"data": "\n\n" "data": "\r\n\r\n"
}, },
{ {
"start": 68, "start": 74,
"end": 90, "end": 96,
"type": "Element", "type": "Element",
"name": "h1", "name": "h1",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 72, "start": 78,
"end": 78, "end": 84,
"type": "Text", "type": "Text",
"raw": "Hello ", "raw": "Hello ",
"data": "Hello " "data": "Hello "
}, },
{ {
"start": 78, "start": 84,
"end": 84, "end": 90,
"type": "MustacheTag", "type": "MustacheTag",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 79, "start": 85,
"end": 83, "end": 89,
"loc": { "loc": {
"start": { "start": {
"line": 7, "line": 7,
@ -47,8 +47,8 @@
} }
}, },
{ {
"start": 84, "start": 90,
"end": 85, "end": 91,
"type": "Text", "type": "Text",
"raw": "!", "raw": "!",
"data": "!" "data": "!"
@ -60,12 +60,12 @@
"instance": { "instance": {
"type": "Script", "type": "Script",
"start": 0, "start": 0,
"end": 66, "end": 70,
"context": "default", "context": "default",
"content": { "content": {
"type": "Program", "type": "Program",
"start": 8, "start": 8,
"end": 57, "end": 61,
"loc": { "loc": {
"start": { "start": {
"line": 1, "line": 1,
@ -79,8 +79,8 @@
"body": [ "body": [
{ {
"type": "VariableDeclaration", "type": "VariableDeclaration",
"start": 10, "start": 11,
"end": 29, "end": 30,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -94,8 +94,8 @@
"declarations": [ "declarations": [
{ {
"type": "VariableDeclarator", "type": "VariableDeclarator",
"start": 14, "start": 15,
"end": 28, "end": 29,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -108,8 +108,8 @@
}, },
"id": { "id": {
"type": "Identifier", "type": "Identifier",
"start": 14, "start": 15,
"end": 18, "end": 19,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -124,8 +124,8 @@
}, },
"init": { "init": {
"type": "Literal", "type": "Literal",
"start": 21, "start": 22,
"end": 28, "end": 29,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -149,8 +149,8 @@
{ {
"type": "Line", "type": "Line",
"value": " trailing line comment", "value": " trailing line comment",
"start": 32, "start": 35,
"end": 56 "end": 59
} }
] ]
} }

@ -1,38 +1,38 @@
{ {
"html": { "html": {
"start": 41, "start": 45,
"end": 63, "end": 67,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 39, "start": 41,
"end": 41, "end": 45,
"type": "Text", "type": "Text",
"raw": "\n\n", "raw": "\r\n\r\n",
"data": "\n\n" "data": "\r\n\r\n"
}, },
{ {
"start": 41, "start": 45,
"end": 63, "end": 67,
"type": "Element", "type": "Element",
"name": "h1", "name": "h1",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 45, "start": 49,
"end": 51, "end": 55,
"type": "Text", "type": "Text",
"raw": "Hello ", "raw": "Hello ",
"data": "Hello " "data": "Hello "
}, },
{ {
"start": 51, "start": 55,
"end": 57, "end": 61,
"type": "MustacheTag", "type": "MustacheTag",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 52, "start": 56,
"end": 56, "end": 60,
"loc": { "loc": {
"start": { "start": {
"line": 5, "line": 5,
@ -47,8 +47,8 @@
} }
}, },
{ {
"start": 57, "start": 61,
"end": 58, "end": 62,
"type": "Text", "type": "Text",
"raw": "!", "raw": "!",
"data": "!" "data": "!"
@ -60,12 +60,12 @@
"instance": { "instance": {
"type": "Script", "type": "Script",
"start": 0, "start": 0,
"end": 39, "end": 41,
"context": "default", "context": "default",
"content": { "content": {
"type": "Program", "type": "Program",
"start": 8, "start": 8,
"end": 30, "end": 32,
"loc": { "loc": {
"start": { "start": {
"line": 1, "line": 1,
@ -79,8 +79,8 @@
"body": [ "body": [
{ {
"type": "VariableDeclaration", "type": "VariableDeclaration",
"start": 10, "start": 11,
"end": 29, "end": 30,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -94,8 +94,8 @@
"declarations": [ "declarations": [
{ {
"type": "VariableDeclarator", "type": "VariableDeclarator",
"start": 14, "start": 15,
"end": 28, "end": 29,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -108,8 +108,8 @@
}, },
"id": { "id": {
"type": "Identifier", "type": "Identifier",
"start": 14, "start": 15,
"end": 18, "end": 19,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -124,8 +124,8 @@
}, },
"init": { "init": {
"type": "Literal", "type": "Literal",
"start": 21, "start": 22,
"end": 28, "end": 29,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,

@ -1,12 +1,12 @@
{ {
"html": { "html": {
"start": 0, "start": 0,
"end": 57, "end": 59,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 0, "start": 0,
"end": 57, "end": 59,
"type": "IfBlock", "type": "IfBlock",
"expression": { "expression": {
"type": "BinaryExpression", "type": "BinaryExpression",
@ -59,25 +59,25 @@
}, },
"children": [ "children": [
{ {
"start": 17, "start": 18,
"end": 51, "end": 52,
"type": "InlineComponent", "type": "InlineComponent",
"name": "svelte:self", "name": "svelte:self",
"attributes": [ "attributes": [
{ {
"start": 30, "start": 31,
"end": 49, "end": 50,
"type": "Attribute", "type": "Attribute",
"name": "depth", "name": "depth",
"value": [ "value": [
{ {
"start": 37, "start": 38,
"end": 48, "end": 49,
"type": "MustacheTag", "type": "MustacheTag",
"expression": { "expression": {
"type": "BinaryExpression", "type": "BinaryExpression",
"start": 38, "start": 39,
"end": 47, "end": 48,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -90,8 +90,8 @@
}, },
"left": { "left": {
"type": "Identifier", "type": "Identifier",
"start": 38, "start": 39,
"end": 43, "end": 44,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -107,8 +107,8 @@
"operator": "-", "operator": "-",
"right": { "right": {
"type": "Literal", "type": "Literal",
"start": 46, "start": 47,
"end": 47, "end": 48,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,

@ -1,12 +1,12 @@
{ {
"html": { "html": {
"start": 0, "start": 0,
"end": 61, "end": 63,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 0, "start": 0,
"end": 61, "end": 63,
"type": "Element", "type": "Element",
"name": "textarea", "name": "textarea",
"attributes": [ "attributes": [
@ -16,19 +16,19 @@
"value": [ "value": [
{ {
"start": 10, "start": 10,
"end": 41, "end": 42,
"type": "Text", "type": "Text",
"raw": "\n\t<p>not actually an element. ", "raw": "\r\n\t<p>not actually an element. ",
"data": "\n\t<p>not actually an element. " "data": "\r\n\t<p>not actually an element. "
}, },
{ {
"start": 40, "start": 41,
"end": 45, "end": 46,
"type": "MustacheTag", "type": "MustacheTag",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 41, "start": 42,
"end": 44, "end": 45,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -43,11 +43,11 @@
} }
}, },
{ {
"start": 45, "start": 46,
"end": 50, "end": 52,
"type": "Text", "type": "Text",
"raw": "</p>\n", "raw": "</p>\r\n",
"data": "</p>\n" "data": "</p>\r\n"
} }
] ]
} }

@ -1,12 +1,12 @@
{ {
"html": { "html": {
"start": 0, "start": 0,
"end": 41, "end": 43,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 0, "start": 0,
"end": 41, "end": 43,
"type": "EachBlock", "type": "EachBlock",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
@ -26,20 +26,20 @@
}, },
"children": [ "children": [
{ {
"start": 22, "start": 23,
"end": 33, "end": 34,
"type": "Element", "type": "Element",
"name": "p", "name": "p",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 25, "start": 26,
"end": 29, "end": 30,
"type": "MustacheTag", "type": "MustacheTag",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 26, "start": 27,
"end": 28, "end": 29,
"loc": { "loc": {
"start": { "start": {
"line": 2, "line": 2,
@ -57,10 +57,10 @@
} }
], ],
"context": { "context": {
"start": 17,
"end": 19,
"type": "Identifier", "type": "Identifier",
"name": "𐊧" "name": "𐊧",
"start": 17,
"end": 19
} }
} }
] ]

@ -1,26 +1,26 @@
{ {
"html": { "html": {
"start": 6, "start": 8,
"end": 36, "end": 38,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 0, "start": 0,
"end": 6, "end": 8,
"type": "Text", "type": "Text",
"raw": "\n\n\t\t\t\t", "raw": "\r\n\r\n\t\t\t\t",
"data": "\n\n\t\t\t\t" "data": "\r\n\r\n\t\t\t\t"
}, },
{ {
"start": 6, "start": 8,
"end": 36, "end": 38,
"type": "Element", "type": "Element",
"name": "p", "name": "p",
"attributes": [], "attributes": [],
"children": [ "children": [
{ {
"start": 9, "start": 11,
"end": 32, "end": 34,
"type": "Text", "type": "Text",
"raw": "just chillin' over here", "raw": "just chillin' over here",
"data": "just chillin' over here" "data": "just chillin' over here"

@ -1,13 +0,0 @@
// this file will replace all the output.json files with their _actual.json
// equivalents. Only use it when you're sure that you haven't
// broken anything!
const fs = require("fs");
const glob = require("tiny-glob/sync.js");
glob("samples/*/_actual.json", { cwd: __dirname }).forEach(file => {
const actual = fs.readFileSync(`${__dirname}/${file}`, "utf-8");
fs.writeFileSync(
`${__dirname}/${file.replace("_actual.json", "output.json")}`,
actual
);
});

@ -0,0 +1,31 @@
import { readFileSync, writeFileSync } from 'fs';
import { resolve } from 'path';
// this file will replace all the expected.js files with their _actual
// equivalents. Only use it when you're sure that you haven't
// broken anything!
const svelte = (function loadSvelte(test) {
process.env.TEST = test ? 'true' : '';
const resolved = require.resolve('../../compiler.js');
delete require.cache[resolved];
return require(resolved);
})(false);
require(resolve(__dirname, '../tiny-glob.ts'))
.glob('samples/*/input.svelte', { cwd: __dirname })
.forEach((file) => {
try {
writeFileSync(
`${__dirname}/${file.replace('input.svelte', 'output.json')}`,
JSON.stringify(
svelte.compile(readFileSync(`${__dirname}/${file}`, 'utf-8').replace(/\s+$/, ''), { generate: false }).ast,
null,
'\t'
)
);
} catch (e) {
if (e.name !== 'ParseError') throw e;
writeFileSync(
`${__dirname}/${file.replace('input.svelte', 'error.json')}`,
JSON.stringify({ ...e, message: e.message }, null, '\t')
);
}
});

@ -1,9 +1,9 @@
import * as fs from 'fs'; import * as fs from 'fs';
import * as assert from 'assert'; import { loadConfig, svelte } from '../helpers';
import { loadConfig, svelte } from '../helpers.js'; import { assert } from '../test';
describe('preprocess', () => { describe('preprocess', () => {
fs.readdirSync(`${__dirname}/samples`).forEach(dir => { fs.readdirSync(`${__dirname}/samples`).forEach((dir) => {
if (dir[0] === '.') return; if (dir[0] === '.') return;
const config = loadConfig(`${__dirname}/samples/${dir}/_config.js`); const config = loadConfig(`${__dirname}/samples/${dir}/_config.js`);

@ -1,20 +1,11 @@
import * as assert from "assert"; import { relative, resolve } from 'path';
import * as path from "path"; import { readFileSync, existsSync, unlinkSync, writeFileSync, readdirSync } from 'fs';
import * as fs from "fs";
import { rollup } from 'rollup'; import { rollup } from 'rollup';
import * as virtual from '@rollup/plugin-virtual'; import virtual from '@rollup/plugin-virtual';
import * as glob from 'tiny-glob/sync.js'; import { clear_loops, flush, SvelteComponent,set_now, set_raf } from '../../internal';
import { clear_loops, flush, set_now, set_raf } from "../../internal"; import { showOutput, loadConfig, loadSvelte, cleanRequireCache, env, setupHtmlEqual, mkdirp } from '../helpers';
import { glob } from '../tiny-glob';
import { import { assert } from '../test';
showOutput,
loadConfig,
loadSvelte,
cleanRequireCache,
env,
setupHtmlEqual,
mkdirp
} from "../helpers.js";
let svelte$; let svelte$;
let svelte; let svelte;
@ -24,24 +15,21 @@ let compile = null;
const sveltePath = process.cwd().split('\\').join('/'); const sveltePath = process.cwd().split('\\').join('/');
let unhandled_rejection = false; let unhandled_rejection: Error | false = false;
process.on('unhandledRejection', err => { process.on('unhandledRejection', (err: Error) => {
unhandled_rejection = err; unhandled_rejection = err;
}); });
describe("runtime", () => { describe('runtime', () => {
before(() => { before(() => {
svelte = loadSvelte(false); svelte = loadSvelte(false);
svelte$ = loadSvelte(true); svelte$ = loadSvelte(true);
require.extensions[".svelte"] = function(module, filename) { require.extensions['.svelte'] = function (module, filename) {
const options = Object.assign({ return module._compile(
compile(readFileSync(filename, 'utf-8'), { filename, ...compileOptions }).js.code,
filename filename
}, compileOptions); );
const { js: { code } } = compile(fs.readFileSync(filename, "utf-8"), options);
return module._compile(code, filename);
}; };
return setupHtmlEqual(); return setupHtmlEqual();
@ -49,19 +37,20 @@ describe("runtime", () => {
const failed = new Set(); const failed = new Set();
function runTest(dir, hydrate) { function runTest(dir, hydratable) {
if (dir[0] === ".") return; if (dir[0] === '.') return;
const config = loadConfig(`${__dirname}/samples/${dir}/_config.js`); const config = loadConfig(`${__dirname}/samples/${dir}/_config.js`);
const solo = config.solo || /\.solo/.test(dir); const solo = config.solo || /\.solo/.test(dir);
const skip = config.skip || /\.skip/.test(dir);
if (hydrate && config.skip_if_hydrate) return; if (hydratable && config.skip_if_hydrate) return;
if (solo && process.env.CI) { if (solo && process.env.CI) {
throw new Error("Forgot to remove `solo: true` from test"); throw new Error('Forgot to remove `solo: true` from test');
} }
(config.skip ? it.skip : solo ? it.only : it)(`${dir} ${hydrate ? '(with hydration)' : ''}`, () => { (skip ? it.skip : solo ? it.only : it)(`${dir} ${hydratable ? '(with hydration)' : ''}`, () => {
if (failed.has(dir)) { if (failed.has(dir)) {
// this makes debugging easier, by only printing compiled output once // this makes debugging easier, by only printing compiled output once
throw new Error('skipping test, already failed'); throw new Error('skipping test, already failed');
@ -69,16 +58,18 @@ describe("runtime", () => {
unhandled_rejection = null; unhandled_rejection = null;
compile = (config.preserveIdentifiers ? svelte : svelte$).compile; ({ compile } = config.preserveIdentifiers ? svelte : svelte$);
const cwd = path.resolve(`${__dirname}/samples/${dir}`); const cwd = resolve(`${__dirname}/samples/${dir}`);
compileOptions = config.compileOptions || {}; compileOptions = {
compileOptions.format = 'cjs'; ...(config.compileOptions || {}),
compileOptions.sveltePath = sveltePath; format: 'cjs',
compileOptions.hydratable = hydrate; sveltePath,
compileOptions.immutable = config.immutable; hydratable,
compileOptions.accessors = 'accessors' in config ? config.accessors : true; immutable: config.immutable,
accessors: 'accessors' in config ? config.accessors : true,
};
cleanRequireCache(); cleanRequireCache();
@ -89,28 +80,23 @@ describe("runtime", () => {
const window = env(); const window = env();
glob('**/*.svelte', { cwd }).forEach(file => { glob('**/*.svelte', { cwd }).forEach((filename) => {
if (file[0] === '_') return; if (filename[0] === '_') return;
const dir = `${cwd}/_output/${hydrate ? 'hydratable' : 'normal'}`; const dir = `${cwd}/_output/${hydratable ? 'hydratable' : 'normal'}`;
const out = `${dir}/${file.replace(/\.svelte$/, '.js')}`; const out = `${dir}/${filename.replace(/\.svelte$/, '.js')}`;
if (fs.existsSync(out)) {
fs.unlinkSync(out);
}
if (existsSync(out)) unlinkSync(out);
mkdirp(dir); mkdirp(dir);
try { try {
const { js } = compile( writeFileSync(
fs.readFileSync(`${cwd}/${file}`, 'utf-8'), out,
{ compile(readFileSync(`${cwd}/${filename}`, 'utf-8'), {
...compileOptions, ...compileOptions,
filename: file filename,
} }).js.code
); );
fs.writeFileSync(out, js.code);
} catch (err) { } catch (err) {
// do nothing // do nothing
} }
@ -118,19 +104,17 @@ describe("runtime", () => {
return Promise.resolve() return Promise.resolve()
.then(() => { .then(() => {
// hack to support transition tests
clear_loops(); clear_loops();
const raf = { const raf = {
time: 0, time: 0,
callback: null, callback: null,
tick: now => { tick: (now) => {
raf.time = now; raf.time = now;
if (raf.callback) raf.callback(); if (raf.callback) raf.callback();
} },
}; };
set_now(() => raf.time); set_now(() => raf.time);
set_raf(cb => { set_raf((cb) => {
raf.callback = () => { raf.callback = () => {
raf.callback = null; raf.callback = null;
cb(raf.time); cb(raf.time);
@ -139,8 +123,7 @@ describe("runtime", () => {
}); });
try { try {
mod = require(`./samples/${dir}/main.svelte`); SvelteComponent = (mod = require(`./samples/${dir}/main.svelte`)).default;
SvelteComponent = mod.default;
} catch (err) { } catch (err) {
showOutput(cwd, compileOptions, compile); // eslint-disable-line no-console showOutput(cwd, compileOptions, compile); // eslint-disable-line no-console
throw err; throw err;
@ -151,35 +134,33 @@ describe("runtime", () => {
// Put things we need on window for testing // Put things we need on window for testing
window.SvelteComponent = SvelteComponent; window.SvelteComponent = SvelteComponent;
const target = window.document.querySelector("main"); const target = window.document.querySelector('main');
const warnings = []; const warnings = [];
const warn = console.warn; const warn = console.warn;
console.warn = warning => { console.warn = (warning) => {
warnings.push(warning); warnings.push(warning);
}; };
const options = Object.assign({}, { const options = {
target, ...{ target, hydrate: hydratable, props: config.props, intro: config.intro },
hydrate, ...(config.options || {}),
props: config.props, };
intro: config.intro
}, config.options || {});
const component = new SvelteComponent(options); const component: SvelteComponent = new SvelteComponent(options);
console.warn = warn; console.warn = warn;
if (config.error) { if (config.error) {
unintendedError = true; unintendedError = true;
throw new Error("Expected a runtime error"); throw new Error('Expected a runtime error');
} }
if (config.warnings) { if (config.warnings) {
assert.deepEqual(warnings, config.warnings); assert.deepEqual(warnings, config.warnings);
} else if (warnings.length) { } else if (warnings.length) {
unintendedError = true; unintendedError = true;
throw new Error("Received unexpected warnings"); throw new Error('Received unexpected warnings');
} }
if (config.html) { if (config.html) {
@ -187,15 +168,18 @@ describe("runtime", () => {
} }
if (config.test) { if (config.test) {
return Promise.resolve(config.test({ return Promise.resolve(
config.test({
assert, assert,
component, component,
mod, mod,
target, target,
window, window,
raf, raf,
compileOptions compileOptions,
})).then(() => { })
).then(() => {
raf.tick(Infinity);
component.$destroy(); component.$destroy();
if (unhandled_rejection) { if (unhandled_rejection) {
@ -204,14 +188,14 @@ describe("runtime", () => {
}); });
} else { } else {
component.$destroy(); component.$destroy();
assert.htmlEqual(target.innerHTML, ""); assert.htmlEqual(target.innerHTML, '');
if (unhandled_rejection) { if (unhandled_rejection) {
throw unhandled_rejection; throw unhandled_rejection;
} }
} }
}) })
.catch(err => { .catch((err) => {
if (config.error && !unintendedError) { if (config.error && !unintendedError) {
if (typeof config.error === 'function') { if (typeof config.error === 'function') {
config.error(assert, err); config.error(assert, err);
@ -221,14 +205,15 @@ describe("runtime", () => {
} else { } else {
throw err; throw err;
} }
}).catch(err => { })
.catch((err) => {
failed.add(dir); failed.add(dir);
showOutput(cwd, compileOptions, compile); // eslint-disable-line no-console showOutput(cwd, compileOptions, compile); // eslint-disable-line no-console
throw err; throw err;
}) })
.catch(err => { .catch((err) => {
// print a clickable link to open the directory // print a clickable link to open the directory
err.stack += `\n\ncmd-click: ${path.relative(process.cwd(), cwd)}/main.svelte`; err.stack += `\n\ncmd-click: ${relative(process.cwd(), cwd)}/main.svelte`;
throw err; throw err;
}) })
.then(() => { .then(() => {
@ -243,23 +228,23 @@ describe("runtime", () => {
}); });
} }
fs.readdirSync(`${__dirname}/samples`).forEach(dir => { readdirSync(`${__dirname}/samples`).forEach((dir) => {
runTest(dir, false); runTest(dir, false);
runTest(dir, true); runTest(dir, true);
}); });
async function create_component(src = '<div></div>') { async function create_component(src = '<div></div>') {
const { js } = svelte$.compile(src, { const { js } = svelte$.compile(src, {
format: "esm", format: 'esm',
name: "SvelteComponent", name: 'SvelteComponent',
dev: true dev: true,
}); });
const bundle = await rollup({ const bundle = await rollup({
input: 'main.js', input: 'main.js',
plugins: [ plugins: [
virtual({ virtual({
'main.js': js.code 'main.js': js.code,
}), }),
{ {
name: 'svelte-packages', name: 'svelte-packages',
@ -267,22 +252,20 @@ describe("runtime", () => {
if (importee.startsWith('svelte/')) { if (importee.startsWith('svelte/')) {
return importee.replace('svelte', process.cwd()) + '/index.mjs'; return importee.replace('svelte', process.cwd()) + '/index.mjs';
} }
} },
} },
] ],
}); });
const result = await bundle.generate({ const result = await bundle.generate({
format: 'iife', format: 'iife',
name: 'App' name: 'App',
}); });
return eval( return eval(`(function () { ${result.output[0].code}; return App; }())`);
`(function () { ${result.output[0].code}; return App; }())`
);
} }
it("fails if options.target is missing in dev mode", async () => { it('fails if options.target is missing in dev mode', async () => {
const App = await create_component(); const App = await create_component();
assert.throws(() => { assert.throws(() => {
@ -290,13 +273,13 @@ describe("runtime", () => {
}, /'target' is a required option/); }, /'target' is a required option/);
}); });
it("fails if options.hydrate is true but the component is non-hydratable", async () => { it('fails if options.hydrate is true but the component is non-hydratable', async () => {
const App = await create_component(); const App = await create_component();
assert.throws(() => { assert.throws(() => {
new App({ new App({
target: { childNodes: [] }, target: { childNodes: [] },
hydrate: true hydrate: true,
}); });
}, /options.hydrate only works if the component was compiled with the `hydratable: true` option/); }, /options.hydrate only works if the component was compiled with the `hydratable: true` option/);
}); });

@ -1,40 +1,39 @@
export default { export default {
html: `<div class=" svelte-x1o6ra"></div>`,
test({ assert, component, target }) { test({ assert, component, target }) {
const div = target.querySelector('div'); const div = target.querySelector('div');
component.testName = null; component.testName = null;
assert.equal(div.className, ' svelte-x1o6ra'); const startsWith = (str) => assert.ok(div.className.startsWith(str));
startsWith(' svelte-');
component.testName = undefined; component.testName = undefined;
assert.equal(div.className, ' svelte-x1o6ra'); startsWith(' svelte-');
component.testName = undefined + ''; component.testName = undefined + '';
assert.equal(div.className, 'undefined svelte-x1o6ra'); startsWith('undefined svelte-');
component.testName = null + ''; component.testName = null + '';
assert.equal(div.className, 'null svelte-x1o6ra'); startsWith('null svelte-');
component.testName = 1; component.testName = 1;
assert.equal(div.className, '1 svelte-x1o6ra'); startsWith('1 svelte-');
component.testName = 0; component.testName = 0;
assert.equal(div.className, '0 svelte-x1o6ra'); startsWith('0 svelte-');
component.testName = false; component.testName = false;
assert.equal(div.className, 'false svelte-x1o6ra'); startsWith('false svelte-');
component.testName = true; component.testName = true;
assert.equal(div.className, 'true svelte-x1o6ra'); startsWith('true svelte-');
component.testName = {}; component.testName = {};
assert.equal(div.className, '[object Object] svelte-x1o6ra'); startsWith('[object Object] svelte-');
component.testName = ''; component.testName = '';
assert.equal(div.className, ' svelte-x1o6ra'); startsWith(' svelte-');
component.testName = 'testClassName'; component.testName = 'testClassName';
assert.equal(div.className, 'testClassName svelte-x1o6ra'); startsWith('testClassName svelte-');
} },
}; };

@ -1,45 +1,43 @@
export default { export default {
props: { props: {
testName1: "test1", testName1: 'test1',
testName2: "test2", testName2: 'test2',
}, },
html: `<div class="test1test2 svelte-x1o6ra"></div>`,
test({ assert, component, target }) { test({ assert, component, target }) {
const div = target.querySelector('div'); const div = target.querySelector('div');
assert.equal(div.className, 'test1test2 svelte-x1o6ra'); const startsWith = (str) => assert.ok(div.className.startsWith(str + ' svelte-'));
startsWith('test1test2');
component.testName1 = null; component.testName1 = null;
component.testName2 = null; component.testName2 = null;
assert.equal(div.className, '0 svelte-x1o6ra'); startsWith('0');
component.testName1 = null; component.testName1 = null;
component.testName2 = "test"; component.testName2 = 'test';
assert.equal(div.className, 'nulltest svelte-x1o6ra'); startsWith('nulltest');
component.testName1 = undefined; component.testName1 = undefined;
component.testName2 = "test"; component.testName2 = 'test';
assert.equal(div.className, 'undefinedtest svelte-x1o6ra'); startsWith('undefinedtest');
component.testName1 = undefined; component.testName1 = undefined;
component.testName2 = undefined; component.testName2 = undefined;
assert.equal(div.className, 'NaN svelte-x1o6ra'); startsWith('NaN');
component.testName1 = null; component.testName1 = null;
component.testName2 = 1; component.testName2 = 1;
assert.equal(div.className, '1 svelte-x1o6ra'); startsWith('1');
component.testName1 = undefined; component.testName1 = undefined;
component.testName2 = 1; component.testName2 = 1;
assert.equal(div.className, 'NaN svelte-x1o6ra'); startsWith('NaN');
component.testName1 = null; component.testName1 = null;
component.testName2 = 0; component.testName2 = 0;
assert.equal(div.className, '0 svelte-x1o6ra'); startsWith('0');
component.testName1 = undefined; component.testName1 = undefined;
component.testName2 = 0; component.testName2 = 0;
assert.equal(div.className, 'NaN svelte-x1o6ra'); startsWith('NaN');
} },
}; };

@ -1,42 +1,40 @@
export default { export default {
props: { props: {
testName: "testClassName" testName: 'testClassName',
}, },
html: `<div class="testClassName svelte-x1o6ra"></div>`,
test({ assert, component, target }) { test({ assert, component, target }) {
const div = target.querySelector('div'); const div = target.querySelector('div');
assert.equal(div.className, 'testClassName svelte-x1o6ra'); const startsWith = (str) => assert.ok(div.className.startsWith(str + ' svelte-'));
startsWith('testClassName');
component.testName = null; component.testName = null;
assert.equal(div.className, ' svelte-x1o6ra'); startsWith('');
component.testName = undefined; component.testName = undefined;
assert.equal(div.className, ' svelte-x1o6ra'); startsWith('');
component.testName = undefined + ''; component.testName = undefined + '';
assert.equal(div.className, 'undefined svelte-x1o6ra'); startsWith('undefined');
component.testName = null + ''; component.testName = null + '';
assert.equal(div.className, 'null svelte-x1o6ra'); startsWith('null');
component.testName = 1; component.testName = 1;
assert.equal(div.className, '1 svelte-x1o6ra'); startsWith('1');
component.testName = 0; component.testName = 0;
assert.equal(div.className, '0 svelte-x1o6ra'); startsWith('0');
component.testName = false; component.testName = false;
assert.equal(div.className, 'false svelte-x1o6ra'); startsWith('false');
component.testName = true; component.testName = true;
assert.equal(div.className, 'true svelte-x1o6ra'); startsWith('true');
component.testName = {}; component.testName = {};
assert.equal(div.className, '[object Object] svelte-x1o6ra'); startsWith('[object Object]');
component.testName = ''; component.testName = '';
assert.equal(div.className, ' svelte-x1o6ra'); startsWith('');
} },
}; };

@ -1,45 +1,43 @@
export default { export default {
props: { props: {
testName1: "test1", testName1: 'test1',
testName2: "test2", testName2: 'test2',
}, },
html: `<div class="test1test2 svelte-x1o6ra"></div>`,
test({ assert, component, target }) { test({ assert, component, target }) {
const div = target.querySelector('div'); const div = target.querySelector('div');
assert.equal(div.className, 'test1test2 svelte-x1o6ra'); const startsWith = (str) => assert.ok(div.className.startsWith(str + ' svelte-'));
startsWith('test1test2');
component.testName1 = null; component.testName1 = null;
component.testName2 = null; component.testName2 = null;
assert.equal(div.className, '0 svelte-x1o6ra'); startsWith('0');
component.testName1 = null; component.testName1 = null;
component.testName2 = "test"; component.testName2 = 'test';
assert.equal(div.className, 'nulltest svelte-x1o6ra'); startsWith('nulltest');
component.testName1 = undefined; component.testName1 = undefined;
component.testName2 = "test"; component.testName2 = 'test';
assert.equal(div.className, 'undefinedtest svelte-x1o6ra'); startsWith('undefinedtest');
component.testName1 = undefined; component.testName1 = undefined;
component.testName2 = undefined; component.testName2 = undefined;
assert.equal(div.className, 'NaN svelte-x1o6ra'); startsWith('NaN');
component.testName1 = null; component.testName1 = null;
component.testName2 = 1; component.testName2 = 1;
assert.equal(div.className, '1 svelte-x1o6ra'); startsWith('1');
component.testName1 = undefined; component.testName1 = undefined;
component.testName2 = 1; component.testName2 = 1;
assert.equal(div.className, 'NaN svelte-x1o6ra'); startsWith('NaN');
component.testName1 = null; component.testName1 = null;
component.testName2 = 0; component.testName2 = 0;
assert.equal(div.className, '0 svelte-x1o6ra'); startsWith('0');
component.testName1 = undefined; component.testName1 = undefined;
component.testName2 = 0; component.testName2 = 0;
assert.equal(div.className, 'NaN svelte-x1o6ra'); startsWith('NaN');
} },
}; };

@ -13,14 +13,14 @@ export default {
file: path.relative(process.cwd(), path.resolve(__dirname, 'main.svelte')), file: path.relative(process.cwd(), path.resolve(__dirname, 'main.svelte')),
line: 4, line: 4,
column: 0, column: 0,
char: 53 char: 57
}); });
assert.deepEqual(p.__svelte_meta.loc, { assert.deepEqual(p.__svelte_meta.loc, {
file: path.relative(process.cwd(), path.resolve(__dirname, 'Foo.svelte')), file: path.relative(process.cwd(), path.resolve(__dirname, 'Foo.svelte')),
line: 1, line: 1,
column: 1, column: 1,
char: 7 char: 8
}); });
} }
}; };

@ -1,6 +1,6 @@
export default { export default {
html: ` html: `
<p class="svelte-y94hdy" style="color: red !important; font-size: 20px !important; opacity: 1;">red</p> <p class="svelte-7m7nuf" style="color: red !important; font-size: 20px !important; opacity: 1;">red</p>
`, `,
test({ assert, component, target, window }) { test({ assert, component, target, window }) {

@ -1,7 +1,7 @@
export default { export default {
html: ` html: `
<div class="foo svelte-xg5rbo">red</div> <div class="foo svelte-1553ulx">red</div>
<div class="qux svelte-xg5rbo">red</div> <div class="qux svelte-1553ulx">red</div>
<div class="bar svelte-xg5rbo">red and bold</div> <div class="bar svelte-1553ulx">red and bold</div>
` `
}; };

@ -5,9 +5,9 @@ export default {
html: ` html: `
<svg> <svg>
<circle class="svelte-i03x00" cx=50 cy=50 r=50 /> <circle class="svelte-1h4oike" cx=50 cy=50 r=50 />
<circle class="foo svelte-i03x00" cx=150 cy=50 r=50 /> <circle class="foo svelte-1h4oike" cx=150 cy=50 r=50 />
<circle class="bar svelte-i03x00" cx=250 cy=50 r=50 /> <circle class="bar svelte-1h4oike" cx=250 cy=50 r=50 />
</svg> </svg>
` `
}; };

@ -1,7 +1,5 @@
import * as assert from "assert"; import * as fs from 'fs';
import * as fs from "fs"; import * as path from 'path';
import * as path from "path";
import * as glob from 'tiny-glob/sync.js';
import { import {
showOutput, showOutput,
@ -11,14 +9,16 @@ import {
tryToLoadJson, tryToLoadJson,
cleanRequireCache, cleanRequireCache,
shouldUpdateExpected, shouldUpdateExpected,
mkdirp mkdirp,
} from "../helpers.js"; } from '../helpers';
import { glob } from '../tiny-glob';
import { assert } from '../test';
function tryToReadFile(file) { function tryToReadFile(file) {
try { try {
return fs.readFileSync(file, "utf-8"); return fs.readFileSync(file, 'utf-8');
} catch (err) { } catch (err) {
if (err.code !== "ENOENT") throw err; if (err.code !== 'ENOENT') throw err;
return null; return null;
} }
} }
@ -26,28 +26,29 @@ function tryToReadFile(file) {
const sveltePath = process.cwd().split('\\').join('/'); const sveltePath = process.cwd().split('\\').join('/');
let compile = null; let compile = null;
describe("ssr", () => { describe('ssr', () => {
before(() => { before(() => {
compile = loadSvelte(true).compile; compile = loadSvelte(true).compile;
return setupHtmlEqual(); return setupHtmlEqual();
}); });
fs.readdirSync(`${__dirname}/samples`).forEach(dir => { fs.readdirSync(`${__dirname}/samples`).forEach((dir) => {
if (dir[0] === ".") return; if (dir[0] === '.') return;
const config = loadConfig(`${__dirname}/samples/${dir}/_config.js`); const config = loadConfig(`${__dirname}/samples/${dir}/_config.js`);
// add .solo to a sample directory name to only run that test, or // add .solo to a sample directory name to only run that test, or
// .show to always show the output. or both // .show to always show the output. or both
const solo = config.solo || /\.solo/.test(dir); const solo = config.solo || /\.solo/.test(dir);
const skip = config.skip || /\.skip/.test(dir);
const show = /\.show/.test(dir); const show = /\.show/.test(dir);
if (solo && process.env.CI) { if (solo && process.env.CI) {
throw new Error("Forgot to remove `solo: true` from test"); throw new Error('Forgot to remove `solo: true` from test');
} }
(solo ? it.only : it)(dir, () => { (skip ? it.skip : solo ? it.only : it)(dir, () => {
dir = path.resolve(`${__dirname}/samples`, dir); dir = path.resolve(`${__dirname}/samples`, dir);
cleanRequireCache(); cleanRequireCache();
@ -56,16 +57,16 @@ describe("ssr", () => {
sveltePath, sveltePath,
...config.compileOptions, ...config.compileOptions,
generate: 'ssr', generate: 'ssr',
format: 'cjs' format: 'cjs',
}; };
require("../../register")(compileOptions); require('../../register')(compileOptions);
try { try {
const Component = require(`${dir}/main.svelte`).default; const Component = require(`${dir}/main.svelte`).default;
const expectedHtml = tryToReadFile(`${dir}/_expected.html`); const expectedHtml = tryToReadFile(`${dir}/_expected.html`);
const expectedCss = tryToReadFile(`${dir}/_expected.css`) || ""; const expectedCss = tryToReadFile(`${dir}/_expected.css`) || '';
const props = tryToLoadJson(`${dir}/data.json`) || undefined; const props = tryToLoadJson(`${dir}/data.json`) || undefined;
@ -87,10 +88,7 @@ describe("ssr", () => {
} }
try { try {
assert.equal( assert.equal(css.code.replace(/^\s+/gm, '').replace(/[\r\n]/, ''), expectedCss.replace(/^\s+/gm, '').replace(/[\r\n]/, ''));
css.code.replace(/^\s+/gm, ""),
expectedCss.replace(/^\s+/gm, "")
);
} catch (error) { } catch (error) {
if (shouldUpdateExpected()) { if (shouldUpdateExpected()) {
fs.writeFileSync(`${dir}/_expected.css`, css.code); fs.writeFileSync(`${dir}/_expected.css`, css.code);
@ -104,10 +102,7 @@ describe("ssr", () => {
fs.writeFileSync(`${dir}/_actual-head.html`, head); fs.writeFileSync(`${dir}/_actual-head.html`, head);
try { try {
assert.htmlEqual( assert.htmlEqual(head, fs.readFileSync(`${dir}/_expected-head.html`, 'utf-8'));
head,
fs.readFileSync(`${dir}/_expected-head.html`, 'utf-8')
);
} catch (error) { } catch (error) {
if (shouldUpdateExpected()) { if (shouldUpdateExpected()) {
fs.writeFileSync(`${dir}/_expected-head.html`, head); fs.writeFileSync(`${dir}/_expected-head.html`, head);
@ -128,20 +123,21 @@ describe("ssr", () => {
}); });
// duplicate client-side tests, as far as possible // duplicate client-side tests, as far as possible
fs.readdirSync("test/runtime/samples").forEach(dir => { fs.readdirSync('test/runtime/samples').forEach((dir) => {
if (dir[0] === ".") return; if (dir[0] === '.') return;
const config = loadConfig(`./runtime/samples/${dir}/_config.js`); const config = loadConfig(`./runtime/samples/${dir}/_config.js`);
const solo = config.solo || /\.solo/.test(dir); const solo = config.solo || /\.solo/.test(dir);
const skip = config.skip || /\.skip/.test(dir);
if (solo && process.env.CI) { if (solo && process.env.CI) {
throw new Error("Forgot to remove `solo: true` from test"); throw new Error('Forgot to remove `solo: true` from test');
} }
if (config.skip_if_ssr) return; if (config.skip_if_ssr) return;
(config.skip ? it.skip : solo ? it.only : it)(dir, () => { (skip ? it.skip : solo ? it.only : it)(dir, () => {
const cwd = path.resolve("test/runtime/samples", dir); const cwd = path.resolve('test/runtime/samples', dir);
cleanRequireCache(); cleanRequireCache();
@ -151,12 +147,12 @@ describe("ssr", () => {
sveltePath, sveltePath,
...config.compileOptions, ...config.compileOptions,
generate: 'ssr', generate: 'ssr',
format: 'cjs' format: 'cjs',
}; };
require("../../register")(compileOptions); require('../../register')(compileOptions);
glob('**/*.svelte', { cwd }).forEach(file => { glob('**/*.svelte', { cwd }).forEach((file) => {
if (file[0] === '_') return; if (file[0] === '_') return;
const dir = `${cwd}/_output/ssr`; const dir = `${cwd}/_output/ssr`;
@ -169,13 +165,10 @@ describe("ssr", () => {
mkdirp(dir); mkdirp(dir);
try { try {
const { js } = compile( const { js } = compile(fs.readFileSync(`${cwd}/${file}`, 'utf-8'), {
fs.readFileSync(`${cwd}/${file}`, 'utf-8'),
{
...compileOptions, ...compileOptions,
filename: file filename: file,
} });
);
fs.writeFileSync(out, js.code); fs.writeFileSync(out, js.code);
} catch (err) { } catch (err) {
@ -188,7 +181,7 @@ describe("ssr", () => {
const Component = require(`../runtime/samples/${dir}/main.svelte`).default; const Component = require(`../runtime/samples/${dir}/main.svelte`).default;
const { html } = Component.render(config.props, { const { html } = Component.render(config.props, {
store: (config.store !== true) && config.store store: config.store !== true && config.store,
}); });
if (config.ssrHtml) { if (config.ssrHtml) {

@ -1,4 +1,4 @@
<title>Some Title</title> <title>Some Title</title>
<link rel="canonical" href="/" data-svelte="svelte-1s8aodm"> <link rel="canonical" href="/" data-svelte="svelte-1t0pfk9">
<meta name="description" content="some description" data-svelte="svelte-1s8aodm"> <meta name="description" content="some description" data-svelte="svelte-1t0pfk9">
<meta name="keywords" content="some keywords" data-svelte="svelte-1s8aodm"> <meta name="keywords" content="some keywords" data-svelte="svelte-1t0pfk9">

@ -1,2 +1,2 @@
div.svelte-bzh57p{color:red} div.svelte-awisl7{color:red}
div.svelte-4yw8vx{color:green} div.svelte-1us38kz{color:green}

@ -1,8 +1,6 @@
<div class="svelte-bzh57p">red</div> <div class="svelte-awisl7">red</div>
<div class="svelte-4yw8vx">green: foo</div> <div class="svelte-1us38kz">green: foo</div>
<div class="svelte-4yw8vx">green: bar</div> <div class="svelte-1us38kz">green: bar</div>

@ -1 +1 @@
div.svelte-bzh57p{color:red} div.svelte-awisl7{color:red}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save