1+ /**
2+ * @fileoverview Test to validate the fix for slash notation
3+ */
4+
5+ import assert from "node:assert" ;
6+ import { tailwind3 } from "../src/tailwind3.js" ;
7+ import { tailwind4 } from "../src/tailwind4.js" ;
8+ import { fork } from "@eslint/css-tree" ;
9+
10+ describe ( "Slash notation fix validation" , function ( ) {
11+ describe ( "Tailwind 3" , function ( ) {
12+ it ( "should parse @apply with slash notation" , ( ) => {
13+ const { parse, toPlainObject } = fork ( tailwind3 ) ;
14+
15+ const result = parse ( "a { @apply outline-ring/50; }" ) ;
16+ const plain = toPlainObject ( result ) ;
17+
18+ const prelude = plain . children [ 0 ] . block . children [ 0 ] . prelude ;
19+
20+ // Should NOT fall back to Raw parsing
21+ assert . notEqual ( prelude . type , "Raw" , "Should not fall back to Raw parsing" ) ;
22+
23+ // Should use proper AtrulePrelude
24+ assert . equal ( prelude . type , "AtrulePrelude" , "Should use AtrulePrelude" ) ;
25+
26+ // Should have the correct parsed structure
27+ assert . ok ( prelude . children && prelude . children . length > 0 , "Should have children" ) ;
28+ } ) ;
29+
30+ it ( "should parse @apply with variant and slash notation" , ( ) => {
31+ const { parse, toPlainObject } = fork ( tailwind3 ) ;
32+
33+ const result = parse ( "a { @apply hover:bg-blue-500/50; }" ) ;
34+ const plain = toPlainObject ( result ) ;
35+
36+ const prelude = plain . children [ 0 ] . block . children [ 0 ] . prelude ;
37+
38+ // Should NOT fall back to Raw parsing
39+ assert . notEqual ( prelude . type , "Raw" , "Should not fall back to Raw parsing" ) ;
40+
41+ // Should use proper AtrulePrelude
42+ assert . equal ( prelude . type , "AtrulePrelude" , "Should use AtrulePrelude" ) ;
43+
44+ // Should have TailwindUtilityClass with slash in name
45+ assert . ok ( prelude . children && prelude . children . length > 0 , "Should have children" ) ;
46+
47+ const child = prelude . children [ 0 ] ;
48+ if ( child . type === "TailwindUtilityClass" ) {
49+ assert . ok ( child . name . name . includes ( '/' ) , "Should include slash in class name" ) ;
50+ }
51+ } ) ;
52+
53+ it ( "should parse complex @apply from the original issue" , ( ) => {
54+ const { parse, toPlainObject } = fork ( tailwind3 ) ;
55+
56+ const css = `
57+ @layer base {
58+ * {
59+ @apply border-border outline-ring/50;
60+ }
61+ body {
62+ @apply bg-background text-foreground;
63+ }
64+ }
65+ ` ;
66+
67+ const result = parse ( css ) ;
68+ const plain = toPlainObject ( result ) ;
69+
70+ // Find the @apply rule
71+ const layerRule = plain . children [ 0 ] ; // @layer
72+ const starRule = layerRule . block . children [ 0 ] ; // *
73+ const applyRule = starRule . block . children [ 0 ] ; // @apply
74+
75+ // Should NOT fall back to Raw parsing
76+ assert . notEqual ( applyRule . prelude . type , "Raw" , "Should not fall back to Raw parsing" ) ;
77+ assert . equal ( applyRule . prelude . type , "AtrulePrelude" , "Should use AtrulePrelude" ) ;
78+ } ) ;
79+ } ) ;
80+
81+ describe ( "Tailwind 4" , function ( ) {
82+ it ( "should parse @apply with slash notation" , ( ) => {
83+ const { parse, toPlainObject } = fork ( tailwind4 ) ;
84+
85+ const result = parse ( "a { @apply outline-ring/50; }" ) ;
86+ const plain = toPlainObject ( result ) ;
87+
88+ const prelude = plain . children [ 0 ] . block . children [ 0 ] . prelude ;
89+
90+ // Should NOT fall back to Raw parsing
91+ assert . notEqual ( prelude . type , "Raw" , "Should not fall back to Raw parsing" ) ;
92+ assert . equal ( prelude . type , "AtrulePrelude" , "Should use AtrulePrelude" ) ;
93+ } ) ;
94+ } ) ;
95+ } ) ;
0 commit comments