mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
API Refactor SapphireTest state management into SapphireTestState
API Remove Injector::unregisterAllObjects() API Remove FakeController
This commit is contained in:
parent
f26ae75c6e
commit
c66d433977
9
_config/tests.yml
Normal file
9
_config/tests.yml
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
Name: sapphiretest
|
||||
---
|
||||
SilverStripe\Core\Injector\Injector:
|
||||
SilverStripe\Dev\SapphireTestState:
|
||||
properties:
|
||||
States:
|
||||
flushable: %$SilverStripe\Dev\FlushableTestState
|
||||
requirements: %$SilverStripe\View\Dev\RequirementsTestState
|
@ -7,15 +7,14 @@ use SilverStripe\Core\Startup\OutputMiddleware;
|
||||
use SilverStripe\Control\HTTPRequest;
|
||||
|
||||
require __DIR__ . '/src/includes/cli.php';
|
||||
$_SERVER['SCRIPT_FILENAME'] = __FILE__;
|
||||
chdir(__DIR__);
|
||||
|
||||
|
||||
require __DIR__ . '/src/includes/autoload.php';
|
||||
|
||||
// Default application
|
||||
// Build request and detect flush
|
||||
$request = HTTPRequest::createFromEnvironment();
|
||||
$kernel = new AppKernel();
|
||||
$flush = $request->getVar('flush') || strpos($request->getURL(), 'dev/build') === 0;
|
||||
|
||||
// Default application
|
||||
$kernel = new AppKernel($flush);
|
||||
$app = new HTTPApplication($kernel);
|
||||
$app->addMiddleware(new OutputMiddleware());
|
||||
$app->handle($request);
|
||||
|
@ -1340,6 +1340,8 @@ After (`mysite/_config/config.yml`):
|
||||
#### <a name="overview-general-removed"></a>General and Core Removed API
|
||||
|
||||
* `CMSMain::buildbrokenlinks()` action is removed.
|
||||
* `Injector::unregisterAllObjects()` has been removed. Use `unregisterObjects` to unregister
|
||||
groups of objects limited by type instead.
|
||||
* `SS_Log` class has been removed. Use `Injector::inst()->get(LoggerInterface::class)` instead.
|
||||
* Removed `CMSBatchAction_Delete`
|
||||
* Removed `CMSBatchAction_DeleteFromLive`
|
||||
|
7
main.php
7
main.php
@ -8,9 +8,12 @@ use SilverStripe\Control\HTTPRequest;
|
||||
|
||||
require __DIR__ . '/src/includes/autoload.php';
|
||||
|
||||
// Default application
|
||||
// Build request and detect flush
|
||||
$request = HTTPRequest::createFromEnvironment();
|
||||
$kernel = new AppKernel();
|
||||
$flush = $request->getVar('flush') || strpos($request->getURL(), 'dev/build') === 0;
|
||||
|
||||
// Default application
|
||||
$kernel = new AppKernel($flush);
|
||||
$app = new HTTPApplication($kernel);
|
||||
$app->addMiddleware(new OutputMiddleware());
|
||||
$app->addMiddleware(new ErrorControlChainMiddleware($app, $request));
|
||||
|
@ -27,8 +27,15 @@ use SilverStripe\View\ThemeResourceLoader;
|
||||
|
||||
class AppKernel extends CoreKernel
|
||||
{
|
||||
public function __construct()
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $flush = false;
|
||||
|
||||
public function __construct($flush = false)
|
||||
{
|
||||
$this->flush = $flush;
|
||||
|
||||
// Initialise the dependency injector as soon as possible, as it is
|
||||
// subsequently used by some of the following code
|
||||
$injector = new Injector(array('locator' => SilverStripeServiceConfigurationLocator::class));
|
||||
@ -355,28 +362,30 @@ class AppKernel extends CoreKernel
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function getIncludeTests()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Boot all manifests
|
||||
*/
|
||||
protected function bootManifests()
|
||||
{
|
||||
// Regenerate the manifest if ?flush is set, or if the database is being built.
|
||||
// The coupling is a hack, but it removes an annoying bug where new classes
|
||||
// referenced in _config.php files can be referenced during the build process.
|
||||
$flush = isset($_GET['flush']) ||
|
||||
trim($_GET['url'], '/') === trim(BASE_URL . '/dev/build', '/');
|
||||
|
||||
// Setup autoloader
|
||||
$this->getClassLoader()->init(false, $flush);
|
||||
$this->getClassLoader()->init($this->getIncludeTests(), $this->flush);
|
||||
|
||||
// Find modules
|
||||
$this->getModuleLoader()->init(false, $flush);
|
||||
$this->getModuleLoader()->init($this->getIncludeTests(), $this->flush);
|
||||
|
||||
// Flush config
|
||||
if ($flush) {
|
||||
if ($this->flush) {
|
||||
$config = $this->getConfigLoader()->getManifest();
|
||||
if ($config instanceof CachedConfigCollection) {
|
||||
$config->setFlush($flush);
|
||||
$config->setFlush(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -386,7 +395,7 @@ class AppKernel extends CoreKernel
|
||||
// Find default templates
|
||||
$defaultSet = $this->getThemeResourceLoader()->getSet('$default');
|
||||
if ($defaultSet instanceof ThemeManifest) {
|
||||
$defaultSet->init(false, $flush);
|
||||
$defaultSet->init($this->getIncludeTests(), $this->flush);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ use InvalidArgumentException;
|
||||
use SilverStripe\Control\RequestHandler;
|
||||
use SilverStripe\Core\Config\Config;
|
||||
use SilverStripe\Core\Injector\Injector;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\View\ViewableData;
|
||||
|
||||
/**
|
||||
@ -271,8 +272,8 @@ trait Extensible
|
||||
}
|
||||
Config::modify()->set($class, 'extensions', $config);
|
||||
|
||||
// unset singletons to avoid side-effects
|
||||
Injector::inst()->unregisterAllObjects();
|
||||
// Unset singletons
|
||||
Injector::inst()->unregisterObjects($class);
|
||||
|
||||
// unset some caches
|
||||
$subclasses = ClassInfo::subclassesFor($class);
|
||||
|
@ -2,14 +2,15 @@
|
||||
|
||||
namespace SilverStripe\Core\Injector;
|
||||
|
||||
use ArrayObject;
|
||||
use InvalidArgumentException;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
use ReflectionMethod;
|
||||
use ReflectionObject;
|
||||
use ReflectionProperty;
|
||||
use SilverStripe\Core\ClassInfo;
|
||||
use SilverStripe\Core\Config\Config;
|
||||
use ReflectionProperty;
|
||||
use ArrayObject;
|
||||
use ReflectionObject;
|
||||
use ReflectionMethod;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use SilverStripe\Dev\Deprecation;
|
||||
|
||||
/**
|
||||
@ -231,16 +232,10 @@ class Injector implements ContainerInterface
|
||||
protected $nestedFrom = null;
|
||||
|
||||
/**
|
||||
* If a user wants to use the injector as a static reference
|
||||
*
|
||||
* @param array $config
|
||||
* @return Injector
|
||||
*/
|
||||
public static function inst($config = null)
|
||||
public static function inst()
|
||||
{
|
||||
if (!self::$instance) {
|
||||
self::$instance = new Injector($config);
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
@ -404,7 +399,7 @@ class Injector implements ContainerInterface
|
||||
|
||||
// make sure the class is set...
|
||||
if (empty($class)) {
|
||||
throw new \InvalidArgumentException('Missing spec class');
|
||||
throw new InvalidArgumentException('Missing spec class');
|
||||
}
|
||||
$spec['class'] = $class;
|
||||
|
||||
@ -651,21 +646,21 @@ class Injector implements ContainerInterface
|
||||
|
||||
// Format validation
|
||||
if (!is_array($method) || !isset($method[0]) || isset($method[2])) {
|
||||
throw new \InvalidArgumentException(
|
||||
throw new InvalidArgumentException(
|
||||
"'calls' entries in service definition should be 1 or 2 element arrays."
|
||||
);
|
||||
}
|
||||
if (!is_string($method[0])) {
|
||||
throw new \InvalidArgumentException("1st element of a 'calls' entry should be a string");
|
||||
throw new InvalidArgumentException("1st element of a 'calls' entry should be a string");
|
||||
}
|
||||
if (isset($method[1]) && !is_array($method[1])) {
|
||||
throw new \InvalidArgumentException("2nd element of a 'calls' entry should an arguments array");
|
||||
throw new InvalidArgumentException("2nd element of a 'calls' entry should an arguments array");
|
||||
}
|
||||
|
||||
// Check that the method exists and is callable
|
||||
$objectMethod = array($object, $method[0]);
|
||||
if (!is_callable($objectMethod)) {
|
||||
throw new \InvalidArgumentException("'$method[0]' in 'calls' entry is not a public method");
|
||||
throw new InvalidArgumentException("'$method[0]' in 'calls' entry is not a public method");
|
||||
}
|
||||
|
||||
// Call it
|
||||
@ -847,16 +842,18 @@ class Injector implements ContainerInterface
|
||||
* @param object $service The object to register
|
||||
* @param string $replace The name of the object to replace (if different to the
|
||||
* class name of the object to register)
|
||||
* @return $this
|
||||
*/
|
||||
public function registerService($service, $replace = null)
|
||||
{
|
||||
$registerAt = get_class($service);
|
||||
if ($replace != null) {
|
||||
if ($replace !== null) {
|
||||
$registerAt = $replace;
|
||||
}
|
||||
|
||||
$this->specs[$registerAt] = array('class' => get_class($service));
|
||||
$this->serviceCache[$registerAt] = $service;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -864,18 +861,40 @@ class Injector implements ContainerInterface
|
||||
* by the inject
|
||||
*
|
||||
* @param string $name The name to unregister
|
||||
* @return $this
|
||||
*/
|
||||
public function unregisterNamedObject($name)
|
||||
{
|
||||
unset($this->serviceCache[$name]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear out all objects that are managed by the injetor.
|
||||
* Clear out objects of one or more types that are managed by the injetor.
|
||||
*
|
||||
* @param array|string $types Base class of object (not service name) to remove
|
||||
* @return $this
|
||||
*/
|
||||
public function unregisterAllObjects()
|
||||
public function unregisterObjects($types)
|
||||
{
|
||||
$this->serviceCache = array('Injector' => $this);
|
||||
if (!is_array($types)) {
|
||||
$types = [ $types ];
|
||||
}
|
||||
|
||||
// Filter all objects
|
||||
foreach ($this->serviceCache as $key => $object) {
|
||||
foreach ($types as $filterClass) {
|
||||
// Prevent destructive flushing
|
||||
if (strcasecmp($filterClass, 'object') === 0) {
|
||||
throw new InvalidArgumentException("Global unregistration is not allowed");
|
||||
}
|
||||
if ($object instanceof $filterClass) {
|
||||
unset($this->serviceCache[$key]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
30
src/Core/TestKernel.php
Normal file
30
src/Core/TestKernel.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\Core;
|
||||
|
||||
/**
|
||||
* Kernel for running unit tests
|
||||
*/
|
||||
class TestKernel extends AppKernel
|
||||
{
|
||||
public function __construct($flush = true)
|
||||
{
|
||||
parent::__construct($flush);
|
||||
$this->setEnvironment(self::DEV);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset kernel between tests.
|
||||
* Note: this avoids resetting services (See TestState for service specific reset)
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->setEnvironment(self::DEV);
|
||||
$this->bootPHP();
|
||||
}
|
||||
|
||||
protected function getIncludeTests()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
49
src/Dev/FlushableTestState.php
Normal file
49
src/Dev/FlushableTestState.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\Dev;
|
||||
|
||||
use SilverStripe\Core\ClassInfo;
|
||||
use SilverStripe\Core\Flushable;
|
||||
use SilverStripe\Core\Resettable;
|
||||
|
||||
/**
|
||||
* Clears flushable / resettable objects
|
||||
*/
|
||||
class FlushableTestState implements TestState
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $flushed = false;
|
||||
|
||||
public function setUp(SapphireTest $test)
|
||||
{
|
||||
// Reset all resettables
|
||||
/** @var Resettable $resettable */
|
||||
foreach (ClassInfo::implementorsOf(Resettable::class) as $resettable) {
|
||||
$resettable::reset();
|
||||
}
|
||||
}
|
||||
|
||||
public function tearDown(SapphireTest $test)
|
||||
{
|
||||
}
|
||||
|
||||
public function setUpOnce($class)
|
||||
{
|
||||
if ($this->flushed) {
|
||||
return;
|
||||
}
|
||||
$this->flushed = true;
|
||||
|
||||
// Flush all flushable records
|
||||
/** @var Flushable $class */
|
||||
foreach (ClassInfo::implementorsOf(Flushable::class) as $class) {
|
||||
$class::flush();
|
||||
}
|
||||
}
|
||||
|
||||
public function tearDownOnce($class)
|
||||
{
|
||||
}
|
||||
}
|
@ -11,37 +11,31 @@ use SilverStripe\Control\Cookie;
|
||||
use SilverStripe\Control\Director;
|
||||
use SilverStripe\Control\Email\Email;
|
||||
use SilverStripe\Control\Email\Mailer;
|
||||
use SilverStripe\Control\HTTPRequest;
|
||||
use SilverStripe\Control\Session;
|
||||
use SilverStripe\Control\Tests\FakeController;
|
||||
use SilverStripe\Core\ClassInfo;
|
||||
use SilverStripe\Core\Config\Config;
|
||||
use SilverStripe\Core\Config\ConfigLoader;
|
||||
use SilverStripe\Core\Config\CoreConfigFactory;
|
||||
use SilverStripe\Core\Config\DefaultConfig;
|
||||
use SilverStripe\Core\Extension;
|
||||
use SilverStripe\Core\Flushable;
|
||||
use SilverStripe\Core\HTTPApplication;
|
||||
use SilverStripe\Core\Injector\Injector;
|
||||
use SilverStripe\Core\Manifest\ClassLoader;
|
||||
use SilverStripe\Core\Manifest\ClassManifest;
|
||||
use SilverStripe\Core\Resettable;
|
||||
use SilverStripe\Core\TestKernel;
|
||||
use SilverStripe\i18n\i18n;
|
||||
use SilverStripe\ORM\DataExtension;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
use SilverStripe\Security\IdentityStore;
|
||||
use SilverStripe\Versioned\Versioned;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\ORM\DB;
|
||||
use SilverStripe\ORM\FieldType\DBDatetime;
|
||||
use SilverStripe\ORM\FieldType\DBField;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
use SilverStripe\Security\Group;
|
||||
use SilverStripe\Security\IdentityStore;
|
||||
use SilverStripe\Security\Member;
|
||||
use SilverStripe\Security\Permission;
|
||||
use SilverStripe\Security\Security;
|
||||
use SilverStripe\View\Requirements;
|
||||
use SilverStripe\View\SSViewer;
|
||||
use SilverStripe\View\ThemeManifest;
|
||||
use SilverStripe\View\ThemeResourceLoader;
|
||||
use Translatable;
|
||||
|
||||
if (!class_exists(PHPUnit_Framework_TestCase::class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test case class for the Sapphire framework.
|
||||
@ -50,12 +44,6 @@ use Translatable;
|
||||
*/
|
||||
class SapphireTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
/** @config */
|
||||
private static $dependencies = array(
|
||||
'fixtureFactory' => '%$FixtureFactory',
|
||||
);
|
||||
|
||||
/**
|
||||
* Path to fixture data for this test run.
|
||||
* If passed as an array, multiple fixture files will be loaded.
|
||||
@ -77,36 +65,18 @@ class SapphireTest extends PHPUnit_Framework_TestCase
|
||||
* {@link $fixture_file}, which always forces a database build.
|
||||
*/
|
||||
protected $usesDatabase = null;
|
||||
protected $originalMemberPasswordValidator;
|
||||
protected $originalRequirements;
|
||||
protected $originalIsRunningTest;
|
||||
protected $originalNestedURLsState;
|
||||
protected $originalMemoryLimit;
|
||||
|
||||
/**
|
||||
* @var TestMailer
|
||||
*/
|
||||
protected $mailer;
|
||||
|
||||
/**
|
||||
* Pointer to the manifest that isn't a test manifest
|
||||
*/
|
||||
protected static $regular_manifest;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
* @var bool
|
||||
*/
|
||||
protected static $is_running_test = false;
|
||||
|
||||
/**
|
||||
* @var ClassManifest
|
||||
*/
|
||||
protected static $test_class_manifest;
|
||||
|
||||
/**
|
||||
* By default, setUp() does not require default records. Pass
|
||||
* class names in here, and the require/augment default records
|
||||
* function will be called on them.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $requireDefaultRecordsFrom = array();
|
||||
|
||||
@ -173,44 +143,35 @@ class SapphireTest extends PHPUnit_Framework_TestCase
|
||||
protected static $flushedFlushables = false;
|
||||
|
||||
/**
|
||||
* Determines if unit tests are currently run, flag set during test bootstrap.
|
||||
* This is used as a cheap replacement for fully mockable state
|
||||
* in certain contiditions (e.g. access checks).
|
||||
* Caution: When set to FALSE, certain controllers might bypass
|
||||
* access checks, so this is a very security sensitive setting.
|
||||
* Test application kernel.
|
||||
* Note: This is always the root kernel. Use Injector to get the current kernel
|
||||
* if nested.
|
||||
*
|
||||
* @return boolean
|
||||
* @var TestKernel
|
||||
*/
|
||||
protected static $kernel = null;
|
||||
|
||||
/**
|
||||
* Check if test bootstrapping has been performed. Must not be relied on
|
||||
* outside of unit tests.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected static function is_running_test()
|
||||
{
|
||||
return self::$is_running_test;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set test running state
|
||||
*
|
||||
* @param bool $bool
|
||||
*/
|
||||
protected static function set_is_running_test($bool)
|
||||
{
|
||||
self::$is_running_test = $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the manifest to be used to look up test classes by helper functions
|
||||
*
|
||||
* @param ClassManifest $manifest
|
||||
*/
|
||||
public static function set_test_class_manifest($manifest)
|
||||
{
|
||||
self::$test_class_manifest = $manifest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the manifest being used to look up test classes by helper functions
|
||||
*
|
||||
* @return ClassManifest
|
||||
*/
|
||||
public static function get_test_class_manifest()
|
||||
{
|
||||
return self::$test_class_manifest;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return String
|
||||
*/
|
||||
@ -219,27 +180,30 @@ class SapphireTest extends PHPUnit_Framework_TestCase
|
||||
return static::$fixture_file;
|
||||
}
|
||||
|
||||
protected $model;
|
||||
/**
|
||||
* @var TestState
|
||||
*/
|
||||
protected static $state = null;
|
||||
|
||||
/**
|
||||
* State of Versioned before this test is run
|
||||
* Setup the test.
|
||||
* Always sets up in order:
|
||||
* - Reset php state
|
||||
* - Nest
|
||||
* - Custom state helpers
|
||||
*
|
||||
* @var string
|
||||
* User code should call parent::setUp() before custom setup code
|
||||
*/
|
||||
protected $originalReadingMode = null;
|
||||
|
||||
protected $originalEnv = null;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
self::$kernel->reset();
|
||||
|
||||
//nest config and injector for each test so they are effectively sandboxed per test
|
||||
Config::nest();
|
||||
Injector::nest();
|
||||
|
||||
$this->originalEnv = Director::get_environment_type();
|
||||
if (class_exists(Versioned::class)) {
|
||||
$this->originalReadingMode = Versioned::get_reading_mode();
|
||||
}
|
||||
// Call state helpers
|
||||
static::$state->setUp($this);
|
||||
|
||||
// We cannot run the tests on this abstract class.
|
||||
if (static::class == __CLASS__) {
|
||||
@ -247,31 +211,18 @@ class SapphireTest extends PHPUnit_Framework_TestCase
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark test as being run
|
||||
$this->originalIsRunningTest = self::$is_running_test;
|
||||
self::$is_running_test = true;
|
||||
|
||||
// i18n needs to be set to the defaults or tests fail
|
||||
i18n::set_locale(i18n::config()->uninherited('default_locale'));
|
||||
|
||||
// Set default timezone consistently to avoid NZ-specific dependencies
|
||||
date_default_timezone_set('UTC');
|
||||
|
||||
// Remove password validation
|
||||
$this->originalMemberPasswordValidator = Member::password_validator();
|
||||
$this->originalRequirements = Requirements::backend();
|
||||
Member::set_password_validator(null);
|
||||
Cookie::config()->update('report_errors', false);
|
||||
if (class_exists(RootURLController::class)) {
|
||||
RootURLController::reset();
|
||||
}
|
||||
|
||||
// Reset all resettables
|
||||
/** @var Resettable $resettable */
|
||||
foreach (ClassInfo::implementorsOf(Resettable::class) as $resettable) {
|
||||
$resettable::reset();
|
||||
}
|
||||
|
||||
Security::clear_database_is_ready();
|
||||
|
||||
// Set up test routes
|
||||
@ -307,18 +258,11 @@ class SapphireTest extends PHPUnit_Framework_TestCase
|
||||
$this->logInWithPermission("ADMIN");
|
||||
}
|
||||
|
||||
// Preserve memory settings
|
||||
$this->originalMemoryLimit = ini_get('memory_limit');
|
||||
|
||||
// turn off template debugging
|
||||
SSViewer::config()->update('source_file_comments', false);
|
||||
|
||||
// Clear requirements
|
||||
Requirements::clear();
|
||||
|
||||
// Set up the test mailer
|
||||
$this->mailer = new TestMailer();
|
||||
Injector::inst()->registerService($this->mailer, Mailer::class);
|
||||
Injector::inst()->registerService(new TestMailer(), Mailer::class);
|
||||
Email::config()->remove('send_all_emails_to');
|
||||
Email::config()->remove('send_all_emails_from');
|
||||
Email::config()->remove('cc_all_emails_to');
|
||||
@ -332,20 +276,25 @@ class SapphireTest extends PHPUnit_Framework_TestCase
|
||||
* don't change state for any called method inside the test,
|
||||
* e.g. dynamically adding an extension. See {@link teardownAfterClass()}
|
||||
* for tearing down the state again.
|
||||
*
|
||||
* Always sets up in order:
|
||||
* - Reset php state
|
||||
* - Nest
|
||||
* - Custom state helpers
|
||||
*
|
||||
* User code should call parent::setUpBeforeClass() before custom setup code
|
||||
*/
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
static::start();
|
||||
|
||||
static::$kernel->reset();
|
||||
|
||||
//nest config and injector for each suite so they are effectively sandboxed
|
||||
Config::nest();
|
||||
Injector::nest();
|
||||
$isAltered = false;
|
||||
|
||||
if (!Director::isDev()) {
|
||||
user_error('Tests can only run in "dev" mode', E_USER_ERROR);
|
||||
}
|
||||
|
||||
// Remove any illegal extensions that are present
|
||||
foreach (static::$illegal_extensions as $class => $extensions) {
|
||||
if (!class_exists($class)) {
|
||||
@ -401,26 +350,30 @@ class SapphireTest extends PHPUnit_Framework_TestCase
|
||||
}
|
||||
// clear singletons, they're caching old extension info
|
||||
// which is used in DatabaseAdmin->doBuild()
|
||||
Injector::inst()->unregisterAllObjects();
|
||||
Injector::inst()->unregisterObjects(DataObject::class);
|
||||
|
||||
// Set default timezone consistently to avoid NZ-specific dependencies
|
||||
date_default_timezone_set('UTC');
|
||||
|
||||
// Flush all flushable records
|
||||
$flush = !empty($_GET['flush']);
|
||||
if (!self::$flushedFlushables && $flush) {
|
||||
self::$flushedFlushables = true;
|
||||
foreach (ClassInfo::implementorsOf(Flushable::class) as $class) {
|
||||
$class::flush();
|
||||
}
|
||||
}
|
||||
// Call state helpers
|
||||
static::$state->setUpOnce(static::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown method that's called once per test class rather once per test method.
|
||||
*
|
||||
* Always sets up in order:
|
||||
* - Custom state helpers
|
||||
* - Unnest
|
||||
* - Reset php state
|
||||
*
|
||||
* User code should call parent::tearDownAfterClass() after custom tear down code
|
||||
*/
|
||||
public static function tearDownAfterClass()
|
||||
{
|
||||
// Call state helpers
|
||||
static::$state->tearDownOnce(static::class);
|
||||
|
||||
// If we have made changes to the extensions present, then migrate the database schema.
|
||||
if (self::$extensions_to_reapply || self::$extensions_to_remove) {
|
||||
// @todo: This isn't strictly necessary to restore extensions, but only to ensure that
|
||||
@ -451,6 +404,8 @@ class SapphireTest extends PHPUnit_Framework_TestCase
|
||||
if (!empty(self::$extensions_to_reapply) || !empty(self::$extensions_to_remove) || !empty($extraDataObjects)) {
|
||||
static::resetDBSchema();
|
||||
}
|
||||
|
||||
static::$kernel->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -464,6 +419,12 @@ class SapphireTest extends PHPUnit_Framework_TestCase
|
||||
return $this->fixtureFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new fixture factory
|
||||
*
|
||||
* @param FixtureFactory $factory
|
||||
* @return $this
|
||||
*/
|
||||
public function setFixtureFactory(FixtureFactory $factory)
|
||||
{
|
||||
$this->fixtureFactory = $factory;
|
||||
@ -552,11 +513,11 @@ class SapphireTest extends PHPUnit_Framework_TestCase
|
||||
/**
|
||||
* Useful for writing unit tests without hardcoding folder structures.
|
||||
*
|
||||
* @return String Absolute path to current class.
|
||||
* @return string Absolute path to current class.
|
||||
*/
|
||||
protected function getCurrentAbsolutePath()
|
||||
{
|
||||
$filename = self::$test_class_manifest->getItemPath(static::class);
|
||||
$filename = static::$kernel->getClassLoader()->getItemPath(static::class);
|
||||
if (!$filename) {
|
||||
throw new LogicException("getItemPath returned null for " . static::class);
|
||||
}
|
||||
@ -564,7 +525,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @return String File path relative to webroot
|
||||
* @return string File path relative to webroot
|
||||
*/
|
||||
protected function getCurrentRelativePath()
|
||||
{
|
||||
@ -576,28 +537,17 @@ class SapphireTest extends PHPUnit_Framework_TestCase
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the test.
|
||||
* Always sets up in order:
|
||||
* - Custom state helpers
|
||||
* - Unnest
|
||||
* - Reset php state
|
||||
*
|
||||
* User code should call parent::tearDown() after custom tear down code
|
||||
*/
|
||||
protected function tearDown()
|
||||
{
|
||||
// Preserve memory settings
|
||||
ini_set('memory_limit', ($this->originalMemoryLimit) ? $this->originalMemoryLimit : -1);
|
||||
|
||||
// Restore email configuration
|
||||
$this->mailer = null;
|
||||
|
||||
// Restore password validation
|
||||
if ($this->originalMemberPasswordValidator) {
|
||||
Member::set_password_validator($this->originalMemberPasswordValidator);
|
||||
}
|
||||
|
||||
// Restore requirements
|
||||
if ($this->originalRequirements) {
|
||||
Requirements::set_backend($this->originalRequirements);
|
||||
}
|
||||
|
||||
// Mark test as no longer being run - we use originalIsRunningTest to allow for nested SapphireTest calls
|
||||
self::$is_running_test = $this->originalIsRunningTest;
|
||||
$this->originalIsRunningTest = null;
|
||||
|
||||
// Reset mocked datetime
|
||||
DBDatetime::clear_mock_now();
|
||||
|
||||
@ -610,14 +560,15 @@ class SapphireTest extends PHPUnit_Framework_TestCase
|
||||
$response->removeHeader('Location');
|
||||
}
|
||||
|
||||
Director::set_environment_type($this->originalEnv);
|
||||
if (class_exists(Versioned::class)) {
|
||||
Versioned::set_reading_mode($this->originalReadingMode);
|
||||
}
|
||||
// Call state helpers
|
||||
static::$state->setUp($this);
|
||||
|
||||
//unnest injector / config now that tests are over
|
||||
Injector::unnest();
|
||||
Config::unnest();
|
||||
|
||||
// Reset state
|
||||
self::$kernel->reset();
|
||||
}
|
||||
|
||||
public static function assertContains(
|
||||
@ -650,36 +601,48 @@ class SapphireTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
/**
|
||||
* Clear the log of emails sent
|
||||
*
|
||||
* @return bool True if emails cleared
|
||||
*/
|
||||
public function clearEmails()
|
||||
{
|
||||
return $this->mailer->clearEmails();
|
||||
/** @var Mailer $mailer */
|
||||
$mailer = Injector::inst()->get(Mailer::class);
|
||||
if ($mailer instanceof TestMailer) {
|
||||
$mailer->clearEmails();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for an email that was sent.
|
||||
* All of the parameters can either be a string, or, if they start with "/", a PREG-compatible regular expression.
|
||||
* @param $to
|
||||
* @param $from
|
||||
* @param $subject
|
||||
* @param $content
|
||||
* @param string $to
|
||||
* @param string $from
|
||||
* @param string $subject
|
||||
* @param string $content
|
||||
* @return array Contains keys: 'type', 'to', 'from', 'subject','content', 'plainContent', 'attachedFiles',
|
||||
* 'customHeaders', 'htmlContent', 'inlineImages'
|
||||
*/
|
||||
public function findEmail($to, $from = null, $subject = null, $content = null)
|
||||
{
|
||||
return $this->mailer->findEmail($to, $from, $subject, $content);
|
||||
/** @var Mailer $mailer */
|
||||
$mailer = Injector::inst()->get(Mailer::class);
|
||||
if ($mailer instanceof TestMailer) {
|
||||
return $mailer->findEmail($to, $from, $subject, $content);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the matching email was sent since the last call to clearEmails()
|
||||
* All of the parameters can either be a string, or, if they start with "/", a PREG-compatible regular expression.
|
||||
* @param $to
|
||||
* @param $from
|
||||
* @param $subject
|
||||
* @param $content
|
||||
* @return array Contains the keys: 'type', 'to', 'from', 'subject', 'content', 'plainContent', 'attachedFiles',
|
||||
* 'customHeaders', 'htmlContent', inlineImages'
|
||||
*
|
||||
* @param string $to
|
||||
* @param string $from
|
||||
* @param string $subject
|
||||
* @param string $content
|
||||
*/
|
||||
public function assertEmailSent($to, $from = null, $subject = null, $content = null)
|
||||
{
|
||||
@ -1013,43 +976,39 @@ class SapphireTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public static function start()
|
||||
{
|
||||
if (!static::is_running_test()) {
|
||||
new FakeController();
|
||||
static::use_test_manifest();
|
||||
if (static::is_running_test()) {
|
||||
return;
|
||||
}
|
||||
// Health check
|
||||
if (Injector::inst() || static::$kernel) {
|
||||
throw new LogicException("SapphireTest::start() cannot be called within another application");
|
||||
}
|
||||
static::set_is_running_test(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes a class and template manifest instance that include tests onto the
|
||||
* top of the loader stacks.
|
||||
*/
|
||||
protected static function use_test_manifest()
|
||||
{
|
||||
$flush = !empty($_GET['flush']);
|
||||
$classManifest = new ClassManifest(
|
||||
BASE_PATH,
|
||||
true,
|
||||
$flush
|
||||
);
|
||||
// Mock request
|
||||
$session = new Session(isset($_SESSION) ? $_SESSION : array());
|
||||
$request = new HTTPRequest('GET', '/');
|
||||
$request->setSession($session);
|
||||
|
||||
ClassLoader::inst()->pushManifest($classManifest, false);
|
||||
static::set_test_class_manifest($classManifest);
|
||||
|
||||
ThemeResourceLoader::inst()->addSet('$default', new ThemeManifest(
|
||||
BASE_PATH,
|
||||
project(),
|
||||
true,
|
||||
$flush
|
||||
));
|
||||
|
||||
// Once new class loader is registered, push a new uncached config
|
||||
$config = CoreConfigFactory::inst()->createCore();
|
||||
ConfigLoader::inst()->pushManifest($config);
|
||||
// Test application
|
||||
static::$kernel = new TestKernel();
|
||||
$app = new HTTPApplication(static::$kernel);
|
||||
|
||||
// Custom application
|
||||
$app->execute(function () use ($request) {
|
||||
// Invalidate classname spec since the test manifest will now pull out new subclasses for each internal class
|
||||
// (e.g. Member will now have various subclasses of DataObjects that implement TestOnly)
|
||||
DataObject::reset();
|
||||
|
||||
// Set dummy controller
|
||||
$controller = Controller::create();
|
||||
$controller->setRequest($request);
|
||||
$controller->pushCurrent();
|
||||
$controller->doInit();
|
||||
});
|
||||
|
||||
// Register state
|
||||
static::$state = SapphireTestState::singleton();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1160,7 +1119,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase
|
||||
DataObject::reset();
|
||||
|
||||
// clear singletons, they're caching old extension info which is used in DatabaseAdmin->doBuild()
|
||||
Injector::inst()->unregisterAllObjects();
|
||||
Injector::inst()->unregisterObjects(DataObject::class);
|
||||
|
||||
$dataClasses = ClassInfo::subclassesFor(DataObject::class);
|
||||
array_shift($dataClasses);
|
||||
|
70
src/Dev/SapphireTestState.php
Normal file
70
src/Dev/SapphireTestState.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\Dev;
|
||||
|
||||
use SilverStripe\Core\Injector\Injectable;
|
||||
|
||||
class SapphireTestState implements TestState
|
||||
{
|
||||
use Injectable;
|
||||
|
||||
/**
|
||||
* @var TestState[]
|
||||
*/
|
||||
protected $states = [];
|
||||
|
||||
/**
|
||||
* @return TestState[]
|
||||
*/
|
||||
public function getStates()
|
||||
{
|
||||
return $this->states;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TestState[] $states
|
||||
* @return $this
|
||||
*/
|
||||
public function setStates(array $states)
|
||||
{
|
||||
$this->states = $states;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setUp(SapphireTest $test)
|
||||
{
|
||||
foreach ($this->states as $state) {
|
||||
$state->setUp($test);
|
||||
}
|
||||
}
|
||||
|
||||
public function tearDown(SapphireTest $test)
|
||||
{
|
||||
// Tear down in reverse order
|
||||
/** @var TestState $state */
|
||||
foreach (array_reverse($this->states) as $state) {
|
||||
$state->tearDown($test);
|
||||
}
|
||||
}
|
||||
|
||||
public function setUpOnce($class)
|
||||
{
|
||||
foreach ($this->states as $state) {
|
||||
$state->setUpOnce($class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called once on tear down
|
||||
*
|
||||
* @param string $class Class being torn down
|
||||
*/
|
||||
public function tearDownOnce($class)
|
||||
{
|
||||
// Tear down in reverse order
|
||||
/** @var TestState $state */
|
||||
foreach (array_reverse($this->states) as $state) {
|
||||
$state->tearDownOnce($class);
|
||||
}
|
||||
}
|
||||
}
|
39
src/Dev/TestState.php
Normal file
39
src/Dev/TestState.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\Dev;
|
||||
|
||||
/**
|
||||
* Helper for resetting, booting, or cleaning up test state.
|
||||
*
|
||||
* SapphireTest will detect all implementors of this interface during test execution
|
||||
*/
|
||||
interface TestState extends TestOnly
|
||||
{
|
||||
/**
|
||||
* Called on setup
|
||||
*
|
||||
* @param SapphireTest $test
|
||||
*/
|
||||
public function setUp(SapphireTest $test);
|
||||
|
||||
/**
|
||||
* Called on tear down
|
||||
*
|
||||
* @param SapphireTest $test
|
||||
*/
|
||||
public function tearDown(SapphireTest $test);
|
||||
|
||||
/**
|
||||
* Called once on setup
|
||||
*
|
||||
* @param string $class Class being setup
|
||||
*/
|
||||
public function setUpOnce($class);
|
||||
|
||||
/**
|
||||
* Called once on tear down
|
||||
*
|
||||
* @param string $class Class being torn down
|
||||
*/
|
||||
public function tearDownOnce($class);
|
||||
}
|
@ -10,6 +10,7 @@ use SilverStripe\Control\Controller;
|
||||
use SilverStripe\Control\Director;
|
||||
use SilverStripe\Control\Email\Email;
|
||||
use SilverStripe\Control\Email\Mailer;
|
||||
use SilverStripe\Core\Config\Config;
|
||||
use SilverStripe\Core\Convert;
|
||||
use SilverStripe\Core\Injector\Injector;
|
||||
use SilverStripe\Dev\Deprecation;
|
||||
@ -176,14 +177,6 @@ class Member extends DataObject
|
||||
*/
|
||||
private static $unique_identifier_field = 'Email';
|
||||
|
||||
/**
|
||||
* Object for validating user's password
|
||||
*
|
||||
* @config
|
||||
* @var PasswordValidator
|
||||
*/
|
||||
private static $password_validator = null;
|
||||
|
||||
/**
|
||||
* @config
|
||||
* The number of days that a password should be valid for.
|
||||
@ -369,23 +362,31 @@ class Member extends DataObject
|
||||
/**
|
||||
* Set a {@link PasswordValidator} object to use to validate member's passwords.
|
||||
*
|
||||
* @param PasswordValidator $pv
|
||||
* @param PasswordValidator $validator
|
||||
*/
|
||||
public static function set_password_validator($pv)
|
||||
public static function set_password_validator(PasswordValidator $validator = null)
|
||||
{
|
||||
self::$password_validator = $pv;
|
||||
// Override existing config
|
||||
Config::modify()->remove(Injector::class, PasswordValidator::class);
|
||||
if ($validator) {
|
||||
Injector::inst()->registerService($validator, PasswordValidator::class);
|
||||
} else {
|
||||
Injector::inst()->unregisterNamedObject(PasswordValidator::class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current {@link PasswordValidator}
|
||||
* Returns the default {@link PasswordValidator}
|
||||
*
|
||||
* @return PasswordValidator
|
||||
*/
|
||||
public static function password_validator()
|
||||
{
|
||||
return self::$password_validator;
|
||||
if (Injector::inst()->has(PasswordValidator::class)) {
|
||||
return Injector::inst()->get(PasswordValidator::class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public function isPasswordExpired()
|
||||
{
|
||||
@ -1605,16 +1606,17 @@ class Member extends DataObject
|
||||
public function validate()
|
||||
{
|
||||
$valid = parent::validate();
|
||||
$validator = static::password_validator();
|
||||
|
||||
if (!$this->ID || $this->isChanged('Password')) {
|
||||
if ($this->Password && self::$password_validator) {
|
||||
$valid->combineAnd(self::$password_validator->validate($this->Password, $this));
|
||||
if ($this->Password && $validator) {
|
||||
$valid->combineAnd($validator->validate($this->Password, $this));
|
||||
}
|
||||
}
|
||||
|
||||
if ((!$this->ID && $this->SetPassword) || $this->isChanged('SetPassword')) {
|
||||
if ($this->SetPassword && self::$password_validator) {
|
||||
$valid->combineAnd(self::$password_validator->validate($this->SetPassword, $this));
|
||||
if ($this->SetPassword && $validator) {
|
||||
$valid->combineAnd($validator->validate($this->SetPassword, $this));
|
||||
}
|
||||
}
|
||||
|
||||
|
39
src/View/Dev/RequirementsTestState.php
Normal file
39
src/View/Dev/RequirementsTestState.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace SilverStripe\View\Dev;
|
||||
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
use SilverStripe\Dev\TestState;
|
||||
use SilverStripe\View\Requirements;
|
||||
use SilverStripe\View\Requirements_Backend;
|
||||
|
||||
/**
|
||||
* Resets requirements for test state
|
||||
*/
|
||||
class RequirementsTestState implements TestState
|
||||
{
|
||||
/**
|
||||
* @var Requirements_Backend
|
||||
*/
|
||||
protected $backend = null;
|
||||
|
||||
public function setUp(SapphireTest $test)
|
||||
{
|
||||
$this->backend = Requirements::backend();
|
||||
Requirements::set_backend(Requirements_Backend::create());
|
||||
}
|
||||
|
||||
public function tearDown(SapphireTest $test)
|
||||
{
|
||||
Requirements::set_backend($this->backend);
|
||||
}
|
||||
|
||||
public function setUpOnce($class)
|
||||
{
|
||||
}
|
||||
|
||||
public function tearDownOnce($class)
|
||||
{
|
||||
}
|
||||
}
|
@ -2,12 +2,11 @@
|
||||
|
||||
namespace SilverStripe\View;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use SilverStripe\Control\HTTPResponse;
|
||||
use SilverStripe\Core\Config\Config;
|
||||
use SilverStripe\Core\Flushable;
|
||||
use SilverStripe\Core\Injector\Injector;
|
||||
use SilverStripe\Dev\Deprecation;
|
||||
use SilverStripe\Control\HTTPResponse;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Requirements tracker for JavaScript and CSS.
|
||||
@ -104,7 +103,7 @@ class Requirements implements Flushable
|
||||
public static function backend()
|
||||
{
|
||||
if (!self::$backend) {
|
||||
self::$backend = Injector::inst()->create('SilverStripe\\View\\Requirements_Backend');
|
||||
self::$backend = Requirements_Backend::create();
|
||||
}
|
||||
return self::$backend;
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
namespace SilverStripe\View;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use SilverStripe\Assets\File;
|
||||
use SilverStripe\Assets\Storage\GeneratedAssetHandler;
|
||||
use SilverStripe\Control\Director;
|
||||
@ -13,7 +13,6 @@ use SilverStripe\Core\Convert;
|
||||
use SilverStripe\Core\Injector\Injectable;
|
||||
use SilverStripe\Dev\Debug;
|
||||
use SilverStripe\Dev\Deprecation;
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
use SilverStripe\i18n\i18n;
|
||||
|
||||
class Requirements_Backend
|
||||
|
@ -3,4 +3,3 @@
|
||||
require __DIR__ . '/bootstrap/init.php';
|
||||
require __DIR__ . '/bootstrap/cli.php';
|
||||
require __DIR__ . '/bootstrap/environment.php';
|
||||
require __DIR__ . '/bootstrap/phpunit.php';
|
||||
|
@ -1,10 +0,0 @@
|
||||
<?php
|
||||
|
||||
// Default database settings
|
||||
global $project;
|
||||
$project = 'mysite';
|
||||
|
||||
global $database;
|
||||
$database = '';
|
||||
|
||||
require_once('conf/ConfigureFromEnv.php');
|
@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
// Bootstrap for running SapphireTests
|
||||
|
||||
// Connect to database
|
||||
use SilverStripe\ORM\DB;
|
||||
|
||||
require_once __DIR__ . '/../../src/Core/functions.php';
|
||||
require_once __DIR__ . '/../php/Control/FakeController.php';
|
||||
|
||||
// Bootstrap a mock project configuration
|
||||
require __DIR__ . '/mysite.php';
|
||||
|
||||
global $databaseConfig;
|
||||
DB::connect($databaseConfig);
|
||||
|
||||
// Now set a fake REQUEST_URI
|
||||
$_SERVER['REQUEST_URI'] = BASE_URL;
|
||||
|
||||
// Fake a session
|
||||
$_SESSION = null;
|
||||
|
||||
// Remove the error handler so that PHPUnit can add its own
|
||||
restore_error_handler();
|
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\Control\Tests;
|
||||
|
||||
use SilverStripe\Control\Session;
|
||||
use SilverStripe\Core\Injector\Injector;
|
||||
use SilverStripe\Control\HTTPRequest;
|
||||
use SilverStripe\Control\HTTPResponse;
|
||||
use SilverStripe\Control\Controller;
|
||||
|
||||
// Fake a current controller. Way harder than it should be
|
||||
class FakeController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->pushCurrent();
|
||||
$session = new Session(isset($_SESSION) ? $_SESSION : array());
|
||||
$request = new HTTPRequest('GET', '/');
|
||||
$request->setSession($session);
|
||||
$this->setRequest($request);
|
||||
$this->setResponse(new HTTPResponse());
|
||||
|
||||
$this->doInit();
|
||||
}
|
||||
}
|
@ -967,7 +967,10 @@ class InjectorTest extends SapphireTest
|
||||
// Test that nested injector values can be overridden
|
||||
Injector::nest();
|
||||
$this->nestingLevel++;
|
||||
Injector::inst()->unregisterAllObjects();
|
||||
Injector::inst()->unregisterObjects([
|
||||
TestStaticInjections::class,
|
||||
MyParentClass::class,
|
||||
]);
|
||||
$newsi = Injector::inst()->get(TestStaticInjections::class);
|
||||
$newsi->backend = new InjectorTest\OriginalRequirementsBackend();
|
||||
Injector::inst()->registerService($newsi, TestStaticInjections::class);
|
||||
@ -990,7 +993,10 @@ class InjectorTest extends SapphireTest
|
||||
$this->assertInstanceOf(MyChildClass::class, Injector::inst()->get(MyChildClass::class));
|
||||
|
||||
// Test reset of cache
|
||||
Injector::inst()->unregisterAllObjects();
|
||||
Injector::inst()->unregisterObjects([
|
||||
TestStaticInjections::class,
|
||||
MyParentClass::class,
|
||||
]);
|
||||
$si = Injector::inst()->get(TestStaticInjections::class);
|
||||
$this->assertInstanceOf(TestStaticInjections::class, $si);
|
||||
$this->assertInstanceOf(NewRequirementsBackend::class, $si->backend);
|
||||
|
@ -6,11 +6,9 @@ use SilverStripe\Dev\TestOnly;
|
||||
|
||||
class TestStaticInjections implements TestOnly
|
||||
{
|
||||
|
||||
public $backend;
|
||||
/**
|
||||
* @config
|
||||
*/
|
||||
|
||||
/** @config */
|
||||
private static $dependencies = array(
|
||||
'backend' => '%$SilverStripe\\Core\\Tests\\Injector\\InjectorTest\\NewRequirementsBackend'
|
||||
);
|
||||
|
@ -2,8 +2,11 @@
|
||||
|
||||
namespace SilverStripe\Core\Tests;
|
||||
|
||||
use SilverStripe\Control\Controller;
|
||||
use SilverStripe\Core\ClassInfo;
|
||||
use SilverStripe\Core\Extension;
|
||||
use SilverStripe\Core\Injector\Injector;
|
||||
use SilverStripe\Core\Tests\ObjectTest\BaseObject;
|
||||
use SilverStripe\Core\Tests\ObjectTest\ExtendTest1;
|
||||
use SilverStripe\Core\Tests\ObjectTest\ExtendTest2;
|
||||
use SilverStripe\Core\Tests\ObjectTest\ExtendTest3;
|
||||
@ -16,7 +19,6 @@ use SilverStripe\Core\Tests\ObjectTest\MyObject;
|
||||
use SilverStripe\Core\Tests\ObjectTest\MySubObject;
|
||||
use SilverStripe\Core\Tests\ObjectTest\TestExtension;
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
use SilverStripe\Control\Controller;
|
||||
use SilverStripe\Versioned\Versioned;
|
||||
|
||||
/**
|
||||
@ -30,7 +32,10 @@ class ObjectTest extends SapphireTest
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
Injector::inst()->unregisterAllObjects();
|
||||
Injector::inst()->unregisterObjects([
|
||||
Extension::class,
|
||||
BaseObject::class,
|
||||
]);
|
||||
}
|
||||
|
||||
public function testHasmethodBehaviour()
|
||||
|
Loading…
Reference in New Issue
Block a user