@@ -7,197 +7,214 @@ const t = require('tap')
7
7
8
8
const dotenv = require ( '../lib/main' )
9
9
10
- const mockParseResponse = { test : 'foo' }
11
- let readFileSyncStub
12
- let parseStub
13
-
14
10
t . beforeEach ( ( ) => {
15
- readFileSyncStub = sinon . stub ( fs , 'readFileSync' ) . returns ( 'test=foo' )
16
- parseStub = sinon . stub ( dotenv , 'parse' ) . returns ( mockParseResponse )
17
- } )
18
-
19
- t . afterEach ( ( ) => {
20
- readFileSyncStub . restore ( )
21
- parseStub . restore ( )
11
+ delete process . env . BASIC // reset
22
12
} )
23
13
24
14
t . test ( 'takes string for path option' , ct => {
25
- ct . plan ( 1 )
26
-
27
15
const testPath = 'tests/.env'
28
- dotenv . config ( { path : testPath } )
16
+ const env = dotenv . config ( { path : testPath } )
29
17
30
- ct . equal ( readFileSyncStub . args [ 0 ] [ 0 ] , testPath )
18
+ ct . equal ( env . parsed . BASIC , 'basic' )
19
+ ct . equal ( process . env . BASIC , 'basic' )
20
+
21
+ ct . end ( )
31
22
} )
32
23
33
- t . test ( 'takes string for path option' , ct => {
34
- ct . plan ( 1 )
24
+ t . test ( 'takes array for path option' , ct => {
25
+ const testPath = [ 'tests/.env' ]
26
+ const env = dotenv . config ( { path : testPath } )
35
27
36
- const testPath = 'tests/. env'
37
- dotenv . config ( { path : testPath } )
28
+ ct . equal ( env . parsed . BASIC , 'basic' )
29
+ ct . equal ( process . env . BASIC , 'basic' )
38
30
39
- ct . equal ( readFileSyncStub . args [ 0 ] [ 0 ] , testPath )
31
+ ct . end ( )
40
32
} )
41
33
42
- t . test ( 'takes array for path option' , ct => {
43
- ct . plan ( 1 )
34
+ t . test ( 'takes two or more files in the array for path option' , ct => {
35
+ const testPath = [ 'tests/.env.local' , 'tests/.env' ]
36
+ const env = dotenv . config ( { path : testPath } )
44
37
45
- const testPath = [ 'tests/. env' ]
46
- dotenv . config ( { path : testPath } )
38
+ ct . equal ( env . parsed . BASIC , 'local_basic' )
39
+ ct . equal ( process . env . BASIC , 'local_basic' )
47
40
48
- ct . equal ( readFileSyncStub . args [ 0 ] [ 0 ] , testPath )
41
+ ct . end ( )
49
42
} )
50
43
51
- t . test ( 'takes two or more files in the array for path option' , ct => {
52
- ct . plan ( 1 )
44
+ t . test ( 'sets values from both .env.local and .env. first file key wins.' , { skip : true } , ct => {
45
+ delete process . env . SINGLE_QUOTES
53
46
54
47
const testPath = [ 'tests/.env.local' , 'tests/.env' ]
55
- dotenv . config ( { path : testPath } )
48
+ const env = dotenv . config ( { path : testPath } )
49
+
50
+ // in both files - first file wins (.env.local)
51
+ ct . equal ( env . parsed . BASIC , 'local_basic' )
52
+ ct . equal ( process . env . BASIC , 'local_basic' )
56
53
57
- ct . equal ( readFileSyncStub . args [ 0 ] [ 0 ] , testPath )
54
+ // in .env.local only
55
+ ct . equal ( env . parsed . LOCAL , 'local' )
56
+ ct . equal ( process . env . LOCAL , 'local' )
57
+
58
+ // in .env only
59
+ ct . equal ( env . parsed . SINGLE_QUOTES , 'single_quotes' )
60
+ ct . equal ( process . env . SINGLE_QUOTES , 'single_quotes' )
61
+
62
+ ct . end ( )
58
63
} )
59
64
60
65
t . test ( 'takes URL for path option' , ct => {
61
- ct . plan ( 1 )
66
+ const envPath = path . resolve ( __dirname , '.env' )
67
+ const fileUrl = new URL ( `file://${ envPath } ` )
62
68
63
- const testPath = new URL ( 'file://home/user/project/.env' )
64
- dotenv . config ( { path : testPath } )
69
+ const env = dotenv . config ( { path : fileUrl } )
70
+
71
+ ct . equal ( env . parsed . BASIC , 'basic' )
72
+ ct . equal ( process . env . BASIC , 'basic' )
65
73
66
- ct . equal ( readFileSyncStub . args [ 0 ] [ 0 ] , testPath )
74
+ ct . end ( )
67
75
} )
68
76
69
77
t . test ( 'takes option for path along with home directory char ~' , ct => {
70
- ct . plan ( 2 )
78
+ const readFileSyncStub = sinon . stub ( fs , 'readFileSync' ) . returns ( 'test=foo' )
71
79
const mockedHomedir = '/Users/dummy'
72
80
const homedirStub = sinon . stub ( os , 'homedir' ) . returns ( mockedHomedir )
73
81
const testPath = '~/.env'
74
82
dotenv . config ( { path : testPath } )
75
83
76
84
ct . equal ( readFileSyncStub . args [ 0 ] [ 0 ] , path . join ( mockedHomedir , '.env' ) )
77
85
ct . ok ( homedirStub . called )
86
+
78
87
homedirStub . restore ( )
88
+ readFileSyncStub . restore ( )
89
+ ct . end ( )
79
90
} )
80
91
81
92
t . test ( 'takes option for encoding' , ct => {
82
- ct . plan ( 1 )
93
+ const readFileSyncStub = sinon . stub ( fs , 'readFileSync' ) . returns ( 'test=foo' )
83
94
84
95
const testEncoding = 'latin1'
85
96
dotenv . config ( { encoding : testEncoding } )
86
-
87
97
ct . equal ( readFileSyncStub . args [ 0 ] [ 1 ] . encoding , testEncoding )
98
+
99
+ readFileSyncStub . restore ( )
100
+ ct . end ( )
88
101
} )
89
102
90
103
t . test ( 'takes option for debug' , ct => {
91
- ct . plan ( 1 )
92
-
93
104
const logStub = sinon . stub ( console , 'log' )
94
- dotenv . config ( { debug : 'true' } )
95
105
106
+ dotenv . config ( { debug : 'true' } )
96
107
ct . ok ( logStub . called )
108
+
97
109
logStub . restore ( )
110
+ ct . end ( )
98
111
} )
99
112
100
113
t . test ( 'reads path with encoding, parsing output to process.env' , ct => {
101
- ct . plan ( 2 )
114
+ const readFileSyncStub = sinon . stub ( fs , 'readFileSync' ) . returns ( 'BASIC=basic' )
115
+ const parseStub = sinon . stub ( dotenv , 'parse' ) . returns ( { BASIC : 'basic' } )
102
116
103
117
const res = dotenv . config ( )
104
118
105
- ct . same ( res . parsed , mockParseResponse )
119
+ ct . same ( res . parsed , { BASIC : 'basic' } )
106
120
ct . equal ( readFileSyncStub . callCount , 1 )
121
+
122
+ readFileSyncStub . restore ( )
123
+ parseStub . restore ( )
124
+
125
+ ct . end ( )
107
126
} )
108
127
109
128
t . test ( 'does not write over keys already in process.env' , ct => {
110
- ct . plan ( 2 )
111
-
129
+ const testPath = 'tests/.env'
112
130
const existing = 'bar'
113
- process . env . test = existing
114
- // 'foo' returned as value in `beforeEach`. should keep this 'bar'
115
- const env = dotenv . config ( )
131
+ process . env . BASIC = existing
132
+ const env = dotenv . config ( { path : testPath } )
133
+
134
+ ct . equal ( env . parsed . BASIC , 'basic' )
135
+ ct . equal ( process . env . BASIC , existing )
116
136
117
- ct . equal ( env . parsed && env . parsed . test , mockParseResponse . test )
118
- ct . equal ( process . env . test , existing )
137
+ ct . end ( )
119
138
} )
120
139
121
140
t . test ( 'does write over keys already in process.env if override turned on' , ct => {
122
- ct . plan ( 2 )
123
-
141
+ const testPath = 'tests/.env'
124
142
const existing = 'bar'
125
- process . env . test = existing
126
- // 'foo' returned as value in `beforeEach`. should keep this 'bar'
127
- const env = dotenv . config ( { override : true } )
128
-
129
- ct . equal ( env . parsed && env . parsed . test , mockParseResponse . test )
130
- ct . equal ( process . env . test , 'foo' )
131
- } )
132
-
133
- t . test (
134
- 'does not write over keys already in process.env if the key has a falsy value' ,
135
- ct => {
136
- ct . plan ( 2 )
137
-
138
- const existing = ''
139
- process . env . test = existing
140
- // 'foo' returned as value in `beforeEach`. should keep this ''
141
- const env = dotenv . config ( )
142
-
143
- ct . equal ( env . parsed && env . parsed . test , mockParseResponse . test )
144
- // NB: process.env.test becomes undefined on Windows
145
- ct . notOk ( process . env . test )
146
- }
147
- )
148
-
149
- t . test (
150
- 'does write over keys already in process.env if the key has a falsy value but override is set to true' ,
151
- ct => {
152
- ct . plan ( 2 )
153
-
154
- const existing = ''
155
- process . env . test = existing
156
- // 'foo' returned as value in `beforeEach`. should keep this ''
157
- const env = dotenv . config ( { override : true } )
158
-
159
- ct . equal ( env . parsed && env . parsed . test , mockParseResponse . test )
160
- // NB: process.env.test becomes undefined on Windows
161
- ct . ok ( process . env . test )
162
- }
163
- )
143
+ process . env . BASIC = existing
144
+ const env = dotenv . config ( { path : testPath , override : true } )
164
145
165
- t . test ( 'can write to a different object rather than process.env' , ct => {
166
- ct . plan ( 3 )
146
+ ct . equal ( env . parsed . BASIC , 'basic' )
147
+ ct . equal ( process . env . BASIC , 'basic' )
148
+
149
+ ct . end ( )
150
+ } )
151
+
152
+ t . test ( 'does not write over keys already in process.env if the key has a falsy value' , ct => {
153
+ const testPath = 'tests/.env'
154
+ const existing = ''
155
+ process . env . BASIC = existing
156
+ const env = dotenv . config ( { path : testPath } )
167
157
168
- process . env . test = 'other' // reset process.env
158
+ ct . equal ( env . parsed . BASIC , 'basic' )
159
+ ct . equal ( process . env . BASIC , '' )
160
+
161
+ ct . end ( )
162
+ } )
163
+
164
+ t . test ( 'does write over keys already in process.env if the key has a falsy value but override is set to true' , ct => {
165
+ const testPath = 'tests/.env'
166
+ const existing = ''
167
+ process . env . BASIC = existing
168
+ const env = dotenv . config ( { path : testPath , override : true } )
169
+
170
+ ct . equal ( env . parsed . BASIC , 'basic' )
171
+ ct . equal ( process . env . BASIC , 'basic' )
172
+ ct . end ( )
173
+ } )
174
+
175
+ t . test ( 'can write to a different object rather than process.env' , ct => {
176
+ const testPath = 'tests/.env'
177
+ process . env . BASIC = 'other' // reset process.env
169
178
170
179
const myObject = { }
171
- const env = dotenv . config ( { processEnv : myObject } )
180
+ const env = dotenv . config ( { path : testPath , processEnv : myObject } )
181
+
182
+ ct . equal ( env . parsed . BASIC , 'basic' )
183
+ console . log ( 'logging' , process . env . BASIC )
184
+ ct . equal ( process . env . BASIC , 'other' )
185
+ ct . equal ( myObject . BASIC , 'basic' )
172
186
173
- ct . equal ( env . parsed && env . parsed . test , mockParseResponse . test )
174
- console . log ( 'logging' , process . env . test )
175
- ct . equal ( process . env . test , 'other' )
176
- ct . equal ( myObject . test , mockParseResponse . test )
187
+ ct . end ( )
177
188
} )
178
189
179
190
t . test ( 'returns parsed object' , ct => {
180
- ct . plan ( 2 )
181
-
182
- const env = dotenv . config ( )
191
+ const testPath = 'tests/.env'
192
+ const env = dotenv . config ( { path : testPath } )
183
193
184
194
ct . notOk ( env . error )
185
- ct . same ( env . parsed , mockParseResponse )
195
+ ct . equal ( env . parsed . BASIC , 'basic' )
196
+
197
+ ct . end ( )
186
198
} )
187
199
188
200
t . test ( 'returns any errors thrown from reading file or parsing' , ct => {
189
- ct . plan ( 1 )
201
+ const readFileSyncStub = sinon . stub ( fs , 'readFileSync' ) . returns ( 'test=foo' )
190
202
191
203
readFileSyncStub . throws ( )
192
204
const env = dotenv . config ( )
193
205
194
206
ct . type ( env . error , Error )
207
+
208
+ readFileSyncStub . restore ( )
209
+
210
+ ct . end ( )
195
211
} )
196
212
197
213
t . test ( 'logs any errors thrown from reading file or parsing when in debug mode' , ct => {
198
214
ct . plan ( 2 )
199
215
200
216
const logStub = sinon . stub ( console , 'log' )
217
+ const readFileSyncStub = sinon . stub ( fs , 'readFileSync' ) . returns ( 'test=foo' )
201
218
202
219
readFileSyncStub . throws ( )
203
220
const env = dotenv . config ( { debug : true } )
@@ -206,6 +223,7 @@ t.test('logs any errors thrown from reading file or parsing when in debug mode',
206
223
ct . type ( env . error , Error )
207
224
208
225
logStub . restore ( )
226
+ readFileSyncStub . restore ( )
209
227
} )
210
228
211
229
t . test ( 'logs any errors parsing when in debug and override mode' , ct => {
0 commit comments