From c61bb4bb2c9aa90a38a7c6ffd33246610c7d5ea4 Mon Sep 17 00:00:00 2001 From: Bart Veneman Date: Sun, 2 Jun 2024 20:27:35 +0200 Subject: [PATCH 1/4] rm unneeded lines for multiline values --- .github/workflows/test.yml | 2 +- index.js | 17 +++-------------- package.json | 4 ++-- test/selectors.test.js | 12 ++++++++++++ test/values.test.js | 6 ++++++ 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fd5f719..06c5cf9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,7 +22,7 @@ jobs: - name: Install dependencies run: npm install --ignore-scripts --no-audit --no-fund - name: Unit tests - run: npx c8 --reporter=lcov npm test + run: npm test - name: Check types run: npm run check - name: Lint JS diff --git a/index.js b/index.js index 73f5836..399f9aa 100644 --- a/index.js +++ b/index.js @@ -48,15 +48,7 @@ function substr(node, css) { let start = loc.start let end = loc.end - let str = css.substring(start.offset, end.offset) - - // Single-line node, most common case - if (start.line === end.line) { - return str - } - - // Multi-line nodes, less common - return str.replace(/\s+/g, SPACE) + return css.substring(start.offset, end.offset) } /** @@ -126,12 +118,9 @@ function print_selectorlist(node, css, indent_level) { */ function print_simple_selector(node, css) { let buffer = EMPTY_STRING + let children = node.children || [] - if (!node.children) { - return buffer - } - - node.children.forEach((child) => { + children.forEach((child) => { switch (child.type) { case 'Combinator': { // putting spaces around `child.name` (+ > ~ or ' '), unless the combinator is ' ' diff --git a/package.json b/package.json index 0c6af41..04a5a14 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "unpkg": "./dist/format-css.umd.cjs", "scripts": { "build": "vite build", - "test": "uvu", + "test": "c8 --reporter=lcov uvu", "check": "tsc", "lint": "oxlint -D perf" }, @@ -45,4 +45,4 @@ "pretty", "prettier" ] -} +} \ No newline at end of file diff --git a/test/selectors.test.js b/test/selectors.test.js index 37c30f0..62d2dab 100644 --- a/test/selectors.test.js +++ b/test/selectors.test.js @@ -134,4 +134,16 @@ test("formats selectors with Nth", () => { } }) +test('formats multiline selectors', () => { + let actual = format(` + a:is( + a, + b, + c + ) {} + `) + let expected = `a:is(a, b, c) {}`; + assert.is(actual, expected) +}) + test.run() diff --git a/test/values.test.js b/test/values.test.js index 179e5e7..f6895bd 100644 --- a/test/values.test.js +++ b/test/values.test.js @@ -75,10 +75,16 @@ a { red, 10% blue, 20% green,100% yellow); + color: rgb( + 0, + 0, + 0 + ); } `); let expected = `a { background: linear-gradient(red, 10% blue, 20% green, 100% yellow); + color: rgb(0, 0, 0); }`; assert.equal(actual, expected); }); From 610ff37c6b12c563f811a3b797d3cfc36bb49b0f Mon Sep 17 00:00:00 2001 From: Bart Veneman Date: Sun, 2 Jun 2024 20:41:13 +0200 Subject: [PATCH 2/4] add case for unkown css in rule block --- index.js | 12 +++++++++--- test/rules.test.js | 10 ++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 399f9aa..47bbe07 100644 --- a/index.js +++ b/index.js @@ -232,8 +232,16 @@ function print_selector(node, css, indent_level) { function print_block(node, css, indent_level) { let children = node.children let buffer = OPTIONAL_SPACE + let only_raw = true - if (children.isEmpty) { + for (let child of children) { + if (child.type !== 'Raw') { + only_raw = false + break + } + } + + if (children.isEmpty || only_raw) { return buffer + '{}' } @@ -259,8 +267,6 @@ function print_block(node, css, indent_level) { buffer += print_rule(child, css, indent_level) } else if (child.type === TYPE_ATRULE) { buffer += print_atrule(child, css, indent_level) - } else { - buffer += print_unknown(child, css, indent_level) } } diff --git a/test/rules.test.js b/test/rules.test.js index dc21c14..b52ad75 100644 --- a/test/rules.test.js +++ b/test/rules.test.js @@ -179,6 +179,16 @@ test("formats nested rules with a selector starting with &", () => { assert.equal(actual, expected); }) +test.only('formats unknown stuff in curly braces', () => { + let actual = format(` + selector { + { color: red; } + } + `) + let expected = `selector {}`; + assert.is(actual, expected); +}) + test.skip("Relaxed nesting: formats nested rules with a selector with a &", () => { let actual = format(` selector { From fa78a2bd14c62c626a48cd2a624aeb93c81831f5 Mon Sep 17 00:00:00 2001 From: Bart Veneman Date: Sun, 2 Jun 2024 20:45:14 +0200 Subject: [PATCH 3/4] add test case for unkown stuff in Value --- index.js | 1 - test/values.test.js | 10 ++++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 47bbe07..76e2f19 100644 --- a/index.js +++ b/index.js @@ -43,7 +43,6 @@ function is_uppercase(str) { */ function substr(node, css) { let loc = node.loc - if (!loc) return EMPTY_STRING let start = loc.start diff --git a/test/values.test.js b/test/values.test.js index f6895bd..dcc21a7 100644 --- a/test/values.test.js +++ b/test/values.test.js @@ -213,4 +213,14 @@ test('lowercases dimensions', () => { assert.is(actual, expected) }) +test('formats unknown content in value', () => { + let actual = format(`a { + content: 'Test' : counter(page); + }`) + let expected = `a { + content: 'Test' : counter(page); +}` + assert.is(actual, expected) +}) + test.run(); From 26d77178320ecfb12bc1ffb63a41562753861964 Mon Sep 17 00:00:00 2001 From: Bart Veneman Date: Sun, 2 Jun 2024 21:01:10 +0200 Subject: [PATCH 4/4] add tests for unknown syntax in rules --- index.js | 20 ++++++++++---------- test/rules.test.js | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/index.js b/index.js index 76e2f19..7978105 100644 --- a/index.js +++ b/index.js @@ -99,8 +99,6 @@ function print_selectorlist(node, css, indent_level) { children.forEach((selector, item) => { if (selector.type === TYPE_SELECTOR) { buffer += print_selector(selector, css, indent_level) - } else { - buffer += print_unknown(selector, css, indent_level) } if (item.next !== null) { @@ -231,16 +229,16 @@ function print_selector(node, css, indent_level) { function print_block(node, css, indent_level) { let children = node.children let buffer = OPTIONAL_SPACE - let only_raw = true + // let only_raw = true - for (let child of children) { - if (child.type !== 'Raw') { - only_raw = false - break - } - } + // for (let child of children) { + // if (child.type !== 'Raw') { + // only_raw = false + // break + // } + // } - if (children.isEmpty || only_raw) { + if (children.isEmpty) { return buffer + '{}' } @@ -266,6 +264,8 @@ function print_block(node, css, indent_level) { buffer += print_rule(child, css, indent_level) } else if (child.type === TYPE_ATRULE) { buffer += print_atrule(child, css, indent_level) + } else { + buffer += print_unknown(child, css, indent_level) } } diff --git a/test/rules.test.js b/test/rules.test.js index b52ad75..40175e0 100644 --- a/test/rules.test.js +++ b/test/rules.test.js @@ -179,16 +179,30 @@ test("formats nested rules with a selector starting with &", () => { assert.equal(actual, expected); }) -test.only('formats unknown stuff in curly braces', () => { +test('formats unknown stuff in curly braces', () => { let actual = format(` selector { { color: red; } } `) - let expected = `selector {}`; + let expected = `selector { + { color: red; } +}`; assert.is(actual, expected); }) +test("[check broken test] Relaxed nesting: formats nested rules with a selector with a &", () => { + let actual = format(` + selector { + a & { color:red } + } + `) + let expected = `selector { + a & { color:red } +}`; + assert.equal(actual, expected); +}) + test.skip("Relaxed nesting: formats nested rules with a selector with a &", () => { let actual = format(` selector { @@ -203,6 +217,18 @@ test.skip("Relaxed nesting: formats nested rules with a selector with a &", () = assert.equal(actual, expected); }) +test("[check broken test] Relaxed nesting: formats nested rules with a selector without a &", () => { + let actual = format(` + selector { + a { color:red } + } + `) + let expected = `selector { + a { color:red } +}`; + assert.equal(actual, expected); +}) + test.skip("Relaxed nesting: formats nested rules with a selector without a &", () => { let actual = format(` selector { @@ -217,6 +243,22 @@ test.skip("Relaxed nesting: formats nested rules with a selector without a &", ( assert.equal(actual, expected); }) +test("[check broken test] Relaxed nesting: formats nested rules with a selector starting with a selector combinator", () => { + let actual = format(` + selector { + > a { color:red } + ~ a { color:red } + + a { color:red } + } + `) + let expected = `selector { + > a { color:red } + ~ a { color:red } + + a { color:red } +}`; + assert.equal(actual, expected); +}) + test.skip("Relaxed nesting: formats nested rules with a selector starting with a selector combinator", () => { let actual = format(` selector {