diff --git a/README.md b/README.md index 1bfb044d..49d192b6 100644 --- a/README.md +++ b/README.md @@ -84,14 +84,14 @@ SECRET_KEY="abc123" You can then load `.env` in your application with: ```php -$dotenv = new Dotenv\Dotenv(__DIR__); +$dotenv = Dotenv\Dotenv::create(__DIR__); $dotenv->load(); ``` Optionally you can pass in a filename as the second parameter, if you would like to use something other than `.env` ```php -$dotenv = new Dotenv\Dotenv(__DIR__, 'myconfig'); +$dotenv = Dotenv\Dotenv::create(__DIR__, 'myconfig'); $dotenv->load(); ``` @@ -136,10 +136,26 @@ If you want Dotenv to overwrite existing environment variables, use `overload` instead of `load`: ```php -$dotenv = new Dotenv\Dotenv(__DIR__); +$dotenv = Dotenv\Dotenv::create(__DIR__); $dotenv->overload(); ``` +### Loader Customization + +Need us to not set `$_ENV` but not `$_SERVER`, or have other custom requirements? No problem! Simply pass a custom implementation of `Dotenv\Environment\FactoryInterface` to `Dotenv\Loader` on construction. In practice, you may not even need a custom implementation, since our default implementation allows you provide an array of `Dotenv\Environment\Adapter\AdapterInterface` for proxing the underlying calls to. + +For example, if you want us to only ever fiddle with `$_ENV` and `putenv`, then you can setup Dotenv as follows: + +```php +$factory = new Dotenv\Environment\DotenvFactory([ + new Dotenv\Environment\Adapter\EnvConstAdapter(), + new Dotenv\Environment\Adapter\PutenvAdapter(), +]); + +$dotenv = Dotenv\Dotenv::create(__DIR__, null, $factory); +``` + + Requiring Variables to be Set ----------------------------- diff --git a/composer.json b/composer.json index 4da4e222..ab6c5fdd 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,8 @@ } ], "require": { - "php": "^5.4 || ^7.0" + "php": "^5.4 || ^7.0", + "phpoption/phpoption": "^1.5" }, "require-dev": { "phpunit/phpunit": "^4.8.35 || ^5.0 || ^6.0" diff --git a/src/Dotenv.php b/src/Dotenv.php index d1e423eb..e168c2bb 100644 --- a/src/Dotenv.php +++ b/src/Dotenv.php @@ -2,6 +2,8 @@ namespace Dotenv; +use Dotenv\Environment\DotenvFactory; +use Dotenv\Environment\FactoryInterface; use Dotenv\Exception\InvalidPathException; /** @@ -13,36 +15,69 @@ class Dotenv { /** - * The file path. + * The loader instance. * - * @var string + * @var \Dotenv\Loader */ - protected $filePath; + protected $loader; /** - * The loader instance. + * Create a new dotenv instance. + * + * @param \Dotenv\Loader $loader * - * @var \Dotenv\Loader|null + * @return void */ - protected $loader; + public function __construct(Loader $loader) + { + $this->loader = $loader; + } /** * Create a new dotenv instance. * - * @param string $path - * @param string $file + * @param string $path + * @param string|null $file + * @param \Dotenv\Environment\FactoryInterface|null $envFactory * - * @return void + * @return \Dotenv\Dotenv + */ + public static function create($path, $file = null, FactoryInterface $envFactory = null) + { + $loader = new Loader( + self::getFilePath($path, $file), + $envFactory ?: new DotenvFactory(), + true + ); + + return new Dotenv($loader); + } + + + /** + * Returns the full path to the file. + * + * @param string $path + * @param string|null $file + * + * @return string */ - public function __construct($path, $file = '.env') + private static function getFilePath($path, $file) { - $this->filePath = $this->getFilePath($path, $file); - $this->loader = new Loader($this->filePath, true); + if (!is_string($file)) { + $file = '.env'; + } + + $filePath = rtrim($path, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.$file; + + return $filePath; } /** * Load environment file in given directory. * + * @throws \Dotenv\Exception\InvalidPathException|\Dotenv\Exception\InvalidFileException + * * @return array */ public function load() @@ -68,6 +103,8 @@ public function safeLoad() /** * Load environment file in given directory. * + * @throws \Dotenv\Exception\InvalidPathException|\Dotenv\Exception\InvalidFileException + * * @return array */ public function overload() @@ -75,30 +112,13 @@ public function overload() return $this->loadData(true); } - /** - * Returns the full path to the file. - * - * @param string $path - * @param string $file - * - * @return string - */ - protected function getFilePath($path, $file) - { - if (!is_string($file)) { - $file = '.env'; - } - - $filePath = rtrim($path, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.$file; - - return $filePath; - } - /** * Actually load the data. * * @param bool $overload * + * @throws \Dotenv\Exception\InvalidPathException|\Dotenv\Exception\InvalidFileException + * * @return array */ protected function loadData($overload = false) @@ -121,10 +141,10 @@ public function required($variable) /** * Get the list of environment variables declared inside the 'env' file. * - * @return array + * @return string[] */ public function getEnvironmentVariableNames() { - return $this->loader->variableNames; + return $this->loader->getEnvironmentVariableNames(); } } diff --git a/src/Environment/AbstractVariables.php b/src/Environment/AbstractVariables.php new file mode 100644 index 00000000..1b30d2cc --- /dev/null +++ b/src/Environment/AbstractVariables.php @@ -0,0 +1,86 @@ +immutable = $immutable; + } + + /** + * Determine if the environment is immutable. + * + * @return bool + */ + public function isImmutable() + { + return $this->immutable; + } + + /** + * Tells whether environment variable has been defined. + * + * @param string $name + * + * @return bool + */ + public function has($name) + { + return !is_null($this->get($name)); + } + + /** + * {@inheritdoc} + */ + public function offsetExists($offset) + { + return $this->has($offset); + } + + /** + * {@inheritdoc} + */ + public function offsetGet($offset) + { + return $this->get($offset); + } + + /** + * {@inheritdoc} + */ + public function offsetSet($offset, $value) + { + $this->set($offset, $value); + } + + /** + * {@inheritdoc} + */ + public function offsetUnset($offset) + { + $this->clear($offset); + } +} diff --git a/src/Environment/Adapter/AdapterInterface.php b/src/Environment/Adapter/AdapterInterface.php new file mode 100644 index 00000000..21ef29a1 --- /dev/null +++ b/src/Environment/Adapter/AdapterInterface.php @@ -0,0 +1,41 @@ +adapters = array_filter($adapters ?: [new ApacheAdapter(), new EnvConstAdapter(), new ServerConstAdapter(), new PutenvAdapter()], function (AdapterInterface $adapter) { + return $adapter->isSupported(); + }); + } + + /** + * Creates a new mutable environment variables instance. + * + * @return \Dotenv\Environment\VariablesInterface + */ + public function create() + { + return new DotenvVariables($this->adapters, false); + } + + /** + * Creates a new immutable environment variables instance. + * + * @return \Dotenv\Environment\VariablesInterface + */ + public function createImmutable() + { + return new DotenvVariables($this->adapters, true); + } +} diff --git a/src/Environment/DotenvVariables.php b/src/Environment/DotenvVariables.php new file mode 100644 index 00000000..5daadb45 --- /dev/null +++ b/src/Environment/DotenvVariables.php @@ -0,0 +1,89 @@ +adapters = $adapters; + parent::__construct($immutable); + } + + /** + * Get an environment variable. + * + * We do this by querying our adapters sequentially. + * + * @param string $name + * + * @return string|null + */ + public function get($name) + { + foreach ($this->adapters as $adapter) { + $result = $adapter->get($name); + if ($result->isDefined()) { + return $result->get(); + } + } + } + + /** + * Set an environment variable. + * + * @param string $name + * @param string|null $value + * + * @return void + */ + public function set($name, $value = null) + { + // Don't overwrite existing environment variables if we're immutable + // Ruby's dotenv does this with `ENV[key] ||= value`. + if ($this->isImmutable() && $this->get($name) !== null) { + return; + } + + foreach ($this->adapters as $adapter) { + $adapter->set($name, $value); + } + } + + /** + * Clear an environment variable. + * + * @param string $name + * + * @return void + */ + public function clear($name) + { + // Don't clear anything if we're immutable. + if ($this->isImmutable()) { + return; + } + + foreach ($this->adapters as $adapter) { + $adapter->clear($name); + } + } +} diff --git a/src/Environment/FactoryInterface.php b/src/Environment/FactoryInterface.php new file mode 100644 index 00000000..3d9f489b --- /dev/null +++ b/src/Environment/FactoryInterface.php @@ -0,0 +1,26 @@ +filePath = $filePath; - $this->immutable = $immutable; + $this->envFactory = $envFactory; + $this->setImmutable($immutable); } /** @@ -60,24 +70,18 @@ public function __construct($filePath, $immutable = false) */ public function setImmutable($immutable = false) { - $this->immutable = $immutable; + $this->envVariables = $immutable + ? $this->envFactory->createImmutable() + : $this->envFactory->create(); return $this; } - /** - * Get immutable value. - * - * @return bool - */ - public function getImmutable() - { - return $this->immutable; - } - /** * Load `.env` file in given directory. * + * @throws \Dotenv\Exception\InvalidPathException|\Dotenv\Exception\InvalidFileException + * * @return array */ public function load() @@ -125,8 +129,10 @@ protected function ensureFileIsReadable() * - cleaning the name of quotes, * - resolving nested variables. * - * @param string $name - * @param string $value + * @param string $name + * @param string|null $value + * + * @throws \Dotenv\Exception\InvalidFileException * * @return array */ @@ -144,8 +150,10 @@ protected function normaliseEnvironmentVariable($name, $value) * * Called from `normaliseEnvironmentVariable` and the `VariableFactory`, passed as a callback in `$this->loadFromFile()`. * - * @param string $name - * @param string $value + * @param string $name + * @param string|null $value + * + * @throws \Dotenv\Exception\InvalidFileException * * @return array */ @@ -260,8 +268,8 @@ protected function looksLikeMultilineStop($line) * If the `$name` contains an `=` sign, then we split it into 2 parts, a `name` & `value` * disregarding the `$value` passed in. * - * @param string $name - * @param string $value + * @param string $name + * @param string|null $value * * @return array */ @@ -277,8 +285,8 @@ protected function splitCompoundStringIntoParts($name, $value) /** * Strips quotes from the environment variable value. * - * @param string $name - * @param string $value + * @param string $name + * @param string|null $value * * @throws \Dotenv\Exception\InvalidFileException * @@ -286,8 +294,12 @@ protected function splitCompoundStringIntoParts($name, $value) */ protected function sanitiseVariableValue($name, $value) { + if ($value === null) { + return [$name, $value]; + } + $value = trim($value); - if (!$value) { + if ($value === '') { return [$name, $value]; } @@ -396,31 +408,19 @@ protected function beginsWithAQuote($value) */ public function getEnvironmentVariable($name) { - switch (true) { - case array_key_exists($name, $_ENV): - return $_ENV[$name]; - case array_key_exists($name, $_SERVER): - return $_SERVER[$name]; - default: - $value = getenv($name); - - return $value === false ? null : $value; // switch getenv default to null - } + return $this->envVariables->get($name); } /** * Set an environment variable. * - * This is done using: - * - putenv, - * - $_ENV, - * - $_SERVER. - * * The environment variable value is stripped of single and double quotes. * * @param string $name * @param string|null $value * + * @throws \Dotenv\Exception\InvalidFileException + * * @return void */ public function setEnvironmentVariable($name, $value = null) @@ -429,53 +429,30 @@ public function setEnvironmentVariable($name, $value = null) $this->variableNames[] = $name; - // Don't overwrite existing environment variables if we're immutable - // Ruby's dotenv does this with `ENV[key] ||= value`. - if ($this->immutable && $this->getEnvironmentVariable($name) !== null) { - return; - } - - // If PHP is running as an Apache module and an existing - // Apache environment variable exists, overwrite it - if (function_exists('apache_getenv') && function_exists('apache_setenv') && apache_getenv($name) !== false) { - apache_setenv($name, $value); - } - - if (function_exists('putenv')) { - putenv("$name=$value"); - } - - $_ENV[$name] = $value; - $_SERVER[$name] = $value; + $this->envVariables->set($name, $value); } /** * Clear an environment variable. * - * This is not (currently) used by Dotenv but is provided as a utility - * method for 3rd party code. - * - * This is done using: - * - putenv, - * - unset($_ENV, $_SERVER). + * This method only expects names in normal form. * * @param string $name * - * @see setEnvironmentVariable() - * * @return void */ public function clearEnvironmentVariable($name) { - // Don't clear anything if we're immutable. - if ($this->immutable) { - return; - } - - if (function_exists('putenv')) { - putenv($name); - } + $this->envVariables->clear($name); + } - unset($_ENV[$name], $_SERVER[$name]); + /** + * Get the list of environment variables names. + * + * @return string[] + */ + public function getEnvironmentVariableNames() + { + return $this->variableNames; } } diff --git a/src/Validator.php b/src/Validator.php index 0a309646..9132f16d 100644 --- a/src/Validator.php +++ b/src/Validator.php @@ -15,7 +15,7 @@ class Validator /** * The variables to validate. * - * @var array + * @var string[] */ protected $variables; @@ -29,9 +29,11 @@ class Validator /** * Create a new validator instance. * - * @param array $variables + * @param string[] $variables * @param \Dotenv\Loader $loader * + * @throws \Dotenv\Exception\ValidationException + * * @return void */ public function __construct(array $variables, Loader $loader) @@ -50,6 +52,8 @@ function ($value) { /** * Assert that each variable is not empty. * + * @throws \Dotenv\Exception\ValidationException + * * @return \Dotenv\Validator */ public function notEmpty() @@ -65,6 +69,8 @@ function ($value) { /** * Assert that each specified variable is an integer. * + * @throws \Dotenv\Exception\ValidationException + * * @return \Dotenv\Validator */ public function isInteger() @@ -80,6 +86,8 @@ function ($value) { /** * Assert that each specified variable is a boolean. * + * @throws \Dotenv\Exception\ValidationException + * * @return \Dotenv\Validator */ public function isBoolean() @@ -101,6 +109,8 @@ function ($value) { * * @param string[] $choices * + * @throws \Dotenv\Exception\ValidationException + * * @return \Dotenv\Validator */ public function allowedValues(array $choices) diff --git a/tests/Dotenv/DotenvTest.php b/tests/Dotenv/DotenvTest.php index 398cb0db..48770161 100644 --- a/tests/Dotenv/DotenvTest.php +++ b/tests/Dotenv/DotenvTest.php @@ -21,19 +21,19 @@ public function setUp() */ public function testDotenvThrowsExceptionIfUnableToLoadFile() { - $dotenv = new Dotenv(__DIR__); + $dotenv = Dotenv::create(__DIR__); $dotenv->load(); } public function testDotenvSkipsLoadingIfFileIsMissing() { - $dotenv = new Dotenv(__DIR__); + $dotenv = Dotenv::create(__DIR__); $this->assertEmpty($dotenv->safeLoad()); } public function testDotenvLoadsEnvironmentVars() { - $dotenv = new Dotenv($this->fixturesFolder); + $dotenv = Dotenv::create($this->fixturesFolder); $dotenv->load(); $this->assertSame('bar', getenv('FOO')); $this->assertSame('baz', getenv('BAR')); @@ -43,7 +43,7 @@ public function testDotenvLoadsEnvironmentVars() public function testCommentedDotenvLoadsEnvironmentVars() { - $dotenv = new Dotenv($this->fixturesFolder, 'commented.env'); + $dotenv = Dotenv::create($this->fixturesFolder, 'commented.env'); $dotenv->load(); $this->assertSame('bar', getenv('CFOO')); $this->assertFalse(getenv('CBAR')); @@ -57,7 +57,7 @@ public function testCommentedDotenvLoadsEnvironmentVars() public function testQuotedDotenvLoadsEnvironmentVars() { - $dotenv = new Dotenv($this->fixturesFolder, 'quoted.env'); + $dotenv = Dotenv::create($this->fixturesFolder, 'quoted.env'); $dotenv->load(); $this->assertSame('bar', getenv('QFOO')); $this->assertSame('baz', getenv('QBAR')); @@ -73,13 +73,13 @@ public function testQuotedDotenvLoadsEnvironmentVars() */ public function testSpacedValuesWithoutQuotesThrowsException() { - $dotenv = new Dotenv(dirname(__DIR__).'/fixtures/env-wrong', 'spaced-wrong.env'); + $dotenv = Dotenv::create(dirname(__DIR__).'/fixtures/env-wrong', 'spaced-wrong.env'); $dotenv->load(); } public function testExportedDotenvLoadsEnvironmentVars() { - $dotenv = new Dotenv($this->fixturesFolder, 'exported.env'); + $dotenv = Dotenv::create($this->fixturesFolder, 'exported.env'); $dotenv->load(); $this->assertSame('bar', getenv('EFOO')); $this->assertSame('baz', getenv('EBAR')); @@ -89,7 +89,7 @@ public function testExportedDotenvLoadsEnvironmentVars() public function testDotenvLoadsEnvGlobals() { - $dotenv = new Dotenv($this->fixturesFolder); + $dotenv = Dotenv::create($this->fixturesFolder); $dotenv->load(); $this->assertSame('bar', $_SERVER['FOO']); $this->assertSame('baz', $_SERVER['BAR']); @@ -99,7 +99,7 @@ public function testDotenvLoadsEnvGlobals() public function testDotenvLoadsServerGlobals() { - $dotenv = new Dotenv($this->fixturesFolder); + $dotenv = Dotenv::create($this->fixturesFolder); $dotenv->load(); $this->assertSame('bar', $_ENV['FOO']); $this->assertSame('baz', $_ENV['BAR']); @@ -114,7 +114,7 @@ public function testDotenvLoadsServerGlobals() */ public function testDotenvRequiredStringEnvironmentVars() { - $dotenv = new Dotenv($this->fixturesFolder); + $dotenv = Dotenv::create($this->fixturesFolder); $dotenv->load(); $dotenv->required('FOO'); $this->assertTrue(true); // anything wrong an exception will be thrown @@ -127,7 +127,7 @@ public function testDotenvRequiredStringEnvironmentVars() */ public function testDotenvRequiredArrayEnvironmentVars() { - $dotenv = new Dotenv($this->fixturesFolder); + $dotenv = Dotenv::create($this->fixturesFolder); $dotenv->load(); $dotenv->required(['FOO', 'BAR']); $this->assertTrue(true); // anything wrong an exception will be thrown @@ -135,7 +135,7 @@ public function testDotenvRequiredArrayEnvironmentVars() public function testDotenvNestedEnvironmentVars() { - $dotenv = new Dotenv($this->fixturesFolder, 'nested.env'); + $dotenv = Dotenv::create($this->fixturesFolder, 'nested.env'); $dotenv->load(); $this->assertSame('{$NVAR1} {$NVAR2}', $_ENV['NVAR3']); // not resolved $this->assertSame('Hello World!', $_ENV['NVAR4']); @@ -151,7 +151,7 @@ public function testDotenvNestedEnvironmentVars() */ public function testDotenvAllowedValues() { - $dotenv = new Dotenv($this->fixturesFolder); + $dotenv = Dotenv::create($this->fixturesFolder); $dotenv->load(); $dotenv->required('FOO')->allowedValues(['bar', 'baz']); $this->assertTrue(true); // anything wrong an exception will be thrown @@ -167,7 +167,7 @@ public function testDotenvAllowedValues() */ public function testDotenvProhibitedValues() { - $dotenv = new Dotenv($this->fixturesFolder); + $dotenv = Dotenv::create($this->fixturesFolder); $dotenv->load(); $dotenv->required('FOO')->allowedValues(['buzz']); } @@ -178,7 +178,7 @@ public function testDotenvProhibitedValues() */ public function testDotenvRequiredThrowsRuntimeException() { - $dotenv = new Dotenv($this->fixturesFolder); + $dotenv = Dotenv::create($this->fixturesFolder); $dotenv->load(); $this->assertFalse(getenv('FOOX')); $this->assertFalse(getenv('NOPE')); @@ -187,7 +187,7 @@ public function testDotenvRequiredThrowsRuntimeException() public function testDotenvNullFileArgumentUsesDefault() { - $dotenv = new Dotenv($this->fixturesFolder, null); + $dotenv = Dotenv::create($this->fixturesFolder, null); $dotenv->load(); $this->assertSame('bar', getenv('FOO')); } @@ -199,7 +199,7 @@ public function testDotenvNullFileArgumentUsesDefault() */ public function testDotenvTrimmedKeys() { - $dotenv = new Dotenv($this->fixturesFolder, 'quoted.env'); + $dotenv = Dotenv::create($this->fixturesFolder, 'quoted.env'); $dotenv->load(); $this->assertSame('no space', getenv('QWHITESPACE')); } @@ -207,7 +207,7 @@ public function testDotenvTrimmedKeys() public function testDotenvLoadDoesNotOverwriteEnv() { putenv('IMMUTABLE=true'); - $dotenv = new Dotenv($this->fixturesFolder, 'immutable.env'); + $dotenv = Dotenv::create($this->fixturesFolder, 'immutable.env'); $dotenv->load(); $this->assertSame('true', getenv('IMMUTABLE')); } @@ -215,7 +215,7 @@ public function testDotenvLoadDoesNotOverwriteEnv() public function testDotenvLoadAfterOverload() { putenv('IMMUTABLE=true'); - $dotenv = new Dotenv($this->fixturesFolder, 'immutable.env'); + $dotenv = Dotenv::create($this->fixturesFolder, 'immutable.env'); $dotenv->overload(); $this->assertSame('false', getenv('IMMUTABLE')); @@ -227,7 +227,7 @@ public function testDotenvLoadAfterOverload() public function testDotenvOverloadAfterLoad() { putenv('IMMUTABLE=true'); - $dotenv = new Dotenv($this->fixturesFolder, 'immutable.env'); + $dotenv = Dotenv::create($this->fixturesFolder, 'immutable.env'); $dotenv->load(); $this->assertSame('true', getenv('IMMUTABLE')); @@ -238,14 +238,14 @@ public function testDotenvOverloadAfterLoad() public function testDotenvOverloadDoesOverwriteEnv() { - $dotenv = new Dotenv($this->fixturesFolder, 'mutable.env'); + $dotenv = Dotenv::create($this->fixturesFolder, 'mutable.env'); $dotenv->overload(); $this->assertSame('true', getenv('MUTABLE')); } public function testDotenvAllowsSpecialCharacters() { - $dotenv = new Dotenv($this->fixturesFolder, 'specialchars.env'); + $dotenv = Dotenv::create($this->fixturesFolder, 'specialchars.env'); $dotenv->load(); $this->assertSame('$a6^C7k%zs+e^.jvjXk', getenv('SPVAR1')); $this->assertSame('?BUty3koaV3%GA*hMAwH}B', getenv('SPVAR2')); @@ -256,7 +256,7 @@ public function testDotenvAllowsSpecialCharacters() public function testDotenvAssertions() { - $dotenv = new Dotenv($this->fixturesFolder, 'assertions.env'); + $dotenv = Dotenv::create($this->fixturesFolder, 'assertions.env'); $dotenv->load(); $this->assertSame('val1', getenv('ASSERTVAR1')); $this->assertEmpty(getenv('ASSERTVAR2')); @@ -305,7 +305,7 @@ public function testDotenvAssertions() */ public function testDotenvEmptyThrowsRuntimeException() { - $dotenv = new Dotenv($this->fixturesFolder, 'assertions.env'); + $dotenv = Dotenv::create($this->fixturesFolder, 'assertions.env'); $dotenv->load(); $this->assertEmpty(getenv('ASSERTVAR2')); @@ -318,7 +318,7 @@ public function testDotenvEmptyThrowsRuntimeException() */ public function testDotenvStringOfSpacesConsideredEmpty() { - $dotenv = new Dotenv($this->fixturesFolder, 'assertions.env'); + $dotenv = Dotenv::create($this->fixturesFolder, 'assertions.env'); $dotenv->load(); $this->assertEmpty(getenv('ASSERTVAR3')); @@ -331,7 +331,7 @@ public function testDotenvStringOfSpacesConsideredEmpty() */ public function testDotenvHitsLastChain() { - $dotenv = new Dotenv($this->fixturesFolder, 'assertions.env'); + $dotenv = Dotenv::create($this->fixturesFolder, 'assertions.env'); $dotenv->load(); $dotenv->required('ASSERTVAR3')->notEmpty(); } @@ -342,23 +342,22 @@ public function testDotenvHitsLastChain() */ public function testDotenvValidateRequiredWithoutLoading() { - $dotenv = new Dotenv($this->fixturesFolder, 'assertions.env'); + $dotenv = Dotenv::create($this->fixturesFolder, 'assertions.env'); $dotenv->required('foo'); } public function testDotenvRequiredCanBeUsedWithoutLoadingFile() { putenv('REQUIRED_VAR=1'); - $dotenv = new Dotenv($this->fixturesFolder); + $dotenv = Dotenv::create($this->fixturesFolder); $dotenv->required('REQUIRED_VAR')->notEmpty(); $this->assertTrue(true); } public function testGetEnvironmentVariablesList() { - $dotenv = new Dotenv($this->fixturesFolder); + $dotenv = Dotenv::create($this->fixturesFolder); $dotenv->load(); - $this->assertTrue(is_array($dotenv->getEnvironmentVariableNames())); $this->assertSame(['FOO', 'BAR', 'SPACED', 'NULL'], $dotenv->getEnvironmentVariableNames()); } } diff --git a/tests/Dotenv/EnvironmentVariablesTest.php b/tests/Dotenv/EnvironmentVariablesTest.php new file mode 100644 index 00000000..dfcca674 --- /dev/null +++ b/tests/Dotenv/EnvironmentVariablesTest.php @@ -0,0 +1,109 @@ +envFactory = new DotenvFactory(); + (new Loader(dirname(__DIR__).'/fixtures/env/.env', $this->envFactory))->load(); + } + + public function testCheckingWhetherVariableExists() + { + $envVars = $this->envFactory->create(); + + $this->assertTrue($envVars->has('FOO')); + $this->assertFalse($envVars->has('NON_EXISTING_VARIABLE')); + } + + public function testGettingVariableByName() + { + $envVars = $this->envFactory->create(); + + $this->assertSame('bar', $envVars->get('FOO')); + } + + public function testSettingVariable() + { + $envVars = $this->envFactory->create(); + + $this->assertSame('bar', $envVars->get('FOO')); + + $envVars->set('FOO', 'new'); + + $this->assertSame('new', $envVars->get('FOO')); + } + + public function testClearingVariable() + { + $envVars = $this->envFactory->create(); + + $envVars->clear('FOO'); + + $this->assertFalse($envVars->has('FOO')); + } + + public function testCannotSetVariableOnImmutableInstance() + { + $envVars = $this->envFactory->createImmutable(); + + $this->assertSame('bar', $envVars->get('FOO')); + + $envVars->set('FOO', 'new'); + + $this->assertSame('bar', $envVars->get('FOO')); + } + + public function testCannotClearVariableOnImmutableInstance() + { + $envVars = $this->envFactory->createImmutable(); + + $envVars->clear('FOO'); + + $this->assertTrue($envVars->has('FOO')); + } + + public function testCheckingWhetherVariableExistsUsingArrayNotation() + { + $envVars = $this->envFactory->create(); + + $this->assertTrue(isset($envVars['FOO'])); + $this->assertFalse(isset($envVars['NON_EXISTING_VARIABLE'])); + } + + public function testGettingVariableByNameUsingArrayNotation() + { + $envVars = $this->envFactory->create(); + + $this->assertSame('bar', $envVars['FOO']); + } + + public function testSettingVariableUsingArrayNotation() + { + $envVars = $this->envFactory->create(); + + $this->assertSame('bar', $envVars['FOO']); + + $envVars['FOO'] = 'new'; + + $this->assertSame('new', $envVars['FOO']); + } + + public function testClearingVariableUsingArrayNotation() + { + $envVars = $this->envFactory->create(); + + unset($envVars['FOO']); + + $this->assertFalse(isset($envVars['FOO'])); + } +} diff --git a/tests/Dotenv/LoaderTest.php b/tests/Dotenv/LoaderTest.php index 74abb1f5..9a5e77db 100644 --- a/tests/Dotenv/LoaderTest.php +++ b/tests/Dotenv/LoaderTest.php @@ -1,5 +1,6 @@ keyVal(true); - - // Build an immutable and mutable loader for convenience. - $this->mutableLoader = new Loader($folder); - $this->immutableLoader = new Loader($folder, true); + $this->loader = new Loader($folder, new DotenvFactory(), false); } protected $keyVal; @@ -37,8 +28,6 @@ public function setUp() * key/value pairs. * * @param bool $reset - * If true, a new pair will be generated. If false, the last returned pair - * will be returned. * * @return array */ @@ -75,55 +64,33 @@ protected function value() return reset($keyVal); } - public function testMutableLoaderSetUnsetImmutable() - { - $immutable = $this->mutableLoader->getImmutable(); - - // Set Immutable. - $this->mutableLoader->setImmutable(!$immutable); - $this->assertSame(!$immutable, $this->mutableLoader->getImmutable()); - $this->mutableLoader->setImmutable($immutable); - $this->assertSame($immutable, $this->mutableLoader->getImmutable()); - } - public function testMutableLoaderClearsEnvironmentVars() { // Set an environment variable. - $this->mutableLoader->setEnvironmentVariable($this->key(), $this->value()); + $this->loader->setEnvironmentVariable($this->key(), $this->value()); // Clear the set environment variable. - $this->mutableLoader->clearEnvironmentVariable($this->key()); - $this->assertSame(null, $this->mutableLoader->getEnvironmentVariable($this->key())); + $this->loader->clearEnvironmentVariable($this->key()); + $this->assertSame(null, $this->loader->getEnvironmentVariable($this->key())); $this->assertSame(false, getenv($this->key())); $this->assertSame(false, isset($_ENV[$this->key()])); $this->assertSame(false, isset($_SERVER[$this->key()])); - $this->assertTrue(is_array($this->mutableLoader->variableNames)); - $this->assertFalse(empty($this->mutableLoader->variableNames)); - } - - public function testImmutableLoaderSetUnsetImmutable() - { - $immutable = $this->immutableLoader->getImmutable(); - - // Set Immutable. - $this->immutableLoader->setImmutable(!$immutable); - $this->assertSame(!$immutable, $this->immutableLoader->getImmutable()); - $this->immutableLoader->setImmutable($immutable); - $this->assertSame($immutable, $this->immutableLoader->getImmutable()); + $this->assertSame([$this->key()], $this->loader->getEnvironmentVariableNames()); } public function testImmutableLoaderCannotClearEnvironmentVars() { + $this->loader->setImmutable(true); + // Set an environment variable. - $this->immutableLoader->setEnvironmentVariable($this->key(), $this->value()); + $this->loader->setEnvironmentVariable($this->key(), $this->value()); // Attempt to clear the environment variable, check that it fails. - $this->immutableLoader->clearEnvironmentVariable($this->key()); - $this->assertSame($this->value(), $this->immutableLoader->getEnvironmentVariable($this->key())); + $this->loader->clearEnvironmentVariable($this->key()); + $this->assertSame($this->value(), $this->loader->getEnvironmentVariable($this->key())); $this->assertSame($this->value(), getenv($this->key())); $this->assertSame(true, isset($_ENV[$this->key()])); $this->assertSame(true, isset($_SERVER[$this->key()])); - $this->assertTrue(is_array($this->immutableLoader->variableNames)); - $this->assertFalse(empty($this->immutableLoader->variableNames)); + $this->assertSame([$this->key()], $this->loader->getEnvironmentVariableNames()); } } diff --git a/tests/Dotenv/ValidatorBooleanTest.php b/tests/Dotenv/ValidatorBooleanTest.php index 520742d8..a16a9488 100644 --- a/tests/Dotenv/ValidatorBooleanTest.php +++ b/tests/Dotenv/ValidatorBooleanTest.php @@ -54,7 +54,7 @@ public function validBooleanValuesDataProvider() */ public function testCanValidateBooleans($boolean) { - $dotenv = new Dotenv($this->fixturesFolder, 'booleans.env'); + $dotenv = Dotenv::create($this->fixturesFolder, 'booleans.env'); $dotenv->load(); $dotenv->required($boolean)->isBoolean(); @@ -88,7 +88,7 @@ public function invalidBooleanValuesDataProvider() */ public function testCanInvalidateNonBooleans($boolean) { - $dotenv = new Dotenv($this->fixturesFolder, 'booleans.env'); + $dotenv = Dotenv::create($this->fixturesFolder, 'booleans.env'); $dotenv->load(); $dotenv->required($boolean)->isBoolean();