1- import { afterEach , beforeEach , expect , test } from '@voidzero-dev/vite-plus-test' ;
1+ import { afterEach , beforeEach , expect , test , vi } from '@voidzero-dev/vite-plus-test' ;
22
33import {
44 configDefaults ,
88 defaultBrowserPort ,
99 defineConfig ,
1010 defineProject ,
11- vitePlugins ,
1211} from '../index.js' ;
1312
1413let originalVpCommand : string | undefined ;
@@ -28,58 +27,176 @@ afterEach(() => {
2827test ( 'should keep vitest exports stable' , ( ) => {
2928 expect ( defineConfig ) . toBeTypeOf ( 'function' ) ;
3029 expect ( defineProject ) . toBeTypeOf ( 'function' ) ;
31- expect ( vitePlugins ) . toBeTypeOf ( 'function' ) ;
3230 expect ( configDefaults ) . toBeDefined ( ) ;
3331 expect ( coverageConfigDefaults ) . toBeDefined ( ) ;
3432 expect ( defaultExclude ) . toBeDefined ( ) ;
3533 expect ( defaultInclude ) . toBeDefined ( ) ;
3634 expect ( defaultBrowserPort ) . toBeDefined ( ) ;
3735} ) ;
3836
39- test ( 'vitePlugins returns undefined when VP_COMMAND is unset' , ( ) => {
40- delete process . env . VP_COMMAND ;
41- const result = vitePlugins ( ( ) => [ { name : 'test' } ] ) ;
42- expect ( result ) . toBeUndefined ( ) ;
43- } ) ;
44-
45- test ( 'vitePlugins returns undefined when VP_COMMAND is empty string' , ( ) => {
46- process . env . VP_COMMAND = '' ;
47- const result = vitePlugins ( ( ) => [ { name : 'test' } ] ) ;
48- expect ( result ) . toBeUndefined ( ) ;
37+ test ( 'defineConfig passes through plain plugins array' , ( ) => {
38+ process . env . VP_COMMAND = 'build' ;
39+ const config = defineConfig ( {
40+ plugins : [ { name : 'test-plugin' } ] ,
41+ } ) ;
42+ expect ( config . plugins ?. length ) . toBe ( 1 ) ;
4943} ) ;
5044
5145test . each ( [ 'dev' , 'build' , 'test' , 'preview' ] ) (
52- 'vitePlugins executes callback when VP_COMMAND is %s' ,
46+ 'defineConfig executes sync plugins factory when VP_COMMAND is %s' ,
5347 ( cmd ) => {
5448 process . env . VP_COMMAND = cmd ;
55- const result = vitePlugins ( ( ) => [ { name : 'my-plugin' } ] ) ;
56- expect ( result ) . toEqual ( [ { name : 'my-plugin' } ] ) ;
49+ const config = defineConfig ( {
50+ plugins : ( ) => [ { name : 'factory-plugin' } ] ,
51+ } ) ;
52+ expect ( config . plugins ?. length ) . toBe ( 1 ) ;
53+ expect ( ( config . plugins ?. [ 0 ] as { name : string } ) ?. name ) . toBe ( 'factory-plugin' ) ;
54+ } ,
55+ ) ;
56+
57+ test . each ( [ 'dev' , 'build' , 'test' , 'preview' ] ) (
58+ 'defineConfig executes async plugins factory when VP_COMMAND is %s' ,
59+ async ( cmd ) => {
60+ process . env . VP_COMMAND = cmd ;
61+ const config = defineConfig ( {
62+ plugins : async ( ) => {
63+ const plugin = await Promise . resolve ( { name : 'async-factory-plugin' } ) ;
64+ return [ plugin ] ;
65+ } ,
66+ } ) ;
67+ // Async factory wraps the promise in an array for asyncFlatten
68+ expect ( config . plugins ?. length ) . toBe ( 1 ) ;
69+ const resolved = await ( config . plugins ?. [ 0 ] as Promise < { name : string } [ ] > ) ;
70+ expect ( resolved . length ) . toBe ( 1 ) ;
71+ expect ( resolved [ 0 ] . name ) . toBe ( 'async-factory-plugin' ) ;
5772 } ,
5873) ;
5974
6075test . each ( [ 'lint' , 'fmt' , 'check' , 'pack' , 'install' , 'run' ] ) (
61- 'vitePlugins returns undefined when VP_COMMAND is %s' ,
76+ 'defineConfig skips plugins factory when VP_COMMAND is %s' ,
6277 ( cmd ) => {
6378 process . env . VP_COMMAND = cmd ;
64- const result = vitePlugins ( ( ) => [ { name : 'my-plugin' } ] ) ;
65- expect ( result ) . toBeUndefined ( ) ;
79+ const factoryFn = vi . fn ( ( ) => [ { name : 'should-not-load' } ] ) ;
80+ const config = defineConfig ( {
81+ plugins : factoryFn ,
82+ } ) ;
83+ expect ( factoryFn ) . not . toHaveBeenCalled ( ) ;
84+ expect ( config . plugins ?. length ) . toBe ( 0 ) ;
6685 } ,
6786) ;
6887
69- test ( 'vitePlugins supports async callback' , async ( ) => {
88+ test ( 'defineConfig skips plugins factory when VP_COMMAND is unset' , ( ) => {
89+ delete process . env . VP_COMMAND ;
90+ const factoryFn = vi . fn ( ( ) => [ { name : 'should-not-load' } ] ) ;
91+ const config = defineConfig ( {
92+ plugins : factoryFn ,
93+ } ) ;
94+ expect ( factoryFn ) . not . toHaveBeenCalled ( ) ;
95+ expect ( config . plugins ?. length ) . toBe ( 0 ) ;
96+ } ) ;
97+
98+ test ( 'defineConfig handles function config with plugins factory' , ( ) => {
99+ process . env . VP_COMMAND = 'build' ;
100+ const configFn = defineConfig ( ( ) => ( {
101+ plugins : ( ) => [ { name : 'fn-factory-plugin' } ] ,
102+ } ) ) ;
103+ const config = configFn ( { command : 'build' , mode : 'production' } ) ;
104+ const plugins = config . plugins as { name : string } [ ] ;
105+ expect ( plugins ?. length ) . toBe ( 1 ) ;
106+ expect ( plugins ?. [ 0 ] ?. name ) . toBe ( 'fn-factory-plugin' ) ;
107+ } ) ;
108+
109+ test ( 'defineConfig handles async function config with plugins factory' , async ( ) => {
70110 process . env . VP_COMMAND = 'build' ;
71- const result = vitePlugins ( async ( ) => {
72- const plugin = await Promise . resolve ( { name : 'async-plugin' } ) ;
73- return [ plugin ] ;
111+ const configFn = defineConfig ( async ( ) => ( {
112+ plugins : ( ) => [ { name : 'async-fn-factory-plugin' } ] ,
113+ } ) ) ;
114+ const config = await configFn ( { command : 'build' , mode : 'production' } ) ;
115+ const plugins = config . plugins as { name : string } [ ] ;
116+ expect ( plugins ?. length ) . toBe ( 1 ) ;
117+ expect ( plugins ?. [ 0 ] ?. name ) . toBe ( 'async-fn-factory-plugin' ) ;
118+ } ) ;
119+
120+ test ( 'defineConfig handles Promise config with plugins factory' , async ( ) => {
121+ process . env . VP_COMMAND = 'build' ;
122+ const config = await defineConfig (
123+ Promise . resolve ( {
124+ plugins : ( ) => [ { name : 'promise-factory-plugin' } ] ,
125+ } ) ,
126+ ) ;
127+ expect ( config . plugins ?. length ) . toBe ( 1 ) ;
128+ expect ( ( config . plugins ?. [ 0 ] as { name : string } ) ?. name ) . toBe ( 'promise-factory-plugin' ) ;
129+ } ) ;
130+
131+ // Vite/Vitest PluginOption compatibility tests
132+ // PluginOption = Thenable<Plugin | { name: string } | false | null | undefined | PluginOption[]>
133+
134+ test ( 'defineConfig supports Plugin objects in plugins array' , ( ) => {
135+ const config = defineConfig ( {
136+ plugins : [ { name : 'plugin-a' } , { name : 'plugin-b' } ] ,
137+ } ) ;
138+ expect ( config . plugins ?. length ) . toBe ( 2 ) ;
139+ } ) ;
140+
141+ test ( 'defineConfig supports falsy values in plugins array' , ( ) => {
142+ const config = defineConfig ( {
143+ plugins : [ { name : 'real-plugin' } , false , null , undefined ] ,
144+ } ) ;
145+ expect ( config . plugins ?. length ) . toBe ( 4 ) ;
146+ } ) ;
147+
148+ test ( 'defineConfig supports nested plugin arrays' , ( ) => {
149+ const config = defineConfig ( {
150+ plugins : [ [ { name : 'nested-a' } , { name : 'nested-b' } ] , { name : 'top-level' } ] ,
151+ } ) ;
152+ expect ( config . plugins ?. length ) . toBe ( 2 ) ;
153+ } ) ;
154+
155+ test ( 'defineConfig supports Promise<Plugin> in plugins array' , ( ) => {
156+ const config = defineConfig ( {
157+ plugins : [ Promise . resolve ( { name : 'async-plugin' } ) ] ,
74158 } ) ;
75- expect ( result ) . toBeInstanceOf ( Promise ) ;
76- expect ( await result ) . toEqual ( [ { name : 'async-plugin' } ] ) ;
159+ expect ( config . plugins ?. length ) . toBe ( 1 ) ;
77160} ) ;
78161
79- test ( 'vitePlugins returns undefined for async callback when skipped' , ( ) => {
80- process . env . VP_COMMAND = 'lint' ;
81- const result = vitePlugins ( async ( ) => {
82- return [ { name : 'async-plugin' } ] ;
162+ test ( 'defineConfig supports mixed PluginOption types in array' , ( ) => {
163+ const config = defineConfig ( {
164+ plugins : [
165+ { name : 'sync-plugin' } ,
166+ false ,
167+ Promise . resolve ( { name : 'promised-plugin' } ) ,
168+ [ { name : 'nested-plugin' } ] ,
169+ null ,
170+ undefined ,
171+ ] ,
83172 } ) ;
84- expect ( result ) . toBeUndefined ( ) ;
173+ expect ( config . plugins ?. length ) . toBe ( 6 ) ;
174+ } ) ;
175+
176+ test ( 'defineConfig supports empty plugins array' , ( ) => {
177+ const config = defineConfig ( {
178+ plugins : [ ] ,
179+ } ) ;
180+ expect ( config . plugins ?. length ) . toBe ( 0 ) ;
181+ } ) ;
182+
183+ test ( 'defineConfig supports config without plugins' , ( ) => {
184+ const config = defineConfig ( { } ) ;
185+ expect ( config . plugins ) . toBeUndefined ( ) ;
186+ } ) ;
187+
188+ test ( 'defineConfig supports function config with plain plugins array' , ( ) => {
189+ const configFn = defineConfig ( ( ) => ( {
190+ plugins : [ { name : 'fn-plugin' } ] ,
191+ } ) ) ;
192+ const config = configFn ( { command : 'build' , mode : 'production' } ) ;
193+ expect ( config . plugins ?. length ) . toBe ( 1 ) ;
194+ } ) ;
195+
196+ test ( 'defineConfig supports async function config with plain plugins array' , async ( ) => {
197+ const configFn = defineConfig ( async ( ) => ( {
198+ plugins : [ { name : 'async-fn-plugin' } ] ,
199+ } ) ) ;
200+ const config = await configFn ( { command : 'build' , mode : 'production' } ) ;
201+ expect ( config . plugins ?. length ) . toBe ( 1 ) ;
85202} ) ;
0 commit comments