Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
28 changes: 11 additions & 17 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,11 @@ function is_uppercase(str) {
*/
function substr(node, css) {
let loc = node.loc

if (!loc) return EMPTY_STRING

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)
}

/**
Expand Down Expand Up @@ -108,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) {
Expand All @@ -126,12 +115,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 ' '
Expand Down Expand Up @@ -243,6 +229,14 @@ 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

// for (let child of children) {
// if (child.type !== 'Raw') {
// only_raw = false
// break
// }
// }

if (children.isEmpty) {
return buffer + '{}'
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down Expand Up @@ -45,4 +45,4 @@
"pretty",
"prettier"
]
}
}
52 changes: 52 additions & 0 deletions test/rules.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,30 @@ test("formats nested rules with a selector starting with &", () => {
assert.equal(actual, expected);
})

test('formats unknown stuff in curly braces', () => {
let actual = format(`
selector {
{ color: red; }
}
`)
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 {
Expand All @@ -193,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 {
Expand All @@ -207,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 {
Expand Down
12 changes: 12 additions & 0 deletions test/selectors.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()
16 changes: 16 additions & 0 deletions test/values.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
Expand Down Expand Up @@ -207,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();