getMessage()}\n"); exit(1); } } function assertSameValue(mixed $expected, mixed $actual, string $message): void { if ($expected !== $actual) { throw new RuntimeException($message . ' Expected ' . var_export($expected, true) . ', got ' . var_export($actual, true) . '.'); } } function clearEnvKey(string $key): void { putenv($key); unset($_ENV[$key], $_SERVER[$key]); } /** * @param list $lines */ function withTempEnvFile(array $lines): string { $path = tempnam(sys_get_temp_dir(), 'voipms-env-'); if ($path === false) { throw new RuntimeException('Unable to create temp env file.'); } file_put_contents($path, implode("\n", $lines) . "\n"); return $path; } runTest('loads simple and quoted .env values', function (): void { foreach (['VOIPMS_TEST_SIMPLE', 'VOIPMS_TEST_SINGLE', 'VOIPMS_TEST_DOUBLE', 'VOIPMS_TEST_EMPTY'] as $key) { clearEnvKey($key); } $path = withTempEnvFile([ '# comment', '', 'VOIPMS_TEST_SIMPLE=value', "VOIPMS_TEST_SINGLE='single quoted value'", 'VOIPMS_TEST_DOUBLE="double quoted value"', 'VOIPMS_TEST_EMPTY=', ]); try { EnvLoader::load($path); assertSameValue('value', getenv('VOIPMS_TEST_SIMPLE'), 'Simple value should be available through getenv().'); assertSameValue('single quoted value', $_ENV['VOIPMS_TEST_SINGLE'] ?? null, 'Single quoted value should be available through $_ENV.'); assertSameValue('double quoted value', $_SERVER['VOIPMS_TEST_DOUBLE'] ?? null, 'Double quoted value should be available through $_SERVER.'); assertSameValue('', getenv('VOIPMS_TEST_EMPTY'), 'Empty value should be loaded.'); } finally { unlink($path); foreach (['VOIPMS_TEST_SIMPLE', 'VOIPMS_TEST_SINGLE', 'VOIPMS_TEST_DOUBLE', 'VOIPMS_TEST_EMPTY'] as $key) { clearEnvKey($key); } } }); runTest('does not override existing process environment', function (): void { clearEnvKey('VOIPMS_TEST_OVERRIDE'); putenv('VOIPMS_TEST_OVERRIDE=from-process'); $_ENV['VOIPMS_TEST_OVERRIDE'] = 'from-process'; $_SERVER['VOIPMS_TEST_OVERRIDE'] = 'from-process'; $path = withTempEnvFile([ 'VOIPMS_TEST_OVERRIDE=from-file', ]); try { EnvLoader::load($path); assertSameValue('from-process', getenv('VOIPMS_TEST_OVERRIDE'), 'Existing getenv() value should win.'); assertSameValue('from-process', $_ENV['VOIPMS_TEST_OVERRIDE'] ?? null, 'Existing $_ENV value should win.'); assertSameValue('from-process', $_SERVER['VOIPMS_TEST_OVERRIDE'] ?? null, 'Existing $_SERVER value should win.'); } finally { unlink($path); clearEnvKey('VOIPMS_TEST_OVERRIDE'); } }); runTest('ignores missing .env files', function (): void { EnvLoader::load(sys_get_temp_dir() . '/voipms-missing-env-file'); });