From a59fac96dde7fdbdd3b7455357b9bf6c95dc7108 Mon Sep 17 00:00:00 2001
From: Marco Pasqualetti
Date: Fri, 7 Jan 2022 05:39:56 +0100
Subject: [PATCH 1/8] =?UTF-8?q?fix:=20Quoted=20=E2=80=93=20clone=20throw?=
=?UTF-8?q?=20an=20error=20(#141)=20(#142)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- add missing `quoted.test.js` file (fixtures were already present)
---
lib/nodes/Quoted.js | 9 +-
test/quoted.test.js | 57 ++
test/snapshots/quoted.test.js.md | 1445 ++++++++++++++++++++++++++++
test/snapshots/quoted.test.js.snap | Bin 0 -> 2692 bytes
4 files changed, 1509 insertions(+), 2 deletions(-)
create mode 100644 test/quoted.test.js
create mode 100644 test/snapshots/quoted.test.js.md
create mode 100644 test/snapshots/quoted.test.js.snap
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/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/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 0000000000000000000000000000000000000000..0fa332483ff2f1ee362e247437eb15f808210c5f
GIT binary patch
literal 2692
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
literal 0
HcmV?d00001
From b143c3acb44df30629aa6f0e1b83a9f18db63cc6 Mon Sep 17 00:00:00 2001
From: Chen Yangjian <252317+cyjake@users.noreply.github.com>
Date: Fri, 7 Jan 2022 12:40:38 +0800
Subject: [PATCH 2/8] fix: support parsing */ expressions without surrounding
spaces (#144)
fixes #138
---
lib/ValuesParser.js | 2 +
lib/nodes/Operator.js | 8 +
test/fixtures/func.js | 2 +
test/snapshots/func.test.js.md | 1369 ++++++++++++++++++++++++++++++
test/snapshots/func.test.js.snap | Bin 18083 -> 23760 bytes
5 files changed, 1381 insertions(+)
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/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/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 610dc5caf0da5ca739ff06b31cadae48e1e2c22f..774c50bec85106c7c21b714f7dcf713a128e165f 100644
GIT binary patch
literal 23760
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
Vg73fSS!~?lB&|;bG;QGG{6C&vy%zug
literal 18083
zcmYg$WmH{3&o1uL;!bgggHxcmYjKBzQ{3I%-HW>xD{cpOcXxN~!7uOo-EZByf6SVd
zWY3;GnaLziBCIa_O~uyG-pRtw`I{>n5)_0gB{AuVZN3bvtqZz&62%i~6avJ5ALxs0
zcyBDVr4Mr**ChF?{LpEPZ)5>Ki)B;vlPltbAp+uqDOHssp=7?sldDCN55Rx2-&2$8ssni;5!^MBR%DL|A389#rR%+)Dm~)t7GNR>coy_WouKeWce#mf#K^3Qb=iECZmJmx`S-^97a$WNrXZ=rP&q_XaVfpbk
z6p?r5SU7=!{D?4*bL41M@%`bEM)G%etIKU_vW9c7QcWn%u6R@PeoO9_fg|srU&qxS
z?Gzf0j`t_J?1Qp!Ne1KwUI*O;QB%v}s#bnFuY-9BQG?@^pEN{oa{B?p8Tu_BinjbM
z9+%M$w*&IOWxU^BB(m)}TAD+e$kmj;Gc(9n#%N{}@cpxG*#B{nb6kTNE5O92Z=%OF
zlpS@f-aS?k=hX=)c@3`K<9eJylw^q%JJ8f*&Do>2Y306(K}Q#~;Bi}Qeb?#cE5eK=
z!DywMwc#34OHcJYSZCm#+Pto5^HkZc|MmHsv<#22)J}+JYwP_A#_qI5BND
z<+$Xc!svvo@GR6BqNY@>{MymKL5mpNf&cHeTD@N=k+^evy8U-rIaPznQE{YDwWH
z%)0Qld1V-K>77Xv-~2kl8?>cbZf27RN1|T`9*kIUV{?Q%4lZ;OYl^&Y?R7Xfs!|~0
zyIqYSi|Vf0{0Ekm{ZvT=xs}-A35V`c&7v>in|S|5tIL#u0r+2f^XI5Gj{c+YdW^<_fF$W^(#EiZn!>w7Xipy^lPo8W+b~q?ZB?AH(LdIN&ga+>~<6*mv53
zYTKQ=LxRaZ^TBEw^kXx8(!YG!dekS#+4lFbQqIW8grSx#W8JUU_Xl)#X`6!7WoySY
zu#mlHJ&?EEvxfp@c-77l-vb*nNS2ro04pHARvYcvhuM{D%o^ta#?~BC!QL8>SLy
zT&aj}xMSaxX^1vxZ!@IksNCVo{pPK||FP+28N}~)_f*37%eMcUCKWqet=7^o30l*8v-Eg5WJo;;F7y)j#lUZp
z?~{K%pQ33p_rpo#`X+D}(clF2xkRw!?c%*?zgl)|niP57=d7Ic-%FGW2kuIDHHJv#
zu}&D-o?AkH3$VNBovqpMZV+tUc3M&Wv71AbJc_W!czXOB`n$1U@W<8(_m+G(Uh?Bx
zaVt0$T(~4QZqBIM8E$3py6RP>IJVUiGUnt>ayj>@&uTGcv69#F9W-Lkc1aPVQpI{J
zrY%*+jlufQ?X^ap8~*Al*+*PSii^$OJP