Skip to content
This repository was archived by the owner on Feb 6, 2020. It is now read-only.

Commit c679418

Browse files
author
fhein
committed
Adds a test to verify that build/get/has remain stable and correct over
internal state changes.
1 parent aea63ce commit c679418

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed

test/CommonServiceLocatorBehaviorsTrait.php

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
use function call_user_func_array;
3030
use function restore_error_handler;
3131
use function set_error_handler;
32+
use ZendTest\ServiceManager\TestAsset\SampleFactory;
3233

3334
trait CommonServiceLocatorBehaviorsTrait
3435
{
@@ -879,4 +880,128 @@ public function testCoverageDepthFirstTaggingOnRecursiveAliasDefinitions()
879880
$this->assertSame($sm->get('alias1'), $sm->get('alias2'));
880881
$this->assertSame($sm->get(stdClass::class), $sm->get('alias1'));
881882
}
883+
884+
/**
885+
* The particular test procedure called by
886+
* testConsistencyOverInternalStates
887+
*
888+
* This test calls build()/get() and in between has() 3 times for
889+
* the given service name.
890+
* It asserts that sm continues to have (has) a service, asserts
891+
* that the built services each reference an object different
892+
* from all other objects, and asserts that the services got
893+
* reference the same object.
894+
*
895+
* @see testConsistencyOverInternalStates
896+
*
897+
* @param ContainerInterface $smTemplate
898+
* @param string $name
899+
* @param array[] string $test
900+
*/
901+
protected function checkConsistencyOverInternalStates($smTemplate, $name, $test)
902+
{
903+
$sm = clone $smTemplate;
904+
$object['get'] = [];
905+
$object['build'] = [];
906+
907+
// call get()/build() and store the retrieved
908+
// objects in $object['get'] or $object['build']
909+
// respectively
910+
foreach ($test as $method) {
911+
$object[$method][] = $sm->$method($name);
912+
$this->assertTrue($sm->has($name));
913+
}
914+
915+
// if there is more than one object in $object['get']
916+
// compare all to the first
917+
$nrShared = count($object['get']);
918+
for ($i = 1; $i < $nrShared; $i++) {
919+
$this->assertSame($object['get'][0], $object['get'][$i]);
920+
}
921+
// objects from object['build'] have to be different
922+
// from all other objects
923+
foreach ($object['build'] as $idx1 => $nonSharedObj) {
924+
foreach ($object['get'] as $sharedObj) {
925+
$this->assertNotSame($nonSharedObj, $sharedObj);
926+
}
927+
foreach ($object['build'] as $idx2 => $nonSharedObj2) {
928+
if ($idx1 !== $idx2) {
929+
$this->assertNotSame($nonSharedObj, $nonSharedObj2);
930+
}
931+
}
932+
}
933+
}
934+
935+
/**
936+
* The ServiceManager can change internal state on calls to get,
937+
* build or has, latter not currently. Possible state changes
938+
* are caching a factory, registering a service produced by
939+
* a factory, ...
940+
*
941+
* This tests performs three consecutive calls to build/get for
942+
* each registered service to push the service manager through
943+
* all internal states, thereby verifying that build/get/has
944+
* remain stable through the internal states.
945+
*
946+
* @see testConsistencyOverInternalStates below
947+
*
948+
* @param ContainerInterface $smTemplate
949+
* @param string $name
950+
* @param array[] string $test
951+
*/
952+
public function testConsistencyOverInternalStates()
953+
{
954+
$config = [
955+
'factories' => [
956+
'factory' => SampleFactory::class,
957+
'service' => function ($container, $requestedName, array $options = null) {
958+
return new stdClass();
959+
},
960+
],
961+
'invokables' => [
962+
'invokable' => InvokableObject::class,
963+
],
964+
'services' => [
965+
'service' => new stdClass(),
966+
],
967+
'aliases' => [
968+
'serviceAlias' => 'service',
969+
'invokableAlias' => 'invokable',
970+
'factoryAlias' => 'factory',
971+
'abstractFactoryAlias' => stdClass::class
972+
],
973+
'abstract_factories' => [
974+
SimpleAbstractFactory::class,
975+
]
976+
];
977+
978+
$smTemplate = $this->createContainer($config);
979+
980+
// produce all 3-tuples of 'build' and 'get'
981+
$methods = ['get', 'build'];
982+
foreach ($methods as $method1) {
983+
foreach ($methods as $method2) {
984+
foreach ($methods as $method3) {
985+
$tests[] = [$method1, $method2, $method3];
986+
}
987+
}
988+
}
989+
990+
// To allow changes to the config above
991+
// $names is not hard coded
992+
$names = array_merge(
993+
$config['factories'],
994+
$config['invokables'],
995+
$config['services'],
996+
$config['aliases']
997+
);
998+
$names[stdClass::class] = true;
999+
1000+
foreach ($names as $name => $_) {
1001+
foreach ($tests as $test) {
1002+
$sm = clone $smTemplate;
1003+
$this->checkConsistencyOverInternalStates($smTemplate, $name, $test);
1004+
}
1005+
}
1006+
}
8821007
}

0 commit comments

Comments
 (0)