1+ import { should , expect } from 'chai'
2+ import parser from '../build/lib/index.js'
3+ import path from 'path'
4+ import { fileURLToPath } from 'url'
5+ import { readFileSync } from 'fs'
6+
7+ should ( )
8+
9+ describe ( 'yargs-parser (esm)' , function ( ) {
10+ const __dirname = path . dirname ( fileURLToPath ( import . meta. url ) )
11+ const jsonPath = path . resolve ( __dirname , './fixtures/config.json' )
12+ describe ( 'config' , function ( ) {
13+ it ( 'should load options and values from default config if specified' , function ( ) {
14+ const argv = parser ( [ '--foo' , 'bar' ] , {
15+ alias : {
16+ z : 'zoom'
17+ } ,
18+ default : {
19+ settings : jsonPath
20+ } ,
21+ config : 'settings'
22+ } )
23+
24+ argv . should . have . property ( 'herp' , 'derp' )
25+ argv . should . have . property ( 'zoom' , 55 )
26+ argv . should . have . property ( 'foo' ) . and . deep . equal ( 'bar' )
27+ } )
28+
29+ it ( 'should use value from config file, if argv value is using default value' , function ( ) {
30+ const argv = parser ( [ ] , {
31+ alias : {
32+ z : 'zoom'
33+ } ,
34+ config : [ 'settings' ] ,
35+ default : {
36+ settings : jsonPath ,
37+ foo : 'banana'
38+ }
39+ } )
40+
41+ argv . should . have . property ( 'herp' , 'derp' )
42+ argv . should . have . property ( 'zoom' , 55 )
43+ argv . should . have . property ( 'foo' ) . and . deep . equal ( 'baz' )
44+ } )
45+
46+ it ( 'should combine values from config file and argv, if argv value is an array' , function ( ) {
47+ const argv = parser ( [ '--foo' , 'bar' ] , {
48+ config : [ 'settings' ] ,
49+ array : [ 'foo' ] ,
50+ default : {
51+ settings : jsonPath
52+ } ,
53+ configuration : {
54+ 'combine-arrays' : true
55+ }
56+ } )
57+
58+ argv . should . have . property ( 'foo' ) . and . deep . equal ( [ 'bar' , 'baz' ] )
59+ } )
60+
61+ it ( 'should use value from config file, if argv key is a boolean' , function ( ) {
62+ const argv = parser ( [ ] , {
63+ config : [ 'settings' ] ,
64+ default : {
65+ settings : jsonPath
66+ } ,
67+ boolean : [ 'truthy' ]
68+ } )
69+
70+ argv . should . have . property ( 'truthy' , true )
71+ } )
72+
73+ it ( 'should use value from cli, if cli overrides boolean argv key' , function ( ) {
74+ const argv = parser ( [ '--no-truthy' ] , {
75+ config : [ 'settings' ] ,
76+ default : {
77+ settings : jsonPath
78+ } ,
79+ boolean : [ 'truthy' ]
80+ } )
81+
82+ argv . should . have . property ( 'truthy' , false )
83+ } )
84+
85+ it ( 'should use cli value, if cli value is set and both cli and default value match' , function ( ) {
86+ const argv = parser ( [ '--foo' , 'banana' ] , {
87+ alias : {
88+ z : 'zoom'
89+ } ,
90+ config : [ 'settings' ] ,
91+ default : {
92+ settings : jsonPath ,
93+ foo : 'banana'
94+ }
95+ } )
96+
97+ argv . should . have . property ( 'herp' , 'derp' )
98+ argv . should . have . property ( 'zoom' , 55 )
99+ argv . should . have . property ( 'foo' ) . and . deep . equal ( 'banana' )
100+ } )
101+
102+ it ( "should allow config to be set as flag in 'option'" , function ( ) {
103+ const argv = parser ( [ '--settings' , jsonPath , '--foo' , 'bar' ] , {
104+ alias : {
105+ z : 'zoom'
106+ } ,
107+ config : [ 'settings' ]
108+ } )
109+
110+ argv . should . have . property ( 'herp' , 'derp' )
111+ argv . should . have . property ( 'zoom' , 55 )
112+ argv . should . have . property ( 'foo' ) . and . deep . equal ( 'bar' )
113+ } )
114+
115+ // for esm, only support importing json files
116+ it ( 'should fail to load options and values from a JS file when config has .js extention' , function ( ) {
117+ const jsPath = path . resolve ( __dirname , './fixtures/settings.cjs' )
118+ const argv = parser . detailed ( [ '--settings' , jsPath , '--foo' , 'bar' ] , {
119+ config : [ 'settings' ]
120+ } )
121+
122+ argv . error . message . should . include ( 'Invalid JSON config file' )
123+ } )
124+
125+ it ( 'should raise an appropriate error if JSON file is not found' , function ( ) {
126+ const argv = parser . detailed ( [ '--settings' , 'fake.json' , '--foo' , 'bar' ] , {
127+ alias : {
128+ z : 'zoom'
129+ } ,
130+ config : [ 'settings' ]
131+ } )
132+
133+ argv . error . message . should . equal ( 'Invalid JSON config file: fake.json' )
134+ } )
135+
136+ // see: https://github.com/bcoe/yargs/issues/172
137+ it ( 'should not raise an exception if config file is set as default argument value' , function ( ) {
138+ const argv = parser . detailed ( [ ] , {
139+ default : {
140+ config : 'foo.json'
141+ } ,
142+ config : [ 'config' ]
143+ } )
144+
145+ expect ( argv . error ) . to . equal ( null )
146+ } )
147+
148+ it ( 'should load nested options from config file' , function ( ) {
149+ const jsonPath = path . resolve ( __dirname , './fixtures/nested_config.json' )
150+ const argv = parser ( [ '--settings' , jsonPath , '--nested.foo' , 'bar' ] , {
151+ config : [ 'settings' ]
152+ } )
153+
154+ argv . should . have . property ( 'a' , 'a' )
155+ argv . should . have . property ( 'b' , 'b' )
156+ argv . should . have . property ( 'nested' ) . and . deep . equal ( {
157+ foo : 'bar' ,
158+ bar : 'bar'
159+ } )
160+ } )
161+
162+ it ( 'should use nested value from config file, if argv value is using default value' , function ( ) {
163+ const jsonPath = path . resolve ( __dirname , './fixtures/nested_config.json' )
164+ const argv = parser ( [ '--settings' , jsonPath ] , {
165+ config : [ 'settings' ] ,
166+ default : {
167+ 'nested.foo' : 'banana'
168+ }
169+ } )
170+
171+ argv . should . have . property ( 'a' , 'a' )
172+ argv . should . have . property ( 'b' , 'b' )
173+ argv . should . have . property ( 'nested' ) . and . deep . equal ( {
174+ foo : 'baz' ,
175+ bar : 'bar'
176+ } )
177+ } )
178+
179+ it ( 'allows a custom parsing function to be provided' , function ( ) {
180+ const jsPath = path . resolve ( __dirname , './fixtures/config.txt' )
181+ const argv = parser ( [ '--settings' , jsPath , '--foo' , 'bar' ] , {
182+ config : {
183+ settings : function ( configPath ) {
184+ // as an example, parse an environment
185+ // variable style config:
186+ // FOO=99
187+ // BATMAN=grumpy
188+ const config = { }
189+ const txt = readFileSync ( configPath , 'utf-8' )
190+ txt . split ( / \r ? \n / ) . forEach ( function ( l ) {
191+ const kv = l . split ( '=' )
192+ config [ kv [ 0 ] . toLowerCase ( ) ] = kv [ 1 ]
193+ } )
194+ return config
195+ }
196+ }
197+ } )
198+
199+ argv . batman . should . equal ( 'grumpy' )
200+ argv . awesome . should . equal ( 'banana' )
201+ argv . foo . should . equal ( 'bar' )
202+ } )
203+
204+ it ( 'allows a custom parsing function to be provided as an alias' , function ( ) {
205+ const jsPath = path . resolve ( __dirname , './fixtures/config.json' )
206+ const argv = parser ( [ '--settings' , jsPath , '--foo' , 'bar' ] , {
207+ config : {
208+ s : function ( configPath ) {
209+ return JSON . parse ( readFileSync ( configPath , 'utf-8' ) )
210+ }
211+ } ,
212+ alias : {
213+ s : [ 'settings' ]
214+ }
215+ } )
216+
217+ argv . should . have . property ( 'herp' , 'derp' )
218+ argv . should . have . property ( 'foo' , 'bar' )
219+ } )
220+
221+ it ( 'outputs an error returned by the parsing function' , function ( ) {
222+ const argv = parser . detailed ( [ '--settings=./package.json' ] , {
223+ config : {
224+ settings : function ( configPath ) {
225+ return Error ( 'someone set us up the bomb' )
226+ }
227+ }
228+ } )
229+
230+ argv . error . message . should . equal ( 'someone set us up the bomb' )
231+ } )
232+
233+ it ( 'outputs an error if thrown by the parsing function' , function ( ) {
234+ const argv = parser . detailed ( [ '--settings=./package.json' ] , {
235+ config : {
236+ settings : function ( configPath ) {
237+ throw Error ( 'someone set us up the bomb' )
238+ }
239+ }
240+ } )
241+
242+ argv . error . message . should . equal ( 'someone set us up the bomb' )
243+ } )
244+
245+ it ( 'should not pollute the prototype' , function ( ) {
246+ const argv = parser ( [ '--foo' , 'bar' ] , {
247+ alias : {
248+ z : 'zoom'
249+ } ,
250+ default : {
251+ settings : jsonPath
252+ } ,
253+ config : 'settings'
254+ } )
255+
256+ argv . should . have . property ( 'herp' , 'derp' )
257+ argv . should . have . property ( 'zoom' , 55 )
258+ argv . should . have . property ( 'foo' ) . and . deep . equal ( 'bar' )
259+
260+ expect ( { } . bbb ) . to . equal ( undefined )
261+ expect ( { } . aaa ) . to . equal ( undefined )
262+ } )
263+ } )
264+ } )
0 commit comments