diff --git a/docs/README.md b/docs/README.md index 9bad2c5..9027d0c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -65,7 +65,7 @@ root.walkNumerics((node) => nodes.push(node)); // ... // }, // Numeric { -// value: '3s', +// value: '3', // type: 'numeric', // unit: 'pt', // ... diff --git a/lib/ValuesParser.js b/lib/ValuesParser.js index 82d9e5a..1542b00 100644 --- a/lib/ValuesParser.js +++ b/lib/ValuesParser.js @@ -148,6 +148,8 @@ module.exports = class ValuesParser extends Parser { if (Punctuation.chars.includes(type)) { Punctuation.fromTokens(tokens, this); + } else if (type === 'word' && Operator.test(tokens, this)) { + Operator.fromTokens(tokens, this); } else if (Func.test(tokens)) { Func.fromTokens(tokens, this); } else if (this.options.interpolation && Interpolation.test(tokens, this)) { diff --git a/lib/nodes/Operator.js b/lib/nodes/Operator.js index 2fac9af..5034ca6 100644 --- a/lib/nodes/Operator.js +++ b/lib/nodes/Operator.js @@ -14,6 +14,7 @@ const Node = require('./Node'); const operators = ['+', '-', '/', '*', '%', '=', '<=', '>=', '<', '>']; const operRegex = new RegExp(`([/|*}])`); +const compactRegex = /^[*/]\b/; class Operator extends Node { constructor(options) { @@ -33,6 +34,13 @@ class Operator extends Node { return operRegex; } + static test(tokens, parser) { + const [first] = tokens; + const [, value] = first; + const { lastNode } = parser; + return lastNode && lastNode.type === 'func' && compactRegex.test(value); + } + static tokenize(tokens, parser) { const [first, ...rest] = tokens; const [, value, startLine, , endLine, endChar] = first; diff --git a/lib/nodes/Quoted.js b/lib/nodes/Quoted.js index dbee524..f2a42c2 100644 --- a/lib/nodes/Quoted.js +++ b/lib/nodes/Quoted.js @@ -18,8 +18,13 @@ class Quoted extends Node { constructor(options) { super(options); this.type = 'quoted'; - this.contents = unquote(options.value); - [this.quote] = options.value; + /** + * When cloning the node via {@link Node.clone()} there are no constructor params + */ + if (options && options.value) { + this.contents = unquote(options.value); + [this.quote] = options.value; + } } static fromTokens(tokens, parser) { diff --git a/package-lock.json b/package-lock.json index 42eb981..4573062 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "postcss-values-parser", - "version": "6.0.1", + "version": "6.0.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index af42abf..d4cf7d9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-values-parser", - "version": "6.0.1", + "version": "6.0.2", "description": "A CSS property value parser for use with PostCSS", "license": "MPL-2.0", "repository": "shellscape/postcss-values-parser", diff --git a/test/fixtures/func.js b/test/fixtures/func.js index c58e3bf..562b243 100644 --- a/test/fixtures/func.js +++ b/test/fixtures/func.js @@ -29,8 +29,10 @@ module.exports = { 'lCH(40% 68.8 34.5 / 50%)', 'hwb(90deg 0% 0% / 0.5)', 'calc(-0.5 * var(foo))', + 'calc(var(--foo)*var(--bar))', 'calc(1px + -2vw - 4px)', 'calc(((768px - 100vw) / 2) - 15px)', + 'calc(((768px - 100vw)/2) - 15px)', 'bar(baz(black, 10%), 10%)', '-webkit-linear-gradient(0)', 'var(--foo)', diff --git a/test/quoted.test.js b/test/quoted.test.js new file mode 100644 index 0000000..1dc810a --- /dev/null +++ b/test/quoted.test.js @@ -0,0 +1,57 @@ +/* + Copyright © 2018 Andrew Powell + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of this Source Code Form. +*/ +const test = require('ava'); + +const { nodeToString, parse } = require('../lib'); + +const { snapshot, throws } = require('./fixtures/quoted'); + +for (const fixture of snapshot) { + test(fixture, (t) => { + const root = parse(fixture); + const nodes = root.nodes.map((node) => { + delete node.parent; // eslint-disable-line no-param-reassign + return node; + }); + const string = nodeToString(root); + + t.is(string, fixture); + t.is(fixture, root.toString()); + t.snapshot(root.first.toString()); + t.snapshot(string); + t.snapshot(nodes); + + root.clone(); + }); + + test(`${fixture} be should cloned`, (t) => { + const root = parse(fixture); + const nodes = root.nodes.map((node) => { + delete node.parent; // eslint-disable-line no-param-reassign + return node; + }); + const string = nodeToString(root); + + const cloned = root.clone(); + + t.is(string, fixture); + t.is(fixture, root.toString()); + t.snapshot(cloned.first.toString()); + t.snapshot(string); + t.snapshot(nodes); + }); +} + +for (const fixture of throws) { + test(fixture, (t) => { + t.throws(() => parse(fixture)); + }); +} diff --git a/test/snapshots/func.test.js.md b/test/snapshots/func.test.js.md index 4591cb5..ec7a017 100644 --- a/test/snapshots/func.test.js.md +++ b/test/snapshots/func.test.js.md @@ -5114,3 +5114,1372 @@ Generated by [AVA](https://avajs.dev). [Symbol(isClean)]: false, }, ] + +## calc(-0.5*var(foo)) + +> Snapshot 1 + + 'calc(-0.5*var(foo))' + +> Snapshot 2 + + 'calc(-0.5*var(foo))' + +> Snapshot 3 + + [ + Func { + isColor: false, + isVar: false, + name: 'calc', + nodes: [ + Numeric { + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '-0.5*var(foo)', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'numeric', + unit: '', + value: '-0.5', + [Symbol(isClean)]: false, + }, + Operator { + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '-0.5*var(foo)', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'operator', + value: '*', + [Symbol(isClean)]: false, + }, + Func { + isColor: false, + isVar: false, + name: 'var', + nodes: [ + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: false, + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: 'foo', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'word', + value: 'foo', + [Symbol(isClean)]: false, + }, + ], + params: '(foo)', + parent: [Circular], + raws: { + after: '', + before: '', + semicolon: false, + }, + source: { + end: { + column: 9, + line: 1, + offset: 8, + }, + input: Input { + css: '-0.5*var(foo)', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'func', + [Symbol(isClean)]: false, + }, + ], + params: '(-0.5*var(foo))', + raws: { + after: '', + before: '', + semicolon: false, + }, + source: { + end: { + column: 19, + line: 1, + offset: 18, + }, + input: Input { + css: 'calc(-0.5*var(foo))', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'func', + [Symbol(isClean)]: false, + }, + ] + +## calc(var(--foo)) + +> Snapshot 1 + + 'calc(var(--foo))' + +> Snapshot 2 + + 'calc(var(--foo))' + +> Snapshot 3 + + [ + Func { + isColor: false, + isVar: false, + name: 'calc', + nodes: [ + Func { + isColor: false, + isVar: true, + name: 'var', + nodes: [ + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: true, + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '--foo', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'word', + value: '--foo', + [Symbol(isClean)]: false, + }, + ], + params: '(--foo)', + parent: [Circular], + raws: { + after: '', + before: '', + semicolon: false, + }, + source: { + end: { + column: 4, + line: 1, + offset: 3, + }, + input: Input { + css: 'var(--foo)', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'func', + [Symbol(isClean)]: false, + }, + ], + params: '(var(--foo))', + raws: { + after: '', + before: '', + semicolon: false, + }, + source: { + end: { + column: 16, + line: 1, + offset: 15, + }, + input: Input { + css: 'calc(var(--foo))', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'func', + [Symbol(isClean)]: false, + }, + ] + +## calc(var(--foo) * var(--bar)) + +> Snapshot 1 + + 'calc(var(--foo) * var(--bar))' + +> Snapshot 2 + + 'calc(var(--foo) * var(--bar))' + +> Snapshot 3 + + [ + Func { + isColor: false, + isVar: false, + name: 'calc', + nodes: [ + Func { + isColor: false, + isVar: true, + name: 'var', + nodes: [ + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: true, + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '--foo', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'word', + value: '--foo', + [Symbol(isClean)]: false, + }, + ], + params: '(--foo)', + parent: [Circular], + raws: { + after: '', + before: '', + semicolon: false, + }, + source: { + end: { + column: 4, + line: 1, + offset: 3, + }, + input: Input { + css: 'var(--foo) * var(--bar)', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'func', + [Symbol(isClean)]: false, + }, + Operator { + parent: [Circular], + raws: { + after: '', + before: ' ', + }, + source: { + end: { + column: 12, + line: 1, + offset: 11, + }, + input: Input { + css: 'var(--foo) * var(--bar)', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 12, + line: 1, + offset: 11, + }, + }, + type: 'operator', + value: '*', + [Symbol(isClean)]: false, + }, + Func { + isColor: false, + isVar: true, + name: 'var', + nodes: [ + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: true, + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '--bar', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'word', + value: '--bar', + [Symbol(isClean)]: false, + }, + ], + params: '(--bar)', + parent: [Circular], + raws: { + after: '', + before: ' ', + semicolon: false, + }, + source: { + end: { + column: 17, + line: 1, + offset: 16, + }, + input: Input { + css: 'var(--foo) * var(--bar)', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 14, + line: 1, + offset: 13, + }, + }, + type: 'func', + [Symbol(isClean)]: false, + }, + ], + params: '(var(--foo) * var(--bar))', + raws: { + after: '', + before: '', + semicolon: false, + }, + source: { + end: { + column: 29, + line: 1, + offset: 28, + }, + input: Input { + css: 'calc(var(--foo) * var(--bar))', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'func', + [Symbol(isClean)]: false, + }, + ] + +## calc(var(--foo)* var(--bar)) + +> Snapshot 1 + + 'calc(var(--foo)* var(--bar))' + +> Snapshot 2 + + 'calc(var(--foo)* var(--bar))' + +> Snapshot 3 + + [ + Func { + isColor: false, + isVar: false, + name: 'calc', + nodes: [ + Func { + isColor: false, + isVar: true, + name: 'var', + nodes: [ + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: true, + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '--foo', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'word', + value: '--foo', + [Symbol(isClean)]: false, + }, + ], + params: '(--foo)', + parent: [Circular], + raws: { + after: '', + before: '', + semicolon: false, + }, + source: { + end: { + column: 4, + line: 1, + offset: 3, + }, + input: Input { + css: 'var(--foo)* var(--bar)', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'func', + [Symbol(isClean)]: false, + }, + Operator { + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 11, + line: 1, + offset: 10, + }, + input: Input { + css: 'var(--foo)* var(--bar)', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 11, + line: 1, + offset: 10, + }, + }, + type: 'operator', + value: '*', + [Symbol(isClean)]: false, + }, + Func { + isColor: false, + isVar: true, + name: 'var', + nodes: [ + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: true, + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '--bar', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'word', + value: '--bar', + [Symbol(isClean)]: false, + }, + ], + params: '(--bar)', + parent: [Circular], + raws: { + after: '', + before: ' ', + semicolon: false, + }, + source: { + end: { + column: 16, + line: 1, + offset: 15, + }, + input: Input { + css: 'var(--foo)* var(--bar)', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 13, + line: 1, + offset: 12, + }, + }, + type: 'func', + [Symbol(isClean)]: false, + }, + ], + params: '(var(--foo)* var(--bar))', + raws: { + after: '', + before: '', + semicolon: false, + }, + source: { + end: { + column: 28, + line: 1, + offset: 27, + }, + input: Input { + css: 'calc(var(--foo)* var(--bar))', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'func', + [Symbol(isClean)]: false, + }, + ] + +## calc(var(--foo)*var(--bar)) + +> Snapshot 1 + + 'calc(var(--foo)*var(--bar))' + +> Snapshot 2 + + 'calc(var(--foo)*var(--bar))' + +> Snapshot 3 + + [ + Func { + isColor: false, + isVar: false, + name: 'calc', + nodes: [ + Func { + isColor: false, + isVar: true, + name: 'var', + nodes: [ + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: true, + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '--foo', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'word', + value: '--foo', + [Symbol(isClean)]: false, + }, + ], + params: '(--foo)', + parent: [Circular], + raws: { + after: '', + before: '', + semicolon: false, + }, + source: { + end: { + column: 4, + line: 1, + offset: 3, + }, + input: Input { + css: 'var(--foo)*var(--bar)', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'func', + [Symbol(isClean)]: false, + }, + Operator { + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 11, + line: 1, + offset: 10, + }, + input: Input { + css: 'var(--foo)*var(--bar)', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 11, + line: 1, + offset: 10, + }, + }, + type: 'operator', + value: '*var', + [Symbol(isClean)]: false, + }, + Punctuation { + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 15, + line: 1, + offset: 14, + }, + input: Input { + css: 'var(--foo)*var(--bar)', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 15, + line: 1, + offset: 14, + }, + }, + type: 'punctuation', + value: '(', + [Symbol(isClean)]: false, + }, + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: true, + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: 'var(--foo)*var(--bar)', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'word', + value: '--bar', + [Symbol(isClean)]: false, + }, + Punctuation { + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 15, + line: 1, + offset: 14, + }, + input: Input { + css: 'var(--foo)*var(--bar)', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 15, + line: 1, + offset: 14, + }, + }, + type: 'punctuation', + value: ')', + [Symbol(isClean)]: false, + }, + ], + params: '(var(--foo)*var(--bar))', + raws: { + after: '', + before: '', + semicolon: false, + }, + source: { + end: { + column: 27, + line: 1, + offset: 26, + }, + input: Input { + css: 'calc(var(--foo)*var(--bar))', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'func', + [Symbol(isClean)]: false, + }, + ] + +## calc(((768px - 100vw)/2) - 15px) + +> Snapshot 1 + + 'calc(((768px - 100vw)/2) - 15px)' + +> Snapshot 2 + + 'calc(((768px - 100vw)/2) - 15px)' + +> Snapshot 3 + + [ + Func { + isColor: false, + isVar: false, + name: 'calc', + nodes: [ + Punctuation { + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '((768px - 100vw)/2) - 15px', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'punctuation', + value: '(', + [Symbol(isClean)]: false, + }, + Punctuation { + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 2, + line: 1, + offset: 1, + }, + input: Input { + css: '((768px - 100vw)/2) - 15px', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 2, + line: 1, + offset: 1, + }, + }, + type: 'punctuation', + value: '(', + [Symbol(isClean)]: false, + }, + Numeric { + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '((768px - 100vw)/2) - 15px', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'numeric', + unit: 'px', + value: '768', + [Symbol(isClean)]: false, + }, + Operator { + parent: [Circular], + raws: { + after: '', + before: ' ', + }, + source: { + end: { + column: 7, + line: 1, + offset: 6, + }, + input: Input { + css: '((768px - 100vw)/2) - 15px', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 7, + line: 1, + offset: 6, + }, + }, + type: 'operator', + value: '-', + [Symbol(isClean)]: false, + }, + Numeric { + parent: [Circular], + raws: { + after: '', + before: ' ', + }, + source: { + end: { + column: 9, + line: 1, + offset: 8, + }, + input: Input { + css: '((768px - 100vw)/2) - 15px', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 9, + line: 1, + offset: 8, + }, + }, + type: 'numeric', + unit: 'vw', + value: '100', + [Symbol(isClean)]: false, + }, + Punctuation { + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 2, + line: 1, + offset: 1, + }, + input: Input { + css: '((768px - 100vw)/2) - 15px', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 2, + line: 1, + offset: 1, + }, + }, + type: 'punctuation', + value: ')', + [Symbol(isClean)]: false, + }, + Operator { + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 17, + line: 1, + offset: 16, + }, + input: Input { + css: '((768px - 100vw)/2) - 15px', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 17, + line: 1, + offset: 16, + }, + }, + type: 'operator', + value: '/', + [Symbol(isClean)]: false, + }, + Numeric { + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 17, + line: 1, + offset: 16, + }, + input: Input { + css: '((768px - 100vw)/2) - 15px', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 17, + line: 1, + offset: 16, + }, + }, + type: 'numeric', + unit: '', + value: '2', + [Symbol(isClean)]: false, + }, + Punctuation { + parent: [Circular], + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 19, + line: 1, + offset: 18, + }, + input: Input { + css: '((768px - 100vw)/2) - 15px', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 19, + line: 1, + offset: 18, + }, + }, + type: 'punctuation', + value: ')', + [Symbol(isClean)]: false, + }, + Operator { + parent: [Circular], + raws: { + after: '', + before: ' ', + }, + source: { + end: { + column: 21, + line: 1, + offset: 20, + }, + input: Input { + css: '((768px - 100vw)/2) - 15px', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 21, + line: 1, + offset: 20, + }, + }, + type: 'operator', + value: '-', + [Symbol(isClean)]: false, + }, + Numeric { + parent: [Circular], + raws: { + after: '', + before: ' ', + }, + source: { + end: { + column: 23, + line: 1, + offset: 22, + }, + input: Input { + css: '((768px - 100vw)/2) - 15px', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 23, + line: 1, + offset: 22, + }, + }, + type: 'numeric', + unit: 'px', + value: '15', + [Symbol(isClean)]: false, + }, + ], + params: '(((768px - 100vw)/2) - 15px)', + raws: { + after: '', + before: '', + semicolon: false, + }, + source: { + end: { + column: 32, + line: 1, + offset: 31, + }, + input: Input { + css: 'calc(((768px - 100vw)/2) - 15px)', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'func', + [Symbol(isClean)]: false, + }, + ] diff --git a/test/snapshots/func.test.js.snap b/test/snapshots/func.test.js.snap index 610dc5c..774c50b 100644 Binary files a/test/snapshots/func.test.js.snap and b/test/snapshots/func.test.js.snap differ diff --git a/test/snapshots/quoted.test.js.md b/test/snapshots/quoted.test.js.md new file mode 100644 index 0000000..4b3f561 --- /dev/null +++ b/test/snapshots/quoted.test.js.md @@ -0,0 +1,1445 @@ +# Snapshot report for `test/quoted.test.js` + +The actual snapshot is saved in `quoted.test.js.snap`. + +Generated by [AVA](https://avajs.dev). + +## "string" + +> Snapshot 1 + + '"string"' + +> Snapshot 2 + + ' "string" ' + +> Snapshot 3 + + [ + Quoted { + contents: 'string', + quote: '"', + raws: { + after: '', + before: ' ', + }, + source: { + end: { + column: 2, + line: 1, + offset: 1, + }, + input: Input { + css: ' "string" ', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 2, + line: 1, + offset: 1, + }, + }, + type: 'quoted', + value: '"string"', + [Symbol(isClean)]: false, + }, + ] + +## "" + +> Snapshot 1 + + '""' + +> Snapshot 2 + + '""' + +> Snapshot 3 + + [ + Quoted { + contents: '', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '""', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '""', + [Symbol(isClean)]: false, + }, + ] + +## "string" + +> Snapshot 1 + + '"string"' + +> Snapshot 2 + + '"string"' + +> Snapshot 3 + + [ + Quoted { + contents: 'string', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '"string"', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '"string"', + [Symbol(isClean)]: false, + }, + ] + +## "word'word" + +> Snapshot 1 + + '"word\'word"' + +> Snapshot 2 + + '"word\'word"' + +> Snapshot 3 + + [ + Quoted { + contents: 'word\'word', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '"word\'word"', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '"word\'word"', + [Symbol(isClean)]: false, + }, + ] + +## "word\"word" + +> Snapshot 1 + + '"word\\"word"' + +> Snapshot 2 + + '"word\\"word"' + +> Snapshot 3 + + [ + Quoted { + contents: 'word"word', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '"word\\"word"', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '"word\\"word"', + [Symbol(isClean)]: false, + }, + ] + +## '' + +> Snapshot 1 + + '\'\'' + +> Snapshot 2 + + '\'\'' + +> Snapshot 3 + + [ + Quoted { + contents: '', + quote: '\'', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '\'\'', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '\'\'', + [Symbol(isClean)]: false, + }, + ] + +## 'word"word' + +> Snapshot 1 + + '\'word"word\'' + +> Snapshot 2 + + '\'word"word\'' + +> Snapshot 3 + + [ + Quoted { + contents: 'word"word', + quote: '\'', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '\'word"word\'', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '\'word"word\'', + [Symbol(isClean)]: false, + }, + ] + +## 'word\'word' + +> Snapshot 1 + + '\'word\\\'word\'' + +> Snapshot 2 + + '\'word\\\'word\'' + +> Snapshot 3 + + [ + Quoted { + contents: 'word\'word', + quote: '\'', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '\'word\\\'word\'', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '\'word\\\'word\'', + [Symbol(isClean)]: false, + }, + ] + +## word1"string"word2 + +> Snapshot 1 + + 'word1' + +> Snapshot 2 + + 'word1"string"word2' + +> Snapshot 3 + + [ + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: false, + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: 'word1"string"word2', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'word', + value: 'word1', + [Symbol(isClean)]: false, + }, + Quoted { + contents: 'string', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 6, + line: 1, + offset: 5, + }, + input: Input { + css: 'word1"string"word2', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 6, + line: 1, + offset: 5, + }, + }, + type: 'quoted', + value: '"string"', + [Symbol(isClean)]: false, + }, + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: false, + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 14, + line: 1, + offset: 13, + }, + input: Input { + css: 'word1"string"word2', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 14, + line: 1, + offset: 13, + }, + }, + type: 'word', + value: 'word2', + [Symbol(isClean)]: false, + }, + ] + +## should clone "string" + +> Snapshot 1 + + '"string"' + +> Snapshot 2 + + ' "string" ' + +> Snapshot 3 + + [ + Quoted { + contents: 'string', + quote: '"', + raws: { + after: '', + before: ' ', + }, + source: { + end: { + column: 2, + line: 1, + offset: 1, + }, + input: Input { + css: ' "string" ', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 2, + line: 1, + offset: 1, + }, + }, + type: 'quoted', + value: '"string"', + [Symbol(isClean)]: false, + }, + ] + +## should clone "" + +> Snapshot 1 + + '""' + +> Snapshot 2 + + '""' + +> Snapshot 3 + + [ + Quoted { + contents: '', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '""', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '""', + [Symbol(isClean)]: false, + }, + ] + +## should clone "string" + +> Snapshot 1 + + '"string"' + +> Snapshot 2 + + '"string"' + +> Snapshot 3 + + [ + Quoted { + contents: 'string', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '"string"', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '"string"', + [Symbol(isClean)]: false, + }, + ] + +## should clone "word'word" + +> Snapshot 1 + + '"word\'word"' + +> Snapshot 2 + + '"word\'word"' + +> Snapshot 3 + + [ + Quoted { + contents: 'word\'word', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '"word\'word"', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '"word\'word"', + [Symbol(isClean)]: false, + }, + ] + +## should clone "word\"word" + +> Snapshot 1 + + '"word\\"word"' + +> Snapshot 2 + + '"word\\"word"' + +> Snapshot 3 + + [ + Quoted { + contents: 'word"word', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '"word\\"word"', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '"word\\"word"', + [Symbol(isClean)]: false, + }, + ] + +## should clone '' + +> Snapshot 1 + + '\'\'' + +> Snapshot 2 + + '\'\'' + +> Snapshot 3 + + [ + Quoted { + contents: '', + quote: '\'', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '\'\'', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '\'\'', + [Symbol(isClean)]: false, + }, + ] + +## should clone 'word"word' + +> Snapshot 1 + + '\'word"word\'' + +> Snapshot 2 + + '\'word"word\'' + +> Snapshot 3 + + [ + Quoted { + contents: 'word"word', + quote: '\'', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '\'word"word\'', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '\'word"word\'', + [Symbol(isClean)]: false, + }, + ] + +## should clone 'word\'word' + +> Snapshot 1 + + '\'word\\\'word\'' + +> Snapshot 2 + + '\'word\\\'word\'' + +> Snapshot 3 + + [ + Quoted { + contents: 'word\'word', + quote: '\'', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '\'word\\\'word\'', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '\'word\\\'word\'', + [Symbol(isClean)]: false, + }, + ] + +## should clone word1"string"word2 + +> Snapshot 1 + + 'word1' + +> Snapshot 2 + + 'word1"string"word2' + +> Snapshot 3 + + [ + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: false, + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: 'word1"string"word2', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'word', + value: 'word1', + [Symbol(isClean)]: false, + }, + Quoted { + contents: 'string', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 6, + line: 1, + offset: 5, + }, + input: Input { + css: 'word1"string"word2', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 6, + line: 1, + offset: 5, + }, + }, + type: 'quoted', + value: '"string"', + [Symbol(isClean)]: false, + }, + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: false, + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 14, + line: 1, + offset: 13, + }, + input: Input { + css: 'word1"string"word2', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 14, + line: 1, + offset: 13, + }, + }, + type: 'word', + value: 'word2', + [Symbol(isClean)]: false, + }, + ] + +## "string" be should cloned + +> Snapshot 1 + + '"string"' + +> Snapshot 2 + + ' "string" ' + +> Snapshot 3 + + [ + Quoted { + contents: 'string', + quote: '"', + raws: { + after: '', + before: ' ', + }, + source: { + end: { + column: 2, + line: 1, + offset: 1, + }, + input: Input { + css: ' "string" ', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 2, + line: 1, + offset: 1, + }, + }, + type: 'quoted', + value: '"string"', + [Symbol(isClean)]: false, + }, + ] + +## "" be should cloned + +> Snapshot 1 + + '""' + +> Snapshot 2 + + '""' + +> Snapshot 3 + + [ + Quoted { + contents: '', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '""', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '""', + [Symbol(isClean)]: false, + }, + ] + +## "string" be should cloned + +> Snapshot 1 + + '"string"' + +> Snapshot 2 + + '"string"' + +> Snapshot 3 + + [ + Quoted { + contents: 'string', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '"string"', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '"string"', + [Symbol(isClean)]: false, + }, + ] + +## "word'word" be should cloned + +> Snapshot 1 + + '"word\'word"' + +> Snapshot 2 + + '"word\'word"' + +> Snapshot 3 + + [ + Quoted { + contents: 'word\'word', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '"word\'word"', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '"word\'word"', + [Symbol(isClean)]: false, + }, + ] + +## "word\"word" be should cloned + +> Snapshot 1 + + '"word\\"word"' + +> Snapshot 2 + + '"word\\"word"' + +> Snapshot 3 + + [ + Quoted { + contents: 'word"word', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '"word\\"word"', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '"word\\"word"', + [Symbol(isClean)]: false, + }, + ] + +## '' be should cloned + +> Snapshot 1 + + '\'\'' + +> Snapshot 2 + + '\'\'' + +> Snapshot 3 + + [ + Quoted { + contents: '', + quote: '\'', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '\'\'', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '\'\'', + [Symbol(isClean)]: false, + }, + ] + +## 'word"word' be should cloned + +> Snapshot 1 + + '\'word"word\'' + +> Snapshot 2 + + '\'word"word\'' + +> Snapshot 3 + + [ + Quoted { + contents: 'word"word', + quote: '\'', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '\'word"word\'', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '\'word"word\'', + [Symbol(isClean)]: false, + }, + ] + +## 'word\'word' be should cloned + +> Snapshot 1 + + '\'word\\\'word\'' + +> Snapshot 2 + + '\'word\\\'word\'' + +> Snapshot 3 + + [ + Quoted { + contents: 'word\'word', + quote: '\'', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: '\'word\\\'word\'', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'quoted', + value: '\'word\\\'word\'', + [Symbol(isClean)]: false, + }, + ] + +## word1"string"word2 be should cloned + +> Snapshot 1 + + 'word1' + +> Snapshot 2 + + 'word1"string"word2' + +> Snapshot 3 + + [ + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: false, + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 1, + line: 1, + offset: 0, + }, + input: Input { + css: 'word1"string"word2', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 1, + line: 1, + offset: 0, + }, + }, + type: 'word', + value: 'word1', + [Symbol(isClean)]: false, + }, + Quoted { + contents: 'string', + quote: '"', + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 6, + line: 1, + offset: 5, + }, + input: Input { + css: 'word1"string"word2', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 6, + line: 1, + offset: 5, + }, + }, + type: 'quoted', + value: '"string"', + [Symbol(isClean)]: false, + }, + Word { + isColor: false, + isHex: false, + isUrl: false, + isVariable: false, + raws: { + after: '', + before: '', + }, + source: { + end: { + column: 14, + line: 1, + offset: 13, + }, + input: Input { + css: 'word1"string"word2', + hasBOM: false, + id: '', + [Symbol(fromOffset cache)]: [ + 0, + ], + }, + start: { + column: 14, + line: 1, + offset: 13, + }, + }, + type: 'word', + value: 'word2', + [Symbol(isClean)]: false, + }, + ] diff --git a/test/snapshots/quoted.test.js.snap b/test/snapshots/quoted.test.js.snap new file mode 100644 index 0000000..0fa3324 Binary files /dev/null and b/test/snapshots/quoted.test.js.snap differ