Skip to content

Commit 9d5308f

Browse files
committed
fix: Bug with utility class which contains trailing slash #24
regex should exact match class str
1 parent 29e96df commit 9d5308f

File tree

16 files changed

+477
-50
lines changed

16 files changed

+477
-50
lines changed

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,8 @@
4444
"engines": {
4545
"node": ">=14.0.0"
4646
},
47-
"packageManager": "pnpm@8.5.1"
47+
"packageManager": "pnpm@8.5.1",
48+
"dependencies": {
49+
"vitest": "^0.32.0"
50+
}
4851
}

packages/core/jest.config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import baseConfig from '../../jest.config'
33
const config: Config = {
44
projects: [
55
{
6-
...baseConfig
6+
...baseConfig,
7+
modulePathIgnorePatterns: ['test/html.test.ts']
78
// transformIgnorePatterns: ['/node_modules/(?!(@parse5/)/tools)']
89
}
910
]

packages/core/package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@
1313
"build": "cross-env NODE_ENV=production rollup -c",
1414
"dev:tsc": "tsc -p tsconfig.json --sourceMap",
1515
"build:tsc": "tsc -p tsconfig.json",
16-
"test": "yarn build && jest"
16+
"_test": "yarn build && jest",
17+
"jest:u": "jest -u",
18+
"test:dev": "yarn build && vitest",
19+
"test": "yarn build && jest && vitest run",
20+
"coverage": "vitest run --coverage"
1721
},
1822
"keywords": [
1923
"tailwindcss",
@@ -45,4 +49,4 @@
4549
"type": "git",
4650
"url": "git+https://github.com/sonofmagic/tailwindcss-mangle.git"
4751
}
48-
}
52+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`html handler > common usage 1`] = `
4+
"<!DOCTYPE html><html><head>
5+
<meta charset=\\"UTF-8\\">
6+
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1.0\\">
7+
<link href=\\"/main.css\\" rel=\\"stylesheet\\">
8+
</head>
9+
10+
<body>
11+
<h1 class=\\"tw-a tw-b tw-c\\">
12+
Hello world!
13+
</h1>
14+
15+
16+
</body></html>"
17+
`;
18+
19+
exports[`html handler > trailing slash case 1`] = `
20+
"<!DOCTYPE html><html lang=\\"en\\"><head>
21+
<meta charset=\\"UTF-8\\">
22+
<meta http-equiv=\\"X-UA-Compatible\\" content=\\"IE=edge\\">
23+
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1.0\\">
24+
<title>Document</title>
25+
</head>
26+
27+
<body>
28+
<div>
29+
<div class=\\"tw-a\\">
30+
Block with bg-red-500 class
31+
</div>
32+
<div class=\\"tw-b\\">
33+
Block with bg-red-500/50 class
34+
</div>
35+
</div>
36+
37+
38+
</body></html>"
39+
`;

