diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index ee37e38..cb83e60 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -45,7 +45,7 @@ composer install
composer test
# Run specific test suite
-vendor/bin/phpunit tests/EnvironmentTest.php
+vendor/bin/phpunit tests/FooTest.php
# Run with coverage
vendor/bin/phpunit --coverage-html coverage/
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 7ff5eb0..0c29f6b 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -62,7 +62,7 @@ jobs:
- name: Run tests with coverage
if: matrix.php == '8.4'
- run: vendor/bin/phpunit --coverage-clover=coverage.xml
+ run: composer test-coverage
- name: Upload coverage to Codecov
if: matrix.php == '8.4'
diff --git a/.gitignore b/.gitignore
index 3875a89..3c10f33 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
.psalm/
vendor/
composer.lock
+composer.develop.*
diff --git a/README.md b/README.md
index feb0145..3550707 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,12 @@
+


+




@@ -586,7 +586,7 @@ echo "Debug Mode: " . (Environment::isDebug() ? 'enabled' : 'disabled') . "\n";
## Changelog
-Please see [CHANGELOG.md](CHANGELOG.md) for a detailed list of changes for each release.
+Please see [CHANGELOG](CHANGELOG.md) for a detailed list of changes for each release.
We follow [Semantic Versioning](https://semver.org/) and use [Conventional Commits](https://www.conventionalcommits.org/) to automatically generate our changelog.
@@ -606,6 +606,8 @@ For your contributions please use:
- [git-flow workflow](https://danielkummer.github.io/git-flow-cheatsheet/)
- [Pull request workflow](https://docs.github.com/en/get-started/exploring-projects-on-github/contributing-to-a-project)
+See [CONTRIBUTING](CONTRIBUTING.md) for detailed guidelines.
+
## Sponsor
[
](https://buymeacoff.ee/frugan)
@@ -614,4 +616,3 @@ For your contributions please use:
(ɔ) Copyleft 2025 [Frugan](https://frugan.it).
[GNU GPLv3](https://choosealicense.com/licenses/gpl-3.0/), see [LICENSE](LICENSE) file.
-
diff --git a/composer.json b/composer.json
index 8dc6ee4..78ba55e 100644
--- a/composer.json
+++ b/composer.json
@@ -16,10 +16,16 @@
{
"name": "Frugan",
"email": "dev@frugan.it",
- "homepage": "https://github.com/wp-spaghetti"
+ "homepage": "https://github.com/frugan-dev",
+ "role": "Developer"
}
],
"homepage": "https://github.com/wp-spaghetti/wp-env",
+ "support": {
+ "issues": "https://github.com/wp-spaghetti/wp-env/issues",
+ "source": "https://github.com/wp-spaghetti/wp-env",
+ "docs": "https://github.com/wp-spaghetti/wp-env#readme"
+ },
"require": {
"php": ">=8.0"
},
@@ -60,10 +66,16 @@
"analysis": "grumphp run --tasks=phpstan",
"check": "grumphp run",
"ci": "grumphp run --no-interaction",
- "coverage": "vendor/bin/phpunit --coverage-clover=coverage.xml",
"lint": "grumphp run --tasks=phpcsfixer,phplint,phpstan,rector",
"quality": "grumphp run --tasks=phpmnd,phpparser",
"security": "grumphp run --tasks=securitychecker_roave",
- "test": "grumphp run --tasks=phpunit"
- }
+ "test": "grumphp run --tasks=phpunit",
+ "test-coverage": "vendor/bin/phpunit --coverage-clover=coverage.xml"
+ },
+ "funding": [
+ {
+ "type": "custom",
+ "url": "https://buymeacoff.ee/frugan"
+ }
+ ]
}
diff --git a/phpunit-10.xml.dist b/phpunit-10.xml.dist
index 581f936..8de15e9 100644
--- a/phpunit-10.xml.dist
+++ b/phpunit-10.xml.dist
@@ -22,4 +22,4 @@
-
\ No newline at end of file
+
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index aa4e15e..742fbad 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -23,4 +23,4 @@
-
\ No newline at end of file
+
diff --git a/src/Environment.php b/src/Environment.php
index 3b07f5e..d93da4a 100644
--- a/src/Environment.php
+++ b/src/Environment.php
@@ -14,6 +14,7 @@
namespace WpSpaghetti\WpEnv;
use Env\Env;
+use PHPUnit\Framework\TestCase;
if (!\defined('ABSPATH')) {
exit;
@@ -42,6 +43,8 @@ class Environment
public const ENV_PRODUCTION = 'production';
+ public const ENV_TESTING = 'testing';
+
/**
* Cache for environment values to improve performance.
*
@@ -368,7 +371,8 @@ public static function getEnvironment(): string
// Map common variations
$environment = match ($env) {
'dev', 'develop', 'development', 'local' => self::ENV_DEVELOPMENT,
- 'stage', 'staging', 'test', 'testing' => self::ENV_STAGING,
+ 'stage', 'staging', => self::ENV_STAGING,
+ 'test', 'testing' => self::ENV_TESTING,
'prod', 'production', 'live' => self::ENV_PRODUCTION,
default => self::detectEnvironmentByIndicators()
};
@@ -409,6 +413,34 @@ public static function isProduction(): bool
return self::ENV_PRODUCTION === self::getEnvironment();
}
+ /**
+ * Check if we're in testing environment.
+ * This includes both environment variables and PHPUnit runtime detection.
+ */
+ public static function isTesting(): bool
+ {
+ // First check PHPUnit runtime (not affected by mocks)
+ if (\defined('PHPUNIT_COMPOSER_INSTALL') || class_exists(TestCase::class)) {
+ return true;
+ }
+
+ $testingValue = self::ENV_TESTING;
+
+ // Then check WordPress constants (not affected by mocks)
+ // @phpstan-ignore-next-line identical.alwaysTrue (constants may vary in different environments)
+ if (\defined('WP_ENV') && $testingValue === \constant('WP_ENV')) {
+ return true;
+ }
+
+ // @phpstan-ignore-next-line identical.alwaysTrue (constants may vary in different environments)
+ if (\defined('WP_ENVIRONMENT_TYPE') && $testingValue === \constant('WP_ENVIRONMENT_TYPE')) {
+ return true;
+ }
+
+ // Finally check environment variables (affected by mocks)
+ return self::ENV_TESTING === self::getEnvironment();
+ }
+
/**
* Check if WordPress debug mode is enabled.
*/
@@ -579,12 +611,12 @@ private static function getRaw(string $key, mixed $default = null): mixed
}
// Normal priority outside of testing:
- // Then try WordPress constants (more WordPress-native)
+ // WordPress constants have priority in production (defined in wp-config.php)
if (\defined($key)) {
return \constant($key);
}
- // Then try oscarotero/env (for Bedrock and modern setups)
+ // Then try oscarotero/env (for Bedrock and modern setups) - only in non-testing mode
if (\function_exists('Env\env')) {
/** @phpstan-ignore-next-line */
$originalDefault = Env::$default ?? null;
@@ -626,9 +658,9 @@ private static function getMockAwareEnvVar(string $key): false|string
}
// In testing mode, don't fall back to regular getenv to maintain mock isolation
- if (self::hasMockVariables()) {
- return false;
- }
+ // if (self::hasMockVariables()) {
+ // return false;
+ // }
// Fall back to regular getenv only in non-testing mode
$getEnv = \function_exists('mock_getenv') ? 'mock_getenv' : 'getenv';
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index fd25cde..1b0e140 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -24,6 +24,10 @@
define('WP_ENV', 'testing');
}
+if (!defined('WP_ENVIRONMENT_TYPE')) {
+ define('WP_ENVIRONMENT_TYPE', 'testing');
+}
+
// Autoload Composer dependencies
require_once __DIR__.'/../vendor/autoload.php';