diff --git a/.changeset/itchy-beans-melt.md b/.changeset/itchy-beans-melt.md new file mode 100644 index 0000000000..e6a58d02ff --- /dev/null +++ b/.changeset/itchy-beans-melt.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +chore: fix compiler errors test suite diff --git a/.changeset/sweet-mangos-beg.md b/.changeset/sweet-mangos-beg.md new file mode 100644 index 0000000000..3a0adfc03c --- /dev/null +++ b/.changeset/sweet-mangos-beg.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: handle css nth-selector syntax diff --git a/packages/svelte/src/compiler/errors.js b/packages/svelte/src/compiler/errors.js index 2a2d969475..8d01f4ac97 100644 --- a/packages/svelte/src/compiler/errors.js +++ b/packages/svelte/src/compiler/errors.js @@ -24,9 +24,11 @@ const internal = { const parse = { /** @param {string} name */ 'unclosed-element': (name) => `<${name}> was left open`, - 'unclosed-block': () => `block was left open`, + 'unclosed-block': () => `Block was left open`, 'unexpected-block-close': () => `Unexpected block closing tag`, - 'unexpected-eof': () => `Unexpected end of input`, + /** @param {string} [expected] */ + 'unexpected-eof': (expected) => + `Unexpected end of input` + (expected ? ` (expected ${expected})` : ''), /** @param {string} message */ 'js-parse-error': (message) => message, /** @param {string} token */ @@ -39,17 +41,15 @@ const parse = { 'invalid-script-context': () => `If the context attribute is supplied, its value must be "module"`, 'invalid-elseif': () => `'elseif' should be 'else if'`, - /** - * @param {string} child - * @param {string} parent - */ - 'invalid-block-parent': (child, parent) => - `Expected to close ${parent} before seeing ${child} block`, + 'invalid-continuing-block-placement': () => + `{:...} block is invalid at this position (did you forget to close the preceeding element or block?)`, /** * @param {string} child * @param {string} parent */ 'invalid-block-missing-parent': (child, parent) => `${child} block must be a child of ${parent}`, + /** @param {string} name */ + 'duplicate-block-part': (name) => `${name} cannot appear more than once within a block`, 'expected-block-type': () => `Expected 'if', 'each', 'await', 'key' or 'snippet'`, 'expected-identifier': () => `Expected an identifier`, 'invalid-debug': () => `{@debug ...} arguments must be identifiers, not arbitrary expressions`, @@ -98,12 +98,9 @@ const css = { 'invalid-css-empty-declaration': () => `Declaration cannot be empty`, 'invalid-css-global-placement': () => `:global(...) can be at the start or end of a selector sequence, but not in the middle`, - 'invalid-css-global-selector': () => `:global(...) must contain exactly one selector`, - 'invalid-css-global-selector-list': () => `:global(...) cannot be used to modify a selector, or be modified by another selector`, - 'invalid-css-selector': () => `Invalid selector`, 'invalid-css-identifier': () => 'Expected a valid CSS identifier' }; diff --git a/packages/svelte/src/compiler/phases/1-parse/index.js b/packages/svelte/src/compiler/phases/1-parse/index.js index 5199ad5960..6b7642c251 100644 --- a/packages/svelte/src/compiler/phases/1-parse/index.js +++ b/packages/svelte/src/compiler/phases/1-parse/index.js @@ -77,8 +77,10 @@ export class Parser { const current = this.current(); if (current.type === 'RegularElement') { + current.end = current.start + 1; error(current, 'unclosed-element', current.name); } else { + current.end = current.start + 1; error(current, 'unclosed-block'); } } @@ -145,7 +147,7 @@ export class Parser { if (required) { if (this.index === this.template.length) { - error(this.index, 'unexpected-eof'); + error(this.index, 'unexpected-eof', str); } else { error(this.index, 'expected-token', str); } diff --git a/packages/svelte/src/compiler/phases/1-parse/read/style.js b/packages/svelte/src/compiler/phases/1-parse/read/style.js index 5197f10329..9f59e8205e 100644 --- a/packages/svelte/src/compiler/phases/1-parse/read/style.js +++ b/packages/svelte/src/compiler/phases/1-parse/read/style.js @@ -6,6 +6,7 @@ const REGEX_ATTRIBUTE_FLAGS = /^[a-zA-Z]+/; // only `i` and `s` are valid today, const REGEX_COMBINATOR_WHITESPACE = /^\s*(\+|~|>|\|\|)\s*/; const REGEX_COMBINATOR = /^(\+|~|>|\|\|)/; const REGEX_PERCENTAGE = /^\d+(\.\d+)?%/; +const REGEX_NTH_OF = /^(even|odd|(-?[0-9]?n?(\s*\+\s*[0-9]+)?))(\s+of\s+)?/; const REGEX_WHITESPACE_OR_COLON = /[\s:]/; const REGEX_BRACE_OR_SEMICOLON = /[{;]/; const REGEX_LEADING_HYPHEN_OR_DIGIT = /-?\d/; @@ -234,6 +235,8 @@ function read_selector(parser, inside_pseudo_class = false) { if (parser.eat('(')) { args = read_selector_list(parser, true); parser.eat(')', true); + } else if (name === 'global') { + error(parser.index, 'invalid-css-global-selector'); } children.push({ @@ -291,6 +294,13 @@ function read_selector(parser, inside_pseudo_class = false) { start, end: parser.index }); + } else if (parser.match_regex(REGEX_NTH_OF)) { + children.push({ + type: 'Nth', + value: /** @type {string} */ (parser.read(REGEX_NTH_OF)), + start, + end: parser.index + }); } else { let name = read_identifier(parser); if (parser.match('|')) { diff --git a/packages/svelte/src/compiler/phases/1-parse/state/element.js b/packages/svelte/src/compiler/phases/1-parse/state/element.js index a5e2a2a82a..019e29c944 100644 --- a/packages/svelte/src/compiler/phases/1-parse/state/element.js +++ b/packages/svelte/src/compiler/phases/1-parse/state/element.js @@ -202,11 +202,13 @@ export default function tag(parser) { let attribute; while ((attribute = read(parser))) { - if ( - (attribute.type === 'Attribute' || attribute.type === 'BindDirective') && - unique_names.includes(attribute.name) - ) { - error(attribute.start, 'duplicate-attribute'); + if (attribute.type === 'Attribute' || attribute.type === 'BindDirective') { + if (unique_names.includes(attribute.name)) { + error(attribute.start, 'duplicate-attribute'); + // is allowed + } else if (attribute.name !== 'this') { + unique_names.push(attribute.name); + } } element.attributes.push(attribute); @@ -635,13 +637,14 @@ function read_attribute_value(parser) { 'in attribute value' ); } catch (/** @type {any} e */ e) { - if (e.code === 'parse-error') { + if (e.code === 'js-parse-error') { // if the attribute value didn't close + self-closing tag // eg: `` // acorn may throw a `Unterminated regular expression` because of `/>` - if (parser.template.slice(e.pos - 1, e.pos + 1) === '/>') { - parser.index = e.pos; - error(e.pos, 'unclosed-attribute-value', quote_mark || '}'); + const pos = e.position?.[0]; + if (pos !== undefined && parser.template.slice(pos - 1, pos + 1) === '/>') { + parser.index = pos; + error(pos, 'unclosed-attribute-value', quote_mark || '}'); } } throw e; diff --git a/packages/svelte/src/compiler/phases/1-parse/state/tag.js b/packages/svelte/src/compiler/phases/1-parse/state/tag.js index 36a66ac59f..ebfebb73b1 100644 --- a/packages/svelte/src/compiler/phases/1-parse/state/tag.js +++ b/packages/svelte/src/compiler/phases/1-parse/state/tag.js @@ -315,7 +315,7 @@ function next(parser) { const block = parser.current(); // TODO type should not be TemplateNode, that's much too broad if (block.type === 'IfBlock') { - if (!parser.eat('else')) error(start, 'expected-token', 'else'); + if (!parser.eat('else')) error(start, 'expected-token', '{:else} or {:else if}'); if (parser.eat('if')) error(start, 'invalid-elseif'); parser.allow_whitespace(); @@ -359,7 +359,7 @@ function next(parser) { } if (block.type === 'EachBlock') { - if (!parser.eat('else')) error(start, 'expected-token', 'else'); + if (!parser.eat('else')) error(start, 'expected-token', '{:else}'); parser.allow_whitespace(); parser.eat('}', true); @@ -375,7 +375,7 @@ function next(parser) { if (block.type === 'AwaitBlock') { if (parser.eat('then')) { if (block.then) { - error(start, 'TODO', 'duplicate then'); + error(start, 'duplicate-block-part', '{:then}'); } if (!parser.eat('}')) { @@ -394,7 +394,7 @@ function next(parser) { if (parser.eat('catch')) { if (block.catch) { - error(start, 'TODO', 'duplicate catch'); + error(start, 'duplicate-block-part', '{:catch}'); } if (!parser.eat('}')) { @@ -413,6 +413,8 @@ function next(parser) { error(start, 'expected-token', '{:then ...} or {:catch ...}'); } + + error(start, 'invalid-continuing-block-placement'); } /** @param {import('../index.js').Parser} parser */ diff --git a/packages/svelte/src/compiler/phases/2-analyze/css/Selector.js b/packages/svelte/src/compiler/phases/2-analyze/css/Selector.js index fcddaf2df6..b0942d6572 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/css/Selector.js +++ b/packages/svelte/src/compiler/phases/2-analyze/css/Selector.js @@ -306,7 +306,7 @@ function block_might_apply_to_node(block, node) { while (i--) { const selector = block.selectors[i]; - if (selector.type === 'Percentage') continue; + if (selector.type === 'Percentage' || selector.type === 'Nth') continue; const name = selector.name.replace(regex_backslash_and_following_character, '$1'); diff --git a/packages/svelte/src/compiler/types/css.d.ts b/packages/svelte/src/compiler/types/css.d.ts index 7d936207ac..49a3fc5143 100644 --- a/packages/svelte/src/compiler/types/css.d.ts +++ b/packages/svelte/src/compiler/types/css.d.ts @@ -67,6 +67,11 @@ export interface Percentage extends BaseNode { value: string; } +export interface Nth extends BaseNode { + type: 'Nth'; + value: string; +} + export type SimpleSelector = | TypeSelector | IdSelector @@ -74,7 +79,8 @@ export type SimpleSelector = | AttributeSelector | PseudoElementSelector | PseudoClassSelector - | Percentage; + | Percentage + | Nth; export interface Combinator extends BaseNode { type: 'Combinator'; diff --git a/packages/svelte/tests/compiler-errors/samples/attribute-empty/_config.js b/packages/svelte/tests/compiler-errors/samples/attribute-empty/_config.js index 5823dca910..248fc1107e 100644 --- a/packages/svelte/tests/compiler-errors/samples/attribute-empty/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/attribute-empty/_config.js @@ -3,7 +3,7 @@ import { test } from '../../test'; export default test({ error: { code: 'missing-attribute-value', - message: 'Expected value for the attribute', + message: 'Expected attribute value', position: [12, 12] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/attribute-empty/input.svelte b/packages/svelte/tests/compiler-errors/samples/attribute-empty/main.svelte similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/attribute-empty/input.svelte rename to packages/svelte/tests/compiler-errors/samples/attribute-empty/main.svelte diff --git a/packages/svelte/tests/compiler-errors/samples/attribute-unique-binding/input.svelte b/packages/svelte/tests/compiler-errors/samples/attribute-unique-binding/main.svelte similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/attribute-unique-binding/input.svelte rename to packages/svelte/tests/compiler-errors/samples/attribute-unique-binding/main.svelte diff --git a/packages/svelte/tests/compiler-errors/samples/attribute-unique-shorthand/input.svelte b/packages/svelte/tests/compiler-errors/samples/attribute-unique-shorthand/main.svelte similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/attribute-unique-shorthand/input.svelte rename to packages/svelte/tests/compiler-errors/samples/attribute-unique-shorthand/main.svelte diff --git a/packages/svelte/tests/compiler-errors/samples/attribute-unique/input.svelte b/packages/svelte/tests/compiler-errors/samples/attribute-unique/main.svelte similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/attribute-unique/input.svelte rename to packages/svelte/tests/compiler-errors/samples/attribute-unique/main.svelte diff --git a/packages/svelte/tests/compiler-errors/samples/catch-before-closing/_config.js b/packages/svelte/tests/compiler-errors/samples/catch-before-closing/_config.js index 5fb8c58c2a..1a50076da4 100644 --- a/packages/svelte/tests/compiler-errors/samples/catch-before-closing/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/catch-before-closing/_config.js @@ -2,8 +2,8 @@ import { test } from '../../test'; export default test({ error: { - code: 'invalid-catch-placement', - message: 'Expected to close {#each} block before seeing {:catch} block', - position: [41, 41] + code: 'expected-token', + message: 'Expected token {:else}', + position: [35, 35] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/catch-before-closing/input.svelte b/packages/svelte/tests/compiler-errors/samples/catch-before-closing/main.svelte similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/catch-before-closing/input.svelte rename to packages/svelte/tests/compiler-errors/samples/catch-before-closing/main.svelte diff --git a/packages/svelte/tests/compiler-errors/samples/catch-without-await/_config.js b/packages/svelte/tests/compiler-errors/samples/catch-without-await/_config.js index 63f3b5e3cd..64c85f85c9 100644 --- a/packages/svelte/tests/compiler-errors/samples/catch-without-await/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/catch-without-await/_config.js @@ -2,8 +2,9 @@ import { test } from '../../test'; export default test({ error: { - code: 'invalid-catch-placement', - message: 'Cannot have an {:catch} block outside an {#await ...} block', - position: [7, 7] + code: 'invalid-continuing-block-placement', + message: + '{:...} block is invalid at this position (did you forget to close the preceeding element or block?)', + position: [1, 1] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/catch-without-await/input.svelte b/packages/svelte/tests/compiler-errors/samples/catch-without-await/main.svelte similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/catch-without-await/input.svelte rename to packages/svelte/tests/compiler-errors/samples/catch-without-await/main.svelte diff --git a/packages/svelte/tests/compiler-errors/samples/class-state-field-static/_config.js b/packages/svelte/tests/compiler-errors/samples/class-state-field-static/_config.js index b6dca4e40d..27991ba427 100644 --- a/packages/svelte/tests/compiler-errors/samples/class-state-field-static/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/class-state-field-static/_config.js @@ -4,6 +4,6 @@ export default test({ error: { code: 'invalid-state-location', message: '$state() can only be used as a variable declaration initializer or a class field', - position: process.platform === 'win32' ? [35, 43] : [33, 41] + position: [33, 41] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/comment-unclosed/_config.js b/packages/svelte/tests/compiler-errors/samples/comment-unclosed/_config.js index 166a9df9b7..7c00375ad6 100644 --- a/packages/svelte/tests/compiler-errors/samples/comment-unclosed/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/comment-unclosed/_config.js @@ -2,8 +2,8 @@ import { test } from '../../test'; export default test({ error: { - code: 'unclosed-comment', - message: 'comment was left open, expected -->', + code: 'unexpected-eof', + message: 'Unexpected end of input (expected -->)', position: [24, 24] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/comment-unclosed/input.svelte b/packages/svelte/tests/compiler-errors/samples/comment-unclosed/main.svelte similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/comment-unclosed/input.svelte rename to packages/svelte/tests/compiler-errors/samples/comment-unclosed/main.svelte diff --git a/packages/svelte/tests/compiler-errors/samples/css-global-without-selector/_config.js b/packages/svelte/tests/compiler-errors/samples/css-global-without-selector/_config.js index c8e598d4a8..549ad3ebe2 100644 --- a/packages/svelte/tests/compiler-errors/samples/css-global-without-selector/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/css-global-without-selector/_config.js @@ -2,8 +2,8 @@ import { test } from '../../test'; export default test({ error: { - code: 'css-syntax-error', - message: ':global() must contain a selector', - position: [9, 9] + code: 'invalid-css-global-selector', + message: ':global(...) must contain exactly one selector', + position: [16, 16] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/css-global-without-selector/input.svelte b/packages/svelte/tests/compiler-errors/samples/css-global-without-selector/main.svelte similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/css-global-without-selector/input.svelte rename to packages/svelte/tests/compiler-errors/samples/css-global-without-selector/main.svelte diff --git a/packages/svelte/tests/compiler-errors/samples/css/_config.js b/packages/svelte/tests/compiler-errors/samples/css/_config.js index d1a7e346f9..9705cde6b5 100644 --- a/packages/svelte/tests/compiler-errors/samples/css/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/css/_config.js @@ -2,8 +2,8 @@ import { test } from '../../test'; export default test({ error: { - code: 'css-syntax-error', - message: '"{" is expected', - position: [24, 24] + code: 'invalid-css-identifier', + message: 'Expected a valid CSS identifier', + position: [25, 25] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/css/input.svelte b/packages/svelte/tests/compiler-errors/samples/css/main.svelte similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/css/input.svelte rename to packages/svelte/tests/compiler-errors/samples/css/main.svelte diff --git a/packages/svelte/tests/compiler-errors/samples/dollar-binding-global-js/main.js b/packages/svelte/tests/compiler-errors/samples/dollar-binding-global-js/main.svelte.js similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/dollar-binding-global-js/main.js rename to packages/svelte/tests/compiler-errors/samples/dollar-binding-global-js/main.svelte.js diff --git a/packages/svelte/tests/compiler-errors/samples/else-before-closing-2/_config.js b/packages/svelte/tests/compiler-errors/samples/else-before-closing-2/_config.js index 7b1d43bf1d..dc9aff145c 100644 --- a/packages/svelte/tests/compiler-errors/samples/else-before-closing-2/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/else-before-closing-2/_config.js @@ -2,8 +2,8 @@ import { test } from '../../test'; export default test({ error: { - code: 'invalid-else-placement', - message: 'Expected to close {#await} block before seeing {:else} block', - position: [29, 29] + code: 'expected-token', + message: 'Expected token {:then ...} or {:catch ...}', + position: [24, 24] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/else-before-closing-2/input.svelte b/packages/svelte/tests/compiler-errors/samples/else-before-closing-2/main.svelte similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/else-before-closing-2/input.svelte rename to packages/svelte/tests/compiler-errors/samples/else-before-closing-2/main.svelte diff --git a/packages/svelte/tests/compiler-errors/samples/else-before-closing-3/_config.js b/packages/svelte/tests/compiler-errors/samples/else-before-closing-3/_config.js index ab7281cee5..80a2a136db 100644 --- a/packages/svelte/tests/compiler-errors/samples/else-before-closing-3/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/else-before-closing-3/_config.js @@ -2,8 +2,9 @@ import { test } from '../../test'; export default test({ error: { - code: 'invalid-else-placement', - message: 'Cannot have an {:else} block outside an {#if ...} or {#each ...} block', - position: [11, 11] + code: 'invalid-continuing-block-placement', + message: + '{:...} block is invalid at this position (did you forget to close the preceeding element or block?)', + position: [6, 6] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/else-before-closing-3/input.svelte b/packages/svelte/tests/compiler-errors/samples/else-before-closing-3/main.svelte similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/else-before-closing-3/input.svelte rename to packages/svelte/tests/compiler-errors/samples/else-before-closing-3/main.svelte diff --git a/packages/svelte/tests/compiler-errors/samples/else-before-closing/_config.js b/packages/svelte/tests/compiler-errors/samples/else-before-closing/_config.js index 31635f2124..87c1296f49 100644 --- a/packages/svelte/tests/compiler-errors/samples/else-before-closing/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/else-before-closing/_config.js @@ -2,8 +2,9 @@ import { test } from '../../test'; export default test({ error: { - code: 'invalid-else-placement', - message: 'Expected to close
  • tag before seeing {:else} block', - position: [23, 23] + code: 'invalid-continuing-block-placement', + message: + '{:...} block is invalid at this position (did you forget to close the preceeding element or block?)', + position: [18, 18] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/else-before-closing/input.svelte b/packages/svelte/tests/compiler-errors/samples/else-before-closing/main.svelte similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/else-before-closing/input.svelte rename to packages/svelte/tests/compiler-errors/samples/else-before-closing/main.svelte diff --git a/packages/svelte/tests/compiler-errors/samples/else-if-before-closing-2/_config.js b/packages/svelte/tests/compiler-errors/samples/else-if-before-closing-2/_config.js index 10ed037ede..4b4059cf3b 100644 --- a/packages/svelte/tests/compiler-errors/samples/else-if-before-closing-2/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/else-if-before-closing-2/_config.js @@ -2,8 +2,9 @@ import { test } from '../../test'; export default test({ error: { - code: 'invalid-elseif-placement', - message: 'Expected to close

    tag before seeing {:else if ...} block', - position: [25, 25] + code: 'invalid-continuing-block-placement', + message: + '{:...} block is invalid at this position (did you forget to close the preceeding element or block?)', + position: [17, 17] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/else-if-before-closing-2/input.svelte b/packages/svelte/tests/compiler-errors/samples/else-if-before-closing-2/main.svelte similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/else-if-before-closing-2/input.svelte rename to packages/svelte/tests/compiler-errors/samples/else-if-before-closing-2/main.svelte diff --git a/packages/svelte/tests/compiler-errors/samples/else-if-before-closing/_config.js b/packages/svelte/tests/compiler-errors/samples/else-if-before-closing/_config.js index 70823c9959..ae20d2da8c 100644 --- a/packages/svelte/tests/compiler-errors/samples/else-if-before-closing/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/else-if-before-closing/_config.js @@ -2,8 +2,8 @@ import { test } from '../../test'; export default test({ error: { - code: 'invalid-elseif-placement', - message: 'Expected to close {#await} block before seeing {:else if ...} block', - position: [34, 34] + code: 'expected-token', + message: 'Expected token {:then ...} or {:catch ...}', + position: [26, 26] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/else-if-before-closing/input.svelte b/packages/svelte/tests/compiler-errors/samples/else-if-before-closing/main.svelte similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/else-if-before-closing/input.svelte rename to packages/svelte/tests/compiler-errors/samples/else-if-before-closing/main.svelte diff --git a/packages/svelte/tests/compiler-errors/samples/else-if-without-if/_config.js b/packages/svelte/tests/compiler-errors/samples/else-if-without-if/_config.js index cb8e35c41d..04d8342f20 100644 --- a/packages/svelte/tests/compiler-errors/samples/else-if-without-if/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/else-if-without-if/_config.js @@ -2,8 +2,8 @@ import { test } from '../../test'; export default test({ error: { - code: 'invalid-elseif-placement', - message: 'Cannot have an {:else if ...} block outside an {#if ...} block', - position: [35, 35] + code: 'expected-token', + message: 'Expected token {:then ...} or {:catch ...}', + position: [27, 27] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/else-if-without-if/input.svelte b/packages/svelte/tests/compiler-errors/samples/else-if-without-if/main.svelte similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/else-if-without-if/input.svelte rename to packages/svelte/tests/compiler-errors/samples/else-if-without-if/main.svelte diff --git a/packages/svelte/tests/compiler-errors/samples/empty-attribute-shorthand/input.svelte b/packages/svelte/tests/compiler-errors/samples/empty-attribute-shorthand/main.svelte similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/empty-attribute-shorthand/input.svelte rename to packages/svelte/tests/compiler-errors/samples/empty-attribute-shorthand/main.svelte diff --git a/packages/svelte/tests/compiler-errors/samples/empty-classname-binding/_config.js b/packages/svelte/tests/compiler-errors/samples/empty-classname-binding/_config.js index 0051e827a5..bd1d1d7682 100644 --- a/packages/svelte/tests/compiler-errors/samples/empty-classname-binding/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/empty-classname-binding/_config.js @@ -3,7 +3,7 @@ import { test } from '../../test'; export default test({ error: { code: 'empty-directive-name', - message: 'Class name cannot be empty', + message: 'ClassDirective name cannot be empty', position: [10, 10] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/empty-classname-binding/input.svelte b/packages/svelte/tests/compiler-errors/samples/empty-classname-binding/main.svelte similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/empty-classname-binding/input.svelte rename to packages/svelte/tests/compiler-errors/samples/empty-classname-binding/main.svelte diff --git a/packages/svelte/tests/compiler-errors/samples/empty-directive-name/_config.js b/packages/svelte/tests/compiler-errors/samples/empty-directive-name/_config.js index 7f6d0f1d0f..48a0eb32c4 100644 --- a/packages/svelte/tests/compiler-errors/samples/empty-directive-name/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/empty-directive-name/_config.js @@ -3,7 +3,7 @@ import { test } from '../../test'; export default test({ error: { code: 'empty-directive-name', - message: 'Action name cannot be empty', + message: 'UseDirective name cannot be empty', position: [8, 8] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/empty-directive-name/input.svelte b/packages/svelte/tests/compiler-errors/samples/empty-directive-name/main.svelte similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/empty-directive-name/input.svelte rename to packages/svelte/tests/compiler-errors/samples/empty-directive-name/main.svelte diff --git a/packages/svelte/tests/compiler-errors/samples/export-derived-state/_config.js b/packages/svelte/tests/compiler-errors/samples/export-derived-state/_config.js index 801d1d8a30..1c171d19c0 100644 --- a/packages/svelte/tests/compiler-errors/samples/export-derived-state/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/export-derived-state/_config.js @@ -4,6 +4,6 @@ export default test({ error: { code: 'invalid-derived-export', message: 'Cannot export derived state', - position: process.platform === 'win32' ? [26, 68] : [24, 66] + position: [24, 66] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/export-state/_config.js b/packages/svelte/tests/compiler-errors/samples/export-state/_config.js index 755b891586..5ddb2a859a 100644 --- a/packages/svelte/tests/compiler-errors/samples/export-state/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/export-state/_config.js @@ -4,6 +4,6 @@ export default test({ error: { code: 'invalid-state-export', message: 'Cannot export state if it is reassigned', - position: process.platform === 'win32' ? [50, 90] : [46, 86] + position: [46, 86] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/illegal-expression/_config.js b/packages/svelte/tests/compiler-errors/samples/illegal-expression/_config.js index 659679c345..887f11e882 100644 --- a/packages/svelte/tests/compiler-errors/samples/illegal-expression/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/illegal-expression/_config.js @@ -2,7 +2,7 @@ import { test } from '../../test'; export default test({ error: { - code: 'parse-error', + code: 'js-parse-error', message: 'Assigning to rvalue', position: [1, 1] } diff --git a/packages/svelte/tests/compiler-errors/samples/illegal-expression/input.svelte b/packages/svelte/tests/compiler-errors/samples/illegal-expression/main.svelte similarity index 100% rename from packages/svelte/tests/compiler-errors/samples/illegal-expression/input.svelte rename to packages/svelte/tests/compiler-errors/samples/illegal-expression/main.svelte diff --git a/packages/svelte/tests/compiler-errors/samples/multiple-styles/_config.js b/packages/svelte/tests/compiler-errors/samples/multiple-styles/_config.js index da3e69fc1e..50cf2583af 100644 --- a/packages/svelte/tests/compiler-errors/samples/multiple-styles/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/multiple-styles/_config.js @@ -2,8 +2,8 @@ import { test } from '../../test'; export default test({ error: { - code: 'duplicate-style', - message: 'You can only have one top-level + +

    Broken

    diff --git a/packages/svelte/tests/parser-modern/samples/css-nth-syntax/output.json b/packages/svelte/tests/parser-modern/samples/css-nth-syntax/output.json new file mode 100644 index 0000000000..1cea48b17c --- /dev/null +++ b/packages/svelte/tests/parser-modern/samples/css-nth-syntax/output.json @@ -0,0 +1,520 @@ +{ + "css": { + "type": "Style", + "start": 0, + "end": 467, + "attributes": [], + "children": [ + { + "type": "Rule", + "prelude": { + "type": "SelectorList", + "start": 60, + "end": 80, + "children": [ + { + "type": "Selector", + "start": 60, + "end": 80, + "children": [ + { + "type": "TypeSelector", + "name": "h1", + "start": 60, + "end": 62 + }, + { + "type": "PseudoClassSelector", + "name": "nth-of-type", + "args": { + "type": "SelectorList", + "start": 75, + "end": 79, + "children": [ + { + "type": "Selector", + "start": 75, + "end": 79, + "children": [ + { + "type": "Nth", + "value": "2n+1", + "start": 75, + "end": 79 + } + ] + } + ] + }, + "start": 62, + "end": 80 + } + ] + } + ] + }, + "block": { + "type": "Block", + "start": 80, + "end": 112, + "children": [ + { + "type": "Declaration", + "start": 90, + "end": 105, + "property": "background", + "value": "red" + } + ] + }, + "start": 60, + "end": 112 + }, + { + "type": "Rule", + "prelude": { + "type": "SelectorList", + "start": 117, + "end": 153, + "children": [ + { + "type": "Selector", + "start": 117, + "end": 153, + "children": [ + { + "type": "TypeSelector", + "name": "h1", + "start": 117, + "end": 119 + }, + { + "type": "PseudoClassSelector", + "name": "nth-child", + "args": { + "type": "SelectorList", + "start": 130, + "end": 152, + "children": [ + { + "type": "Selector", + "start": 130, + "end": 152, + "children": [ + { + "type": "Nth", + "value": "-n + 3 of ", + "start": 130, + "end": 140 + }, + { + "type": "TypeSelector", + "name": "li", + "start": 140, + "end": 142 + }, + { + "type": "ClassSelector", + "name": "important", + "start": 142, + "end": 152 + } + ] + } + ] + }, + "start": 119, + "end": 153 + } + ] + } + ] + }, + "block": { + "type": "Block", + "start": 154, + "end": 186, + "children": [ + { + "type": "Declaration", + "start": 164, + "end": 179, + "property": "background", + "value": "red" + } + ] + }, + "start": 117, + "end": 186 + }, + { + "type": "Rule", + "prelude": { + "type": "SelectorList", + "start": 191, + "end": 206, + "children": [ + { + "type": "Selector", + "start": 191, + "end": 206, + "children": [ + { + "type": "TypeSelector", + "name": "h1", + "start": 191, + "end": 193 + }, + { + "type": "PseudoClassSelector", + "name": "nth-child", + "args": { + "type": "SelectorList", + "start": 204, + "end": 205, + "children": [ + { + "type": "Selector", + "start": 204, + "end": 205, + "children": [ + { + "type": "Nth", + "value": "1", + "start": 204, + "end": 205 + } + ] + } + ] + }, + "start": 193, + "end": 206 + } + ] + } + ] + }, + "block": { + "type": "Block", + "start": 207, + "end": 239, + "children": [ + { + "type": "Declaration", + "start": 217, + "end": 232, + "property": "background", + "value": "red" + } + ] + }, + "start": 191, + "end": 239 + }, + { + "type": "Rule", + "prelude": { + "type": "SelectorList", + "start": 244, + "end": 259, + "children": [ + { + "type": "Selector", + "start": 244, + "end": 259, + "children": [ + { + "type": "TypeSelector", + "name": "h1", + "start": 244, + "end": 246 + }, + { + "type": "PseudoClassSelector", + "name": "nth-child", + "args": { + "type": "SelectorList", + "start": 257, + "end": 258, + "children": [ + { + "type": "Selector", + "start": 257, + "end": 258, + "children": [ + { + "type": "TypeSelector", + "name": "p", + "start": 257, + "end": 258 + } + ] + } + ] + }, + "start": 246, + "end": 259 + } + ] + } + ] + }, + "block": { + "type": "Block", + "start": 260, + "end": 292, + "children": [ + { + "type": "Declaration", + "start": 270, + "end": 285, + "property": "background", + "value": "red" + } + ] + }, + "start": 244, + "end": 292 + }, + { + "type": "Rule", + "prelude": { + "type": "SelectorList", + "start": 297, + "end": 314, + "children": [ + { + "type": "Selector", + "start": 297, + "end": 314, + "children": [ + { + "type": "TypeSelector", + "name": "h1", + "start": 297, + "end": 299 + }, + { + "type": "PseudoClassSelector", + "name": "nth-child", + "args": { + "type": "SelectorList", + "start": 310, + "end": 313, + "children": [ + { + "type": "Selector", + "start": 310, + "end": 313, + "children": [ + { + "type": "Nth", + "value": "n+7", + "start": 310, + "end": 313 + } + ] + } + ] + }, + "start": 299, + "end": 314 + } + ] + } + ] + }, + "block": { + "type": "Block", + "start": 315, + "end": 347, + "children": [ + { + "type": "Declaration", + "start": 325, + "end": 340, + "property": "background", + "value": "red" + } + ] + }, + "start": 297, + "end": 347 + }, + { + "type": "Rule", + "prelude": { + "type": "SelectorList", + "start": 352, + "end": 370, + "children": [ + { + "type": "Selector", + "start": 352, + "end": 370, + "children": [ + { + "type": "TypeSelector", + "name": "h1", + "start": 352, + "end": 354 + }, + { + "type": "PseudoClassSelector", + "name": "nth-child", + "args": { + "type": "SelectorList", + "start": 365, + "end": 369, + "children": [ + { + "type": "Selector", + "start": 365, + "end": 369, + "children": [ + { + "type": "Nth", + "value": "even", + "start": 365, + "end": 369 + } + ] + } + ] + }, + "start": 354, + "end": 370 + } + ] + } + ] + }, + "block": { + "type": "Block", + "start": 371, + "end": 403, + "children": [ + { + "type": "Declaration", + "start": 381, + "end": 396, + "property": "background", + "value": "red" + } + ] + }, + "start": 352, + "end": 403 + }, + { + "type": "Rule", + "prelude": { + "type": "SelectorList", + "start": 408, + "end": 425, + "children": [ + { + "type": "Selector", + "start": 408, + "end": 425, + "children": [ + { + "type": "TypeSelector", + "name": "h1", + "start": 408, + "end": 410 + }, + { + "type": "PseudoClassSelector", + "name": "nth-child", + "args": { + "type": "SelectorList", + "start": 421, + "end": 424, + "children": [ + { + "type": "Selector", + "start": 421, + "end": 424, + "children": [ + { + "type": "Nth", + "value": "odd", + "start": 421, + "end": 424 + } + ] + } + ] + }, + "start": 410, + "end": 425 + } + ] + } + ] + }, + "block": { + "type": "Block", + "start": 426, + "end": 458, + "children": [ + { + "type": "Declaration", + "start": 436, + "end": 451, + "property": "background", + "value": "red" + } + ] + }, + "start": 408, + "end": 458 + } + ], + "content": { + "start": 7, + "end": 459, + "styles": "\n /* test that all these are parsed correctly */\n\th1:nth-of-type(2n+1){\n background: red;\n }\n h1:nth-child(-n + 3 of li.important) {\n background: red;\n }\n h1:nth-child(1) {\n background: red;\n }\n h1:nth-child(p) {\n background: red;\n }\n h1:nth-child(n+7) {\n background: red;\n }\n h1:nth-child(even) {\n background: red;\n }\n h1:nth-child(odd) {\n background: red;\n }\n" + } + }, + "js": [], + "start": 469, + "end": 484, + "type": "Root", + "fragment": { + "type": "Fragment", + "nodes": [ + { + "type": "Text", + "start": 467, + "end": 469, + "raw": "\n\n", + "data": "\n\n" + }, + { + "type": "RegularElement", + "start": 469, + "end": 484, + "name": "h1", + "attributes": [], + "fragment": { + "type": "Fragment", + "nodes": [ + { + "type": "Text", + "start": 473, + "end": 479, + "raw": "Broken", + "data": "Broken" + } + ], + "transparent": true + } + } + ], + "transparent": false + }, + "options": null +}