11import { afterAll , beforeAll , beforeEach , describe , expect , test , vi } from 'vitest' ;
22
33import { clearCache , cssSupports } from '../cssSupports' ;
4+ import { lightDark } from '../lightDark' ;
45
5- // Mock CSS.supports
6- const originalCSSSupports = CSS . supports ;
6+ // Store original CSS if it exists
7+ const originalCSS = globalThis . CSS ;
78
89beforeAll ( ( ) => {
9- CSS . supports = vi . fn ( feature => {
10- if ( feature === 'color: hsl(from white h s l)' ) {
11- return true ;
12- }
13- if ( feature === 'color: color-mix(in srgb, white, black)' ) {
10+ // Create mock CSS global for Node.js environment
11+ globalThis . CSS = {
12+ supports : vi . fn ( ( feature : string ) => {
13+ if ( feature === 'color: hsl(from white h s l)' ) {
14+ return true ;
15+ }
16+ if ( feature === 'color: color-mix(in srgb, white, black)' ) {
17+ return false ;
18+ }
19+ if ( feature === 'color: light-dark(white, black)' ) {
20+ return true ;
21+ }
1422 return false ;
15- }
16- return false ;
17- } ) ;
23+ } ) ,
24+ } as unknown as typeof CSS ;
1825} ) ;
1926
2027afterAll ( ( ) => {
21- CSS . supports = originalCSSSupports ;
28+ // Restore original CSS or remove if it didn't exist
29+ if ( originalCSS ) {
30+ globalThis . CSS = originalCSS ;
31+ } else {
32+ // @ts -expect-error - cleaning up mock
33+ delete globalThis . CSS ;
34+ }
2235} ) ;
2336
2437beforeEach ( ( ) => {
2538 clearCache ( ) ;
26- vi . mocked ( CSS . supports ) . mockClear ( ) ;
39+ // Reset mock to default behavior
40+ vi . mocked ( globalThis . CSS . supports ) . mockImplementation ( ( feature : string ) => {
41+ if ( feature === 'color: hsl(from white h s l)' ) {
42+ return true ;
43+ }
44+ if ( feature === 'color: color-mix(in srgb, white, black)' ) {
45+ return false ;
46+ }
47+ if ( feature === 'color: light-dark(white, black)' ) {
48+ return true ;
49+ }
50+ return false ;
51+ } ) ;
2752} ) ;
2853
2954describe ( 'cssSupports' , ( ) => {
@@ -39,10 +64,68 @@ describe('cssSupports', () => {
3964 expect ( cssSupports . modernColor ( ) ) . toBe ( true ) ;
4065 } ) ;
4166
67+ test ( 'lightDark should return true when supported' , ( ) => {
68+ expect ( cssSupports . lightDark ( ) ) . toBe ( true ) ;
69+ } ) ;
70+
4271 test ( 'caching works correctly' , ( ) => {
72+ const initialCallCount = vi . mocked ( globalThis . CSS . supports ) . mock . calls . length ;
4373 cssSupports . relativeColorSyntax ( ) ;
44- expect ( CSS . supports ) . toHaveBeenCalledTimes ( 1 ) ;
74+ expect ( globalThis . CSS . supports ) . toHaveBeenCalledTimes ( initialCallCount + 1 ) ;
4575 cssSupports . relativeColorSyntax ( ) ;
46- expect ( CSS . supports ) . toHaveBeenCalledTimes ( 1 ) ; // Should not call again due to caching
76+ expect ( globalThis . CSS . supports ) . toHaveBeenCalledTimes ( initialCallCount + 1 ) ; // Should not call again due to caching
77+ } ) ;
78+
79+ test ( 'lightDark caching works correctly' , ( ) => {
80+ const initialCallCount = vi . mocked ( globalThis . CSS . supports ) . mock . calls . length ;
81+ cssSupports . lightDark ( ) ;
82+ expect ( globalThis . CSS . supports ) . toHaveBeenCalledTimes ( initialCallCount + 1 ) ;
83+ cssSupports . lightDark ( ) ;
84+ expect ( globalThis . CSS . supports ) . toHaveBeenCalledTimes ( initialCallCount + 1 ) ; // Should not call again due to caching
85+ } ) ;
86+ } ) ;
87+
88+ describe ( 'lightDark utility' , ( ) => {
89+ test ( 'returns light-dark() when both lightDark and modernColor are supported' , ( ) => {
90+ // In this test setup: lightDark=true, relativeColorSyntax=true (so modernColor=true)
91+ const result = lightDark ( '#ffffff' , '#000000' ) ;
92+ expect ( result ) . toBe ( 'light-dark(#ffffff, #000000)' ) ;
93+ } ) ;
94+
95+ test ( 'returns light value when lightDark is not supported' , ( ) => {
96+ // Override mock to return false for lightDark
97+ vi . mocked ( globalThis . CSS . supports ) . mockImplementation ( ( feature : string ) => {
98+ if ( feature === 'color: light-dark(white, black)' ) {
99+ return false ;
100+ }
101+ if ( feature === 'color: hsl(from white h s l)' ) {
102+ return true ;
103+ }
104+ return false ;
105+ } ) ;
106+ clearCache ( ) ;
107+
108+ const result = lightDark ( '#ffffff' , '#000000' ) ;
109+ expect ( result ) . toBe ( '#ffffff' ) ;
110+ } ) ;
111+
112+ test ( 'returns light value when modernColor is not supported' , ( ) => {
113+ // Override mock to return true for lightDark but false for modern color features
114+ vi . mocked ( globalThis . CSS . supports ) . mockImplementation ( ( feature : string ) => {
115+ if ( feature === 'color: light-dark(white, black)' ) {
116+ return true ;
117+ }
118+ // Both relativeColorSyntax and colorMix return false
119+ return false ;
120+ } ) ;
121+ clearCache ( ) ;
122+
123+ const result = lightDark ( '#ffffff' , '#000000' ) ;
124+ expect ( result ) . toBe ( '#ffffff' ) ;
125+ } ) ;
126+
127+ test ( 'works with named colors' , ( ) => {
128+ const result = lightDark ( 'white' , 'black' ) ;
129+ expect ( result ) . toBe ( 'light-dark(white, black)' ) ;
47130 } ) ;
48131} ) ;
0 commit comments