Skip to content

Commit 7ea2f81

Browse files
authored
Merge pull request #798 from motdotla/fix-tests
update tests to better handle multiple env files passed to path
2 parents 48a6ade + 6b829d2 commit 7ea2f81

File tree

1 file changed

+120
-102
lines changed

1 file changed

+120
-102
lines changed

tests/test-config.js

+120-102
Original file line numberDiff line numberDiff line change
@@ -7,197 +7,214 @@ const t = require('tap')
77

88
const dotenv = require('../lib/main')
99

10-
const mockParseResponse = { test: 'foo' }
11-
let readFileSyncStub
12-
let parseStub
13-
1410
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
2212
})
2313

2414
t.test('takes string for path option', ct => {
25-
ct.plan(1)
26-
2715
const testPath = 'tests/.env'
28-
dotenv.config({ path: testPath })
16+
const env = dotenv.config({ path: testPath })
2917

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()
3122
})
3223

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 })
3527

36-
const testPath = 'tests/.env'
37-
dotenv.config({ path: testPath })
28+
ct.equal(env.parsed.BASIC, 'basic')
29+
ct.equal(process.env.BASIC, 'basic')
3830

39-
ct.equal(readFileSyncStub.args[0][0], testPath)
31+
ct.end()
4032
})
4133

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 })
4437

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')
4740

48-
ct.equal(readFileSyncStub.args[0][0], testPath)
41+
ct.end()
4942
})
5043

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
5346

5447
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')
5653

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()
5863
})
5964

6065
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}`)
6268

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')
6573

66-
ct.equal(readFileSyncStub.args[0][0], testPath)
74+
ct.end()
6775
})
6876

6977
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')
7179
const mockedHomedir = '/Users/dummy'
7280
const homedirStub = sinon.stub(os, 'homedir').returns(mockedHomedir)
7381
const testPath = '~/.env'
7482
dotenv.config({ path: testPath })
7583

7684
ct.equal(readFileSyncStub.args[0][0], path.join(mockedHomedir, '.env'))
7785
ct.ok(homedirStub.called)
86+
7887
homedirStub.restore()
88+
readFileSyncStub.restore()
89+
ct.end()
7990
})
8091

8192
t.test('takes option for encoding', ct => {
82-
ct.plan(1)
93+
const readFileSyncStub = sinon.stub(fs, 'readFileSync').returns('test=foo')
8394

8495
const testEncoding = 'latin1'
8596
dotenv.config({ encoding: testEncoding })
86-
8797
ct.equal(readFileSyncStub.args[0][1].encoding, testEncoding)
98+
99+
readFileSyncStub.restore()
100+
ct.end()
88101
})
89102

90103
t.test('takes option for debug', ct => {
91-
ct.plan(1)
92-
93104
const logStub = sinon.stub(console, 'log')
94-
dotenv.config({ debug: 'true' })
95105

106+
dotenv.config({ debug: 'true' })
96107
ct.ok(logStub.called)
108+
97109
logStub.restore()
110+
ct.end()
98111
})
99112

100113
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' })
102116

103117
const res = dotenv.config()
104118

105-
ct.same(res.parsed, mockParseResponse)
119+
ct.same(res.parsed, { BASIC: 'basic' })
106120
ct.equal(readFileSyncStub.callCount, 1)
121+
122+
readFileSyncStub.restore()
123+
parseStub.restore()
124+
125+
ct.end()
107126
})
108127

109128
t.test('does not write over keys already in process.env', ct => {
110-
ct.plan(2)
111-
129+
const testPath = 'tests/.env'
112130
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)
116136

117-
ct.equal(env.parsed && env.parsed.test, mockParseResponse.test)
118-
ct.equal(process.env.test, existing)
137+
ct.end()
119138
})
120139

121140
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'
124142
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 })
164145

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 })
167157

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
169178

170179
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')
172186

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()
177188
})
178189

179190
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 })
183193

184194
ct.notOk(env.error)
185-
ct.same(env.parsed, mockParseResponse)
195+
ct.equal(env.parsed.BASIC, 'basic')
196+
197+
ct.end()
186198
})
187199

188200
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')
190202

191203
readFileSyncStub.throws()
192204
const env = dotenv.config()
193205

194206
ct.type(env.error, Error)
207+
208+
readFileSyncStub.restore()
209+
210+
ct.end()
195211
})
196212

197213
t.test('logs any errors thrown from reading file or parsing when in debug mode', ct => {
198214
ct.plan(2)
199215

200216
const logStub = sinon.stub(console, 'log')
217+
const readFileSyncStub = sinon.stub(fs, 'readFileSync').returns('test=foo')
201218

202219
readFileSyncStub.throws()
203220
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',
206223
ct.type(env.error, Error)
207224

208225
logStub.restore()
226+
readFileSyncStub.restore()
209227
})
210228

211229
t.test('logs any errors parsing when in debug and override mode', ct => {

0 commit comments

Comments
 (0)