packages/core/test/__snapshots__/js.test.ts.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ exports[`js handler nextjs server side mangle 1`] = `
252252
})();"
253253
`;
254254
255+
exports[`js handler trailing slash case 0 1`] = `"document.getElementById("#app").classList.add("tw-a tw-b");"`;
256+
255257
exports[`js handler z-10 not transform 1`] = `
256258
"{
257259
className: "tw-a tw-b tw-c tw-d tw-e tw-f tw-g tw-h";
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
document.getElementById('#app').classList.add('bg-red-500 bg-red-500/50')
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
8+
<title>Document</title>
9+
</head>
10+
11+
<body>
12+
<div>
13+
<div class="bg-red-500">
14+
Block with bg-red-500 class
15+
</div>
16+
<div class="bg-red-500/50">
17+
Block with bg-red-500/50 class
18+
</div>
19+
</div>
20+
</body>
21+
22+
</html>

packages/core/test/html.test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { getTestCase } from './utils'
2+
import { htmlHandler } from '../src/html'
3+
import { ClassGenerator, splitCode } from 'tailwindcss-mangle-shared'
4+
import { describe, it, beforeEach, expect } from 'vitest'
5+
describe('html handler', () => {
6+
let classGenerator: ClassGenerator
7+
beforeEach(() => {
8+
classGenerator = new ClassGenerator()
9+
})
10+
it('common usage', () => {
11+
const runtimeSet = new Set<string>()
12+
13+
splitCode('text-3xl font-bold underline').forEach((x) => {
14+
runtimeSet.add(x)
15+
})
16+
const res = htmlHandler(getTestCase('hello-world.html'), {
17+
classGenerator,
18+
runtimeSet
19+
})
20+
expect(res).toMatchSnapshot()
21+
})
22+
23+
it('trailing slash case', () => {
24+
const runtimeSet = new Set<string>()
25+
26+
splitCode('bg-red-500 bg-red-500/50').forEach((x) => {
27+
runtimeSet.add(x)
28+
})
29+
const res = htmlHandler(getTestCase('trailing-slash.html'), {
30+
classGenerator,
31+
runtimeSet
32+
})
33+
expect(res).toMatchSnapshot()
34+
})
35+
})

packages/core/test/js.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,16 @@ describe('js handler', () => {
149149
}).code
150150
expect(code).toMatchSnapshot()
151151
})
152+
// https://github.com/sonofmagic/tailwindcss-mangle/issues/24
153+
it('trailing slash case 0', () => {
154+
const testCase = getTestCase('trailing-slash-0.js')
155+
const runtimeSet = new Set<string>()
156+
runtimeSet.add('bg-red-500')
157+
runtimeSet.add('bg-red-500/50')
158+
const code = jsHandler(testCase, {
159+
classGenerator,
160+
runtimeSet
161+
}).code
162+
expect(code).toMatchSnapshot()
163+
})
152164
})

packages/core/vitest.config.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { defineConfig } from 'vitest/config'
2+
3+
export default defineConfig({
4+
test: {
5+
include: ['test/html.test.ts']
6+
// ...
7+
}
8+
})

packages/shared/src/regex.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ export function escapeStringRegexp(str: string) {
55
return str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d')
66
}
77

8-
export function makeRegex(str: string) {
9-
return new RegExp('(?<=^|[\\s"])' + escapeStringRegexp(str), 'g')
8+
export function makeRegex(
9+
str: string,
10+
options: {
11+
exact: boolean
12+
} = {
13+
exact: true
14+
}
15+
) {
16+
return new RegExp('(?<=^|[\\s"])' + escapeStringRegexp(str) + (options.exact ? '(?=$|[\\s"])' : ''), 'g')
1017
}

packages/shared/test/__snapshots__/reg.test.ts.snap

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`regex trailing slash should exact match case 0 1`] = `
4+
[
5+
[
6+
"bg-red-500",
7+
],
8+
[
9+
"bg-red-500",
10+
],
11+
]
12+
`;
13+
14+
exports[`regex trailing slash should exact match case 1 1`] = `
15+
[
16+
[
17+
"bg-red-500",
18+
],
19+
]
20+
`;
21+
322
exports[`regex z-10 regex 1`] = `
423
[
524
[

packages/shared/test/reg.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,22 @@ describe('regex', () => {
88
expect(arr.length).toBe(1)
99
expect(arr).toMatchSnapshot()
1010
})
11+
12+
it('trailing slash should exact match case 0', () => {
13+
const testCase = 'bg-red-500 bg-red-500/50'
14+
const regex = makeRegex('bg-red-500', {
15+
exact: false
16+
})
17+
const arr = Array.from(testCase.matchAll(regex))
18+
expect(arr.length).toBe(2)
19+
expect(arr).toMatchSnapshot()
20+
})
21+
22+
it('trailing slash should exact match case 1', () => {
23+
const testCase = 'bg-red-500 bg-red-500/50'
24+
const regex = makeRegex('bg-red-500')
25+
const arr = Array.from(testCase.matchAll(regex))
26+
expect(arr.length).toBe(1)
27+
expect(arr).toMatchSnapshot()
28+
})
1129
})

packages/tailwindcss-patch/test/context.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,15 @@ describe('common usage', () => {
3232
expect(Array.from(set.values())[1]).toBe("bg-[url('https://xxx.webp')]")
3333
//
3434
})
35+
36+
it('trailing slash', () => {
37+
getCss([getTestCase('trailing-slash.vue')])
38+
const ctxs = getContexts()
39+
expect(ctxs).toBeTruthy()
40+
const set = getClassCacheSet()
41+
expect(set.size).toBeGreaterThan(0)
42+
expect(set.size).toBe(4)
43+
expect(set.has('bg-red-500')).toBe(true)
44+
expect(set.has('bg-red-500/50')).toBe(true)
45+
})
3546
})
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<template>
2+
<div>
3+
<div class="">
4+
<div class="">
5+
<div class="bg-[#2f2f2f]">
6+
<div class="bg-red-500">
7+
Block with bg-red-500 class
8+
</div>
9+
<div class="bg-red-500/50">
10+
Block with bg-red-500/50 class
11+
</div>
12+
</div>
13+
</div>
14+
</div>
15+
</div>
16+
</template>

0 commit comments

Comments
 (0)