| Current Path : /home/rtorresani/www/vendor/magento/framework/ObjectManager/Test/Unit/Factory/ |
| Current File : //home/rtorresani/www/vendor/magento/framework/ObjectManager/Test/Unit/Factory/FactoryTest.php |
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\Framework\ObjectManager\Test\Unit\Factory;
use Magento\Framework\ObjectManager\Config\Config;
use Magento\Framework\ObjectManager\DefinitionInterface;
use Magento\Framework\ObjectManager\Factory\Dynamic\Developer;
use Magento\Framework\ObjectManager\FactoryInterface;
use Magento\Framework\ObjectManager\ObjectManager;
use Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\OneScalar;
use Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Polymorphous;
use Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\SemiVariadic;
use Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Two;
use Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Variadic;
use PHPUnit\Framework\TestCase;
class FactoryTest extends TestCase
{
/**
* @var FactoryInterface
*/
private $factory;
/**
* @var Config
*/
private $config;
/**
* @var ObjectManager
*/
private $objectManager;
/**
* Setup tests
*/
protected function setUp(): void
{
$this->config = new Config();
$this->factory = new Developer($this->config);
$this->objectManager = new ObjectManager($this->factory, $this->config);
$this->factory->setObjectManager($this->objectManager);
}
/**
* Test create without args
*/
public function testCreateNoArgs()
{
$this->assertInstanceOf('StdClass', $this->factory->create(\StdClass::class));
}
public function testResolveArgumentsException()
{
$this->expectException('UnexpectedValueException');
$this->expectExceptionMessage('Invalid parameter configuration provided for $firstParam argument');
$configMock = $this->createMock(Config::class);
$configMock->expects($this->once())->method('getArguments')->willReturn(
[
'firstParam' => 1,
]
);
$definitionsMock = $this->getMockForAbstractClass(DefinitionInterface::class);
$definitionsMock->expects($this->once())->method('getParameters')->willReturn(
[
[
'firstParam',
'string',
true,
'default_val',
false
]
]
);
$this->factory = new Developer(
$configMock,
null,
$definitionsMock
);
$this->objectManager = new ObjectManager($this->factory, $this->config);
$this->factory->setObjectManager($this->objectManager);
$this->factory->create(
OneScalar::class,
['foo' => 'bar']
);
}
/**
* Test create with one arg
*/
public function testCreateOneArg()
{
/**
* @var OneScalar $result
*/
$result = $this->factory->create(
OneScalar::class,
['foo' => 'bar']
);
$this->assertInstanceOf(OneScalar::class, $result);
$this->assertEquals('bar', $result->getFoo());
}
/**
* Test create with injectable
*/
public function testCreateWithInjectable()
{
// let's imitate that One is injectable by providing DI configuration for it
$this->config->extend(
[
OneScalar::class => [
'arguments' => ['foo' => 'bar'],
],
]
);
/**
* @var Two $result
*/
$result = $this->factory->create(Two::class);
$this->assertInstanceOf(Two::class, $result);
$this->assertInstanceOf(
OneScalar::class,
$result->getOne()
);
$this->assertEquals('bar', $result->getOne()->getFoo());
$this->assertEquals('optional', $result->getBaz());
}
/**
* @param string $startingClass
* @param string $terminationClass
* @dataProvider circularDataProvider
*/
public function testCircular($startingClass, $terminationClass)
{
$this->expectException('\LogicException');
$this->expectExceptionMessage(
sprintf('Circular dependency: %s depends on %s and vice versa.', $startingClass, $terminationClass)
);
$this->factory->create($startingClass);
}
/**
* @return array
*/
public function circularDataProvider()
{
$prefix = 'Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\\';
return [
["{$prefix}CircularOne", "{$prefix}CircularThree"],
["{$prefix}CircularTwo", "{$prefix}CircularOne"],
["{$prefix}CircularThree", "{$prefix}CircularTwo"]
];
}
/**
* Test create using reflection
*/
public function testCreateUsingReflection()
{
$type = Polymorphous::class;
$definitions = $this->getMockForAbstractClass(DefinitionInterface::class);
// should be more than defined in "switch" of create() method
$definitions->expects($this->once())->method('getParameters')->with($type)->willReturn(
[
['one', null, false, null, false],
['two', null, false, null, false],
['three', null, false, null, false],
['four', null, false, null, false],
['five', null, false, null, false],
['six', null, false, null, false],
['seven', null, false, null, false],
['eight', null, false, null, false],
['nine', null, false, null, false],
['ten', null, false, null, false],
]
);
$factory = new Developer($this->config, null, $definitions);
$result = $factory->create(
$type,
[
'one' => 1,
'two' => 2,
'three' => 3,
'four' => 4,
'five' => 5,
'six' => 6,
'seven' => 7,
'eight' => 8,
'nine' => 9,
'ten' => 10,
]
);
$this->assertSame(10, $result->getArg(9));
}
/**
* Test create objects with variadic argument in constructor
*
* @param $createArgs
* @param $expectedArg0
* @param $expectedArg1
* @dataProvider testCreateUsingVariadicDataProvider
*/
public function testCreateUsingVariadic(
$createArgs,
$expectedArg0,
$expectedArg1
) {
$type = Variadic::class;
$definitions = $this->getMockForAbstractClass(DefinitionInterface::class);
$definitions->expects($this->once())->method('getParameters')->with($type)->willReturn(
[
[
'oneScalars',
OneScalar::class,
false,
[],
true
],
]
);
$factory = new Developer($this->config, null, $definitions);
/**
* @var \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Variadic $variadic
*/
$variadic = is_null($createArgs)
? $factory->create($type)
: $factory->create($type, $createArgs);
$this->assertSame($expectedArg0, $variadic->getOneScalarByKey(0));
$this->assertSame($expectedArg1, $variadic->getOneScalarByKey(1));
}
/**
* @return array
*/
public function testCreateUsingVariadicDataProvider()
{
$oneScalar1 = $this->createMock(OneScalar::class);
$oneScalar2 = $this->createMock(OneScalar::class);
return [
'without_args' => [
null,
null,
null,
],
'with_empty_args' => [
[],
null,
null,
],
'with_empty_args_value' => [
[
'oneScalars' => []
],
null,
null,
],
'with_single_arg' => [
[
'oneScalars' => $oneScalar1
],
$oneScalar1,
null,
],
'with_full_args' => [
[
'oneScalars' => [
$oneScalar1,
$oneScalar2,
]
],
$oneScalar1,
$oneScalar2,
],
];
}
/**
* Test data can be injected into variadic arguments from di config
*/
public function testCreateVariadicFromDiConfig()
{
$oneScalar1 = $this->createMock(OneScalar::class);
$oneScalar2 = $this->createMock(OneScalar::class);
// let's imitate that Variadic is configured by providing DI configuration for it
$this->config->extend(
[
Variadic::class => [
'arguments' => [
'oneScalars' => [
$oneScalar1,
$oneScalar2,
]
]
],
]
);
/**
* @var \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Variadic $variadic
*/
$variadic = $this->factory->create(Variadic::class);
$this->assertSame($oneScalar1, $variadic->getOneScalarByKey(0));
$this->assertSame($oneScalar2, $variadic->getOneScalarByKey(1));
}
/**
* Test create objects with non variadic and variadic argument in constructor
*
* @param $createArgs
* @param $expectedFooValue
* @param $expectedArg0
* @param $expectedArg1
* @dataProvider testCreateUsingSemiVariadicDataProvider
*/
public function testCreateUsingSemiVariadic(
$createArgs,
$expectedFooValue,
$expectedArg0,
$expectedArg1
) {
$type = SemiVariadic::class;
$definitions = $this->getMockForAbstractClass(DefinitionInterface::class);
$definitions->expects($this->once())->method('getParameters')->with($type)->willReturn(
[
[
'foo',
null,
false,
SemiVariadic::DEFAULT_FOO_VALUE,
false
],
[
'oneScalars',
OneScalar::class,
false,
[],
true
],
]
);
$factory = new Developer($this->config, null, $definitions);
/**
* @var \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\SemiVariadic $semiVariadic
*/
$semiVariadic = is_null($createArgs)
? $factory->create($type)
: $factory->create($type, $createArgs);
$this->assertSame($expectedFooValue, $semiVariadic->getFoo());
$this->assertSame($expectedArg0, $semiVariadic->getOneScalarByKey(0));
$this->assertSame($expectedArg1, $semiVariadic->getOneScalarByKey(1));
}
/**
* @return array
*/
public function testCreateUsingSemiVariadicDataProvider()
{
$oneScalar1 = $this->createMock(OneScalar::class);
$oneScalar2 = $this->createMock(OneScalar::class);
return [
'without_args' => [
null,
SemiVariadic::DEFAULT_FOO_VALUE,
null,
null,
],
'with_empty_args' => [
[],
SemiVariadic::DEFAULT_FOO_VALUE,
null,
null,
],
'only_with_foo_value' => [
[
'foo' => 'baz'
],
'baz',
null,
null,
],
'only_with_oneScalars_empty_value' => [
[
'oneScalars' => []
],
SemiVariadic::DEFAULT_FOO_VALUE,
null,
null,
],
'only_with_oneScalars_single_value' => [
[
'oneScalars' => $oneScalar1
],
SemiVariadic::DEFAULT_FOO_VALUE,
$oneScalar1,
null,
],
'only_with_oneScalars_full_value' => [
[
'oneScalars' => [
$oneScalar1,
$oneScalar2,
]
],
SemiVariadic::DEFAULT_FOO_VALUE,
$oneScalar1,
$oneScalar2,
],
'with_all_values_defined_in_right_order' => [
[
'foo' => 'baz',
'oneScalars' => [
$oneScalar1,
$oneScalar2,
]
],
'baz',
$oneScalar1,
$oneScalar2,
],
'with_all_values_defined_in_reverse_order' => [
[
'oneScalars' => [
$oneScalar1,
$oneScalar2,
],
'foo' => 'baz',
],
'baz',
$oneScalar1,
$oneScalar2,
],
];
}
}