@@ -19,50 +19,35 @@ describe('regex attribute matching', () => {
1919 } )
2020
2121 test ( 'matches multiple attributes with regex pattern' , async ( { expect } ) => {
22- let result = await format (
23- `<div data-class="sm:p-0 p-0" data-classes="flex block" data-style="bg-red-500 bg-blue-500"></div>` ,
24- {
25- tailwindAttributes : [ '/data-.*/' ] ,
26- } ,
27- )
28-
29- expect ( result ) . toEqual (
30- `<div data-class="p-0 sm:p-0" data-classes="block flex" data-style="bg-blue-500 bg-red-500"></div>` ,
31- )
22+ let result = await format ( `<div data-class="sm:p-0 p-0" data-classes="sm:p-0 p-0" data-style="sm:p-0 p-0"></div>` , {
23+ tailwindAttributes : [ '/data-.*/' ] ,
24+ } )
25+
26+ expect ( result ) . toEqual ( `<div data-class="p-0 sm:p-0" data-classes="p-0 sm:p-0" data-style="p-0 sm:p-0"></div>` )
3227 } )
3328
3429 test ( 'matches attributes with case-insensitive regex' , async ( { expect } ) => {
35- let result = await format ( '<div MyClass="sm:p-0 p-0" myclass="flex block "></div>' , {
30+ let result = await format ( '<div MyClass="sm:p-0 p-0" myclass="sm:p-0 p-0 "></div>' , {
3631 tailwindAttributes : [ '/myclass/i' ] ,
3732 } )
3833
39- expect ( result ) . toEqual ( '<div MyClass="p-0 sm:p-0" myclass="block flex "></div>' )
34+ expect ( result ) . toEqual ( '<div MyClass="p-0 sm:p-0" myclass="p-0 sm:p-0 "></div>' )
4035 } )
4136
4237 test ( 'combines exact match and regex pattern' , async ( { expect } ) => {
43- let result = await format (
44- '<div class="sm:p-0 p-0" data-class="flex block" customClass="bg-red-500 bg-blue-500"></div>' ,
45- {
46- tailwindAttributes : [ 'customClass' , '/data-.*/' ] ,
47- } ,
48- )
49-
50- expect ( result ) . toEqual (
51- '<div class="p-0 sm:p-0" data-class="block flex" customClass="bg-blue-500 bg-red-500"></div>' ,
52- )
38+ let result = await format ( '<div class="sm:p-0 p-0" data-class="sm:p-0 p-0" customClass="sm:p-0 p-0"></div>' , {
39+ tailwindAttributes : [ 'customClass' , '/data-.*/' ] ,
40+ } )
41+
42+ expect ( result ) . toEqual ( '<div class="p-0 sm:p-0" data-class="p-0 sm:p-0" customClass="p-0 sm:p-0"></div>' )
5343 } )
5444
5545 test ( 'regex pattern with specific endings' , async ( { expect } ) => {
56- let result = await format (
57- '<div classList="sm:p-0 p-0" styleList="flex block" otherList="bg-red-500 bg-blue-500"></div>' ,
58- {
59- tailwindAttributes : [ '/.*List$/' ] ,
60- } ,
61- )
62-
63- expect ( result ) . toEqual (
64- '<div classList="p-0 sm:p-0" styleList="block flex" otherList="bg-blue-500 bg-red-500"></div>' ,
65- )
46+ let result = await format ( '<div classList="sm:p-0 p-0" styleList="sm:p-0 p-0" otherList="sm:p-0 p-0"></div>' , {
47+ tailwindAttributes : [ '/.*List$/' ] ,
48+ } )
49+
50+ expect ( result ) . toEqual ( '<div classList="p-0 sm:p-0" styleList="p-0 sm:p-0" otherList="p-0 sm:p-0"></div>' )
6651 } )
6752
6853 test ( 'works with JSX components' , async ( { expect } ) => {
@@ -92,35 +77,50 @@ describe('regex attribute matching', () => {
9277 expect ( result ) . toEqual ( '<div [dataClasses]="p-0 sm:p-0"></div>' )
9378 } )
9479
95- test ( 'invalid regex pattern falls back to exact match' , async ( { expect } ) => {
96- // Invalid regex (unclosed bracket), should treat as literal string and not throw
80+ test ( 'invalid regex patterns do nothing' , async ( { expect } ) => {
9781 let result = await format ( '<div data-test="sm:p-0 p-0"></div>' , {
9882 tailwindAttributes : [ '/data-[/' ] ,
9983 } )
10084
101- // Since it's treated as literal string "/data-[/", it won't match "data-test"
10285 expect ( result ) . toEqual ( '<div data-test="sm:p-0 p-0"></div>' )
10386 } )
10487
10588 test ( 'matches with word boundaries' , async ( { expect } ) => {
106- let result = await format (
107- '<div className="sm:p-0 p-0" myClassName="flex block" classNames="bg-red-500 bg-blue-500"></div>' ,
108- {
109- tailwindAttributes : [ '/\\bclass\\b/i' ] ,
110- } ,
111- )
112-
113- // Should NOT match since we're looking for exact word "class"
114- expect ( result ) . toEqual (
115- '<div className="sm:p-0 p-0" myClassName="flex block" classNames="bg-red-500 bg-blue-500"></div>' ,
116- )
89+ let result = await format ( '<div className="sm:p-0 p-0" myClassName="sm:p-0 p-0" classNames="sm:p-0 p-0"></div>' , {
90+ tailwindAttributes : [ '/\\bclass\\b/i' ] ,
91+ } )
92+
93+ // Does not match since we're looking for exact word "class"
94+ expect ( result ) . toEqual ( '<div className="sm:p-0 p-0" myClassName="sm:p-0 p-0" classNames="sm:p-0 p-0"></div>' )
11795 } )
11896
11997 test ( 'matches with OR patterns' , async ( { expect } ) => {
120- let result = await format ( '<div styles="sm:p-0 p-0" classes="flex block " other="bg-red-500 bg-blue-500 "></div>' , {
98+ let result = await format ( '<div styles="sm:p-0 p-0" classes="sm:p-0 p-0 " other="sm:p-0 p-0 "></div>' , {
12199 tailwindAttributes : [ '/(styles|classes)/' ] ,
122100 } )
123101
124- expect ( result ) . toEqual ( '<div styles="p-0 sm:p-0" classes="block flex" other="bg-red-500 bg-blue-500"></div>' )
102+ expect ( result ) . toEqual ( '<div styles="p-0 sm:p-0" classes="p-0 sm:p-0" other="sm:p-0 p-0"></div>' )
103+ } )
104+
105+ // These tests pass but that is a side-effect of the implementation
106+ // If these change in the future to no longer pass that is a good thing
107+ describe ( 'dynamic attribute matching quirks' , ( ) => {
108+ test ( 'Vue' , async ( { expect } ) => {
109+ let result = await format ( '<div ::data-classes="sm:p-0 p-0"></div>' , {
110+ parser : 'vue' ,
111+ tailwindAttributes : [ '/:data-.*/' ] ,
112+ } )
113+
114+ expect ( result ) . toEqual ( '<div ::data-classes="p-0 sm:p-0"></div>' )
115+ } )
116+
117+ test ( 'Angular' , async ( { expect } ) => {
118+ let result = await format ( '<div [[dataClasses]]="sm:p-0 p-0"></div>' , {
119+ parser : 'angular' ,
120+ tailwindAttributes : [ '/\\[data.*\\]/i' ] ,
121+ } )
122+
123+ expect ( result ) . toEqual ( '<div [[dataClasses]]="p-0 sm:p-0"></div>' )
124+ } )
125125 } )
126126} )
0 commit comments