3
declare(strict_types=1);
6
use Enjoys\Dotenv\Dotenv;
7
use PHPUnit\Framework\TestCase;
9
class DotenvTest extends TestCase
12
protected function setUp(): void
17
protected function tearDown(): void
23
* @param class-string|object $className
24
* @param string $propertyName
25
* @return ReflectionProperty
26
* @throws ReflectionException
28
public function getPrivateProperty($className, string $propertyName): ReflectionProperty
30
$reflector = new ReflectionClass($className);
31
$property = $reflector->getProperty($propertyName);
32
$property->setAccessible(true);
38
public function testVariableReplace()
40
$dotenv = new Dotenv(__DIR__ . '/fixtures/1/.env');
43
$this->assertSame('dev', $_ENV['APP_ENV']);
44
$this->assertSame('C:/openserver/test', $_ENV['TEST_DIR']);
47
public function testVariableReplace2()
49
putenv('APP_ENV=test');
50
$dotenv = new Dotenv(__DIR__ . '/fixtures/1/.env');
53
$this->assertSame('test', $_ENV['APP_ENV']);
54
$this->assertSame('/var/testing/test', $_ENV['TEST_DIR']);
55
putenv('APP_ENV'); //unset
58
public function testVariableReplaceRecursive()
60
$dotenv = new Dotenv(__DIR__ . '/fixtures/4/env');
63
$this->assertSame('/var/www/public', $_ENV['VAR2']);
64
$this->assertSame('/var/www/public/upload', $_ENV['VAR3']);
65
$this->assertSame('/var/www/public/upload', $_ENV['VAR4']);
66
$this->assertSame('/var/www/public/upload', $_ENV['VAR5']);
67
$this->assertSame('/var/www/public/upload', $_ENV['VAR6']);
68
$this->assertSame('/var/www/public/upload', $_ENV['VAR7']);
71
public function testVariableReplaceRecursiveNonLineage()
73
// $this->expectException(InvalidArgumentException::class);
74
$dotenv = new Dotenv(__DIR__ . '/fixtures/5/env');
76
$this->assertSame('/var/www/public', $_ENV['VAR2']);
77
$this->assertSame('/var/www/public/upload', $_ENV['VAR3']);
78
$this->assertSame('/var/www/public/upload', $_ENV['VAR4']);
79
$this->assertSame('/var/www/public/upload', $_ENV['VAR5']);
80
$this->assertSame('/var/www/public/upload', $_ENV['VAR6']);
83
public function testVariablesNotFound()
85
$this->expectExceptionMessage('Not set variable ${BAZ}.');
86
$dotenv = new Dotenv(__DIR__ . '/fixtures/invalid/.notfoundvars');
90
public function testCastType()
92
$dotenv = new Dotenv(__DIR__ . '/fixtures/2/.env');
93
$dotenv->enableCastType();
96
$this->assertSame("*int 42", $_ENV['VAR_1']);
97
$this->assertSame(2, $_ENV['VAR_1_1']);
98
$this->assertSame("*int 4", $_ENV['VAR_1_2']);
99
$this->assertSame('*int not digit', $_ENV['VAR_1_7']);
100
$this->assertSame("*string *int", $_ENV['VAR_1_8']);
101
$this->assertSame(42, $_ENV['VAR_1_3']);
102
$this->assertSame('test *int 5', $_ENV['VAR_1_4']);
103
$this->assertSame(0755, $_ENV['VAR_1_5']);
104
$this->assertSame(0xA, $_ENV['VAR_1_6']);
105
$this->assertSame(true, $_ENV['VAR_2']);
106
$this->assertSame(false, $_ENV['VAR_3']);
107
$this->assertSame(null, $_ENV['VAR_4']);
108
$this->assertSame(3.14, $_ENV['VAR_5']);
109
$this->assertSame(3.14, $_ENV['VAR_6']);
110
$this->assertSame(3.14, $_ENV['VAR_7']);
111
$this->assertSame(3.14, $_ENV['VAR_7_1']);
112
$this->assertSame('3.14', $_ENV['VAR_7_2']);
113
$this->assertSame('', $_ENV['VAR_8']);
114
$this->assertSame('va', $_ENV['VAR_9']);
117
public function testAutoCastType()
119
$dotenv = new Dotenv(__DIR__ . '/fixtures/2/.auto_cast_type');
120
$dotenv->enableCastType();
123
$this->assertSame(42, $_ENV['VAR_1']);
124
$this->assertSame("42", $_ENV['VAR_2']);
125
$this->assertSame("0755", $_ENV['VAR_3']);
126
$this->assertSame("0xA", $_ENV['VAR_4']);
127
$this->assertSame(true, $_ENV['VAR_5']);
128
$this->assertSame(false, $_ENV['VAR_6']);
129
$this->assertSame("", $_ENV['VAR_7']);
130
$this->assertSame(null, $_ENV['VAR_8']);
131
$this->assertSame(3.14, $_ENV['VAR_9']);
132
$this->assertSame(3.14, $_ENV['VAR_10']);
133
$this->assertSame("3.14", $_ENV['VAR_11']);
134
$this->assertSame("true", $_ENV['VAR_12']);
135
$this->assertSame("false", $_ENV['VAR_13']);
136
$this->assertSame($_ENV['VAR_5'], $_ENV['VAR_14']);
137
$this->assertSame($_ENV['VAR_6'], $_ENV['VAR_15']);
138
$this->assertSame($_ENV['VAR_1'], $_ENV['VAR_16']);
139
$this->assertSame($_ENV['VAR_10'], $_ENV['VAR_17']);
142
public function testEnvWithEq()
144
$dotenv = new Dotenv(__DIR__ . '/fixtures/3/.env.dist');
146
$this->assertSame('foo bar = zed', $_ENV['VAR']);
149
public function testUsePutEnvTrue()
151
$dotenv = new Dotenv(__DIR__ . '/fixtures/3/.env.dist');
152
$dotenv->loadEnv(true);
153
$this->assertSame('foo bar = zed', getenv('VAR'));
155
putenv('VAR'); //unset
158
public function testUsePutEnvFalse()
160
$dotenv = new Dotenv(__DIR__ . '/fixtures/3/.env.dist');
162
$this->assertSame(false, getenv('VAR'));
165
public function testNotOverriding()
167
$php_version = 'test';
168
putenv("PHP_VERSION=$php_version");
169
$dotenv = new Dotenv(__DIR__ . '/fixtures/3/.env.dist');
171
$this->assertSame($php_version, $_ENV['PHP_VERSION']);
173
putenv('PHP_VERSION'); //unset
176
public function testWithComment()
178
$dotenv = new Dotenv(__DIR__ . '/fixtures/with_comment/.env');
179
$dotenv->enableCastType();
181
$this->assertSame(false, $_ENV['MY_VAR'] ?? false);
182
$this->assertSame(' # 23', $_ENV['VAR2']);
183
$this->assertSame('/var/www', $_ENV['VAR3']);
184
$this->assertSame(null, $_ENV['VAR4']);
187
public function testInvalidKey()
189
$this->expectException(\Enjoys\Dotenv\Exception\InvalidArgumentException::class);
190
$dotenv = new Dotenv(__DIR__ . '/fixtures/invalid/.error.key');
195
public function testReplaceValueInEnvFilesDefinedInPutenvOrExport()
197
putenv('SYS_VAR=123');
198
putenv('SYS_VAR2=456');
199
$dotenv = new Dotenv(__DIR__ . '/fixtures/without_defined_vars/.env');
201
$this->assertSame('123', $_ENV['VAR2']);
202
$this->assertSame('456', $_ENV['VAR3']);
207
public function testReplaceValueInEnvFilesDefinedInPutenvOrExportButTheyWasBeDefinedInFiles()
209
putenv('SYS_VAR=SYS_VAR');
210
putenv('SYS_VAR2=SYS_VAR2');
211
putenv('DEFINED_VAR=987');
212
$dotenv = new Dotenv(__DIR__ . '/fixtures/without_defined_vars/.env');
214
$this->assertSame('987', $_ENV['VAR4']);
217
putenv('DEFINED_VAR');
220
public function testQuotes()
222
$dotenv = new Dotenv(__DIR__ . '/fixtures/with_qoutes_and_escaping/.quotes');
224
$this->assertSame("value in double quotes", $_ENV['VAR1']);
225
$this->assertSame('value without quotes', $_ENV['VAR2']);
226
$this->assertSame('value in single quotes', $_ENV['VAR3']);
227
$this->assertSame('va"', $_ENV['VAR4']);
228
$this->assertSame('va" lue"', $_ENV['VAR5']);
229
$this->assertSame("\#\"\\", $_ENV['VAR6']);
230
$this->assertSame("it\'s single quote", $_ENV['VAR7']);
231
$this->assertSame("it's double quote", $_ENV['VAR8']);
234
public function testSlashes()
236
putenv('VAR=test\"val');
237
$dotenv = new Dotenv(__DIR__ . '/fixtures/with_qoutes_and_escaping/.slashes');
239
$this->assertSame('double quote in middle " text', $_ENV['VAR1']);
240
$this->assertSame("value. it\'s var #2", $_ENV['VAR2']);
241
$this->assertSame("\\\\ - two backslashes. not's 4", $_ENV['VAR3']);
242
$this->assertSame('test\"val', $_ENV['VAR4']);
243
$this->assertSame($_ENV['VAR1'], $_ENV['VAR5']);
244
$this->assertSame($_ENV['VAR4'], $_ENV['VAR']);
248
public function testEnvArrayAndEnvRawArray()
250
$dotenv = new Dotenv(__DIR__ . '/fixtures/1/.env');
255
'TEST_DIR' => '${APP_DIR}/test',
256
'APP_DIR' => 'C:/openserver',
257
], $dotenv->getEnvRawArray());
261
'TEST_DIR' => 'C:/openserver/test',
262
'APP_DIR' => 'C:/openserver',
263
], $dotenv->getEnvCollection()->getCollection());
266
public function testAutoCastAndEnablePutEnv()
268
$dotenv = new Dotenv(
269
__DIR__ . '/fixtures/2/.auto_cast_type'
271
$dotenv->enableCastType();
272
$dotenv->loadEnv(true);
273
$this->assertSame('42', getenv('VAR_1'));
274
$this->assertSame('3.14', getenv('VAR_10'));
275
$this->assertSame('true', getenv('VAR_5'));
276
$this->assertSame('false', getenv('VAR_6'));
277
$this->assertSame('', getenv('VAR_8'));
280
public function testMultiline()
282
$dotenv = new Dotenv(__DIR__ . '/fixtures/multiline/.env');
283
$dotenv->loadEnv(true);
291
$_ENV['VAR_MULTILINE']
299
getenv('VAR_MULTILINE')
301
$this->assertSame('1\n2', $_ENV['VAR_NON_MULTILINE']);
302
$this->assertSame('1\n2', getenv('VAR_NON_MULTILINE'));
310
$_ENV['VAR_MULTILINE2']
318
getenv('VAR_MULTILINE2')
322
public function testMultiline1()
324
$dotenv = new Dotenv(__DIR__ . '/fixtures/multiline/1');
338
public function testMultiline2()
340
$dotenv = new Dotenv(__DIR__ . '/fixtures/multiline/2');
355
public function testMultiline3()
357
$dotenv = new Dotenv(__DIR__ . '/fixtures/multiline/3');
370
public function testMultilineInvalid()
372
$this->expectException(\Enjoys\Dotenv\Exception\InvalidArgumentException::class);
373
$dotenv = new Dotenv(__DIR__ . '/fixtures/multiline/.invalid');
377
public function testClear()
379
$dotenv = new Dotenv(__DIR__ . '/fixtures/1/.env');
380
$dotenv->loadEnv(true);
381
$enjoysDotenvArray = $dotenv->getEnvCollection()->getKeys();
382
$this->assertSame(implode(",", $enjoysDotenvArray), getenv('ENJOYS_DOTENV'));
384
foreach ($enjoysDotenvArray as $key) {
385
$this->assertFalse(getenv($key));
386
$this->assertFalse($_ENV[$key] ?? false);
388
$this->assertFalse(getenv('ENJOYS_DOTENV'));
391
public function testLoadAppEnvFile()
393
$dotenv = new Dotenv(__DIR__ . '/fixtures/loadAppEnvFile/.env');
395
$this->assertSame('loaded .env.true', $_ENV['LOADED']);
398
public function testNestedManyTimesAppEnvFromFiles()
400
$dotenv = new Dotenv(__DIR__ . '/fixtures/nestedAppEnv/.env');
402
$this->assertCount(6, $dotenv->getLoadedPaths());
403
$this->assertSame('5', $_ENV['VAR']);
407
], $dotenv->getEnvCollection()->getCollection());
411
], $dotenv->getEnvRawArray());
414
public function testNestedManyTimesAppEnvFromGetEnv()
417
$dotenv = new Dotenv(__DIR__ . '/fixtures/nestedAppEnv/.env');
419
$this->assertCount(2, $dotenv->getLoadedPaths());
423
], $dotenv->getEnvCollection()->getCollection());
427
], $dotenv->getEnvRawArray());
428
$this->assertSame('3', $_ENV['VAR']);
431
public function testOtherImplementationStorage()
433
$storage = $this->getMockForAbstractClass(\Enjoys\Dotenv\StorageInterface::class);
434
$dotenv = new Dotenv(__DIR__ . '/fixtures/1/.env', storage: $storage);
436
$this->assertSame([], $dotenv->getLoadedPaths());
439
public function testOtherImplementationParser()
441
$parser = $this->getMockForAbstractClass(\Enjoys\Dotenv\Parser\ParserInterface::class);
442
$dotenv = new Dotenv(__DIR__ . '/fixtures/1/.env', parser: $parser);
444
$this->assertSame([], $dotenv->getEnvCollection()->getCollection());
449
* @dataProvider dataForTestHandleValue
451
public function testHandleValue($key, $string, $expect)
453
$dotenv = new Dotenv(__DIR__ . '/fixtures/1/.env', flags: Dotenv::CAST_TYPE_ENV_VALUE);
454
$this->assertSame($expect, $dotenv->handleValue($key, $string));
458
public function dataForTestHandleValue()
462
['VAR', '"42"', '42'],
463
['VAR', "'42'", '42'],
465
['VAR', 'str\\\'ing', 'str\\\'ing'],
466
['VAR', '"str\\\'ing"', 'str\'ing'],
467
['VAR', "'str\\'ing'", 'str\\\'ing'],
471
public function testCommentWithSpecificSymbols()
473
$dotenv = new Dotenv(__DIR__ . '/fixtures/.comment_with_specific_symbols');
475
$this->assertSame("1", $_ENV['VAR']);