Skip to content
Commits on Source (3)
...@@ -28,4 +28,4 @@ lint: ...@@ -28,4 +28,4 @@ lint:
test: test:
stage: test stage: test
script: script:
- php composer.phar test - php composer.phar test -- -f pretty
\ No newline at end of file \ No newline at end of file
<?php
namespace spec\Minds\UnleashClient\Entities;
use Minds\UnleashClient\Entities\Context;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ContextSpec extends ObjectBehavior
{
public function it_is_initializable()
{
$this->shouldHaveType(Context::class);
}
public function it_should_set_and_get_user_id()
{
$this
->getUserId()
->shouldReturn(null);
$this
->setUserId('phpspec')
->getUserId()
->shouldReturn('phpspec');
}
public function it_should_set_and_get_session_id()
{
$this
->getSessionId()
->shouldReturn(null);
$this
->setSessionId('phpspec')
->getSessionId()
->shouldReturn('phpspec');
}
public function it_should_set_and_get_remote_address()
{
$this
->getRemoteAddress()
->shouldReturn(null);
$this
->setRemoteAddress('127.0.0.1')
->getRemoteAddress()
->shouldReturn('127.0.0.1');
}
public function it_should_set_and_get_host_name()
{
$this
->getHostName()
->shouldReturn(null);
$this
->setHostName('phpspec.test')
->getHostName()
->shouldReturn('phpspec.test');
}
}
<?php
namespace spec\Minds\UnleashClient\Entities;
use Minds\UnleashClient\Entities\Feature;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class FeatureSpec extends ObjectBehavior
{
public function it_is_initializable()
{
$this->shouldHaveType(Feature::class);
}
public function it_should_set_and_get_name()
{
$this
->getName()
->shouldReturn('');
$this
->setName('phpspec')
->getName()
->shouldReturn('phpspec');
}
public function it_should_set_and_get_description()
{
$this
->getDescription()
->shouldReturn('');
$this
->setDescription('phpspec')
->getDescription()
->shouldReturn('phpspec');
}
public function it_should_set_and_get_enabled_flag()
{
$this
->isEnabled()
->shouldReturn(false);
$this
->setEnabled(true)
->isEnabled()
->shouldReturn(true);
$this
->setEnabled(false)
->isEnabled()
->shouldReturn(false);
}
}
<?php
namespace spec\Minds\UnleashClient\Entities;
use Minds\UnleashClient\Entities\Strategy;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class StrategySpec extends ObjectBehavior
{
public function it_is_initializable()
{
$this->shouldHaveType(Strategy::class);
}
public function it_should_set_and_get_name()
{
$this
->getName()
->shouldReturn('');
$this
->setName('phpspec')
->getName()
->shouldReturn('phpspec');
}
public function it_should_set_and_get_parameters()
{
$this
->getParameters()
->shouldReturn([]);
$this
->setParameters([
'phpspec' => 1
])
->getParameters()
->shouldReturn([
'phpspec' => 1
]);
}
}
<?php
namespace spec\Minds\UnleashClient\Factories;
use Minds\UnleashClient\Entities\Feature;
use Minds\UnleashClient\Entities\Strategy;
use Minds\UnleashClient\Factories\FeatureFactory;
use Minds\UnleashClient\Factories\StrategyFactory;
use PhpSpec\Exception\Example\FailureException;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class FeatureFactorySpec extends ObjectBehavior
{
/** @var StrategyFactory */
protected $strategyFactory;
public function let(
StrategyFactory $strategyFactory
) {
$this->strategyFactory = $strategyFactory;
$this->beConstructedWith($strategyFactory);
}
public function it_is_initializable()
{
$this->shouldHaveType(FeatureFactory::class);
}
public function it_should_build(
Strategy $strategy1,
Strategy $strategy2
) {
$this->strategyFactory->build(['strategy.1'])
->shouldBeCalled()
->willReturn($strategy1);
$this->strategyFactory->build(['strategy.2'])
->shouldBeCalled()
->willReturn($strategy2);
$this
->build([
'name' => 'phpspec',
'description' => 'a phpspec feature',
'enabled' => true,
'strategies' => [
['strategy.1'],
['strategy.2']
]
])
->shouldBeAFeature([
'name' => 'phpspec',
'description' => 'a phpspec feature',
'enabled' => true,
'strategies' => [
$strategy1,
$strategy2
]
]);
}
public function getMatchers(): array
{
return [
'beAFeature' => function ($subject, $data) {
if (!($subject instanceof Feature)) {
throw new FailureException(sprintf("Subject should be a %s instance", Feature::class));
}
if ($subject->getName() !== $data['name']) {
throw new FailureException('Unexpected subject getName() value');
}
if ($subject->getDescription() !== $data['description']) {
throw new FailureException('Unexpected subject getDescription() value');
}
if ($subject->isEnabled() !== $data['enabled']) {
throw new FailureException('Unexpected subject isEnabled() value');
}
if ($subject->getStrategies() !== $data['strategies']) {
throw new FailureException('Unexpected subject getStrategies() value');
}
return true;
}
];
}
}
<?php
namespace spec\Minds\UnleashClient\Factories;
use Minds\UnleashClient\Entities\Strategy;
use Minds\UnleashClient\Factories\StrategyAlgorithmFactory;
use Minds\UnleashClient\StrategyAlgorithms\DefaultStrategyAlgorithm;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Psr\Log\LoggerInterface;
class StrategyAlgorithmFactorySpec extends ObjectBehavior
{
/** @var LoggerInterface */
protected $logger;
public function let(
LoggerInterface $logger
) {
$this->logger = $logger;
$this->beConstructedWith($logger);
}
public function it_is_initializable()
{
$this->shouldHaveType(StrategyAlgorithmFactory::class);
}
public function it_should_build(
Strategy $strategy
) {
$strategy->getName()
->shouldBeCalled()
->willReturn('default');
$this
->build($strategy)
->shouldBeAnInstanceOf(DefaultStrategyAlgorithm::class);
}
public function it_should_return_null_if_class_does_not_exist(
Strategy $strategy
) {
$strategy->getName()
->shouldBeCalled()
->willReturn('php~notexisting~class');
$this->logger->warning(Argument::cetera())
->shouldBeCalled();
$this
->build($strategy)
->shouldReturn(null);
}
}
<?php
namespace spec\Minds\UnleashClient\Factories;
use Minds\UnleashClient\Entities\Strategy;
use Minds\UnleashClient\Factories\StrategyFactory;
use PhpSpec\Exception\Example\FailureException;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class StrategyFactorySpec extends ObjectBehavior
{
public function it_is_initializable()
{
$this->shouldHaveType(StrategyFactory::class);
}
public function it_should_build()
{
$this
->build([
'name' => 'phpspec',
'parameters' => [
'test' => 1,
]
])
->shouldBeAStrategy([
'name' => 'phpspec',
'parameters' => [
'test' => 1,
]
]);
}
public function getMatchers(): array
{
return [
'beAStrategy' => function ($subject, $data) {
if (!($subject instanceof Strategy)) {
throw new FailureException(sprintf("Subject should be a %s instance", Strategy::class));
}
if ($subject->getName() !== $data['name']) {
throw new FailureException('Unexpected subject getName() value');
}
if ($subject->getParameters() !== $data['parameters']) {
throw new FailureException('Unexpected subject getParameters() value');
}
return true;
}
];
}
}
<?php
namespace spec\Minds\UnleashClient\Helpers;
use Minds\UnleashClient\Helpers\NormalizedValue;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class NormalizedValueSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType(NormalizedValue::class);
}
public function it_should_build()
{
$this
->build('', 'test', 100)
->shouldReturn(0);
$this
->build('phpspec', 'test', 100)
->shouldReturn(96);
$this
->build('minds', 'test', 100)
->shouldReturn(89);
}
}
...@@ -23,9 +23,9 @@ class Context ...@@ -23,9 +23,9 @@ class Context
/** /**
* Gets the context user ID * Gets the context user ID
* @return string * @return string|null
*/ */
public function getUserId(): string public function getUserId(): ?string
{ {
return $this->userId; return $this->userId;
} }
...@@ -43,9 +43,9 @@ class Context ...@@ -43,9 +43,9 @@ class Context
/** /**
* Gets the context session ID * Gets the context session ID
* @return string * @return string|null
*/ */
public function getSessionId(): string public function getSessionId(): ?string
{ {
return $this->sessionId; return $this->sessionId;
} }
...@@ -63,9 +63,9 @@ class Context ...@@ -63,9 +63,9 @@ class Context
/** /**
* Gets the context remote address * Gets the context remote address
* @return string * @return string|null
*/ */
public function getRemoteAddress(): string public function getRemoteAddress(): ?string
{ {
return $this->remoteAddress; return $this->remoteAddress;
} }
...@@ -83,9 +83,9 @@ class Context ...@@ -83,9 +83,9 @@ class Context
/** /**
* Gets the context host name * Gets the context host name
* @return string * @return string|null
*/ */
public function getHostName(): string public function getHostName(): ?string
{ {
return $this->hostName; return $this->hostName;
} }
......
...@@ -10,7 +10,7 @@ namespace Minds\UnleashClient\Entities; ...@@ -10,7 +10,7 @@ namespace Minds\UnleashClient\Entities;
class Strategy class Strategy
{ {
/** @var string */ /** @var string */
protected $name; protected $name = '';
/** @var array */ /** @var array */
protected $parameters = []; protected $parameters = [];
......
...@@ -19,7 +19,7 @@ class NormalizedValue ...@@ -19,7 +19,7 @@ class NormalizedValue
* @param int $normalizer * @param int $normalizer
* @return int * @return int
*/ */
public static function build(string $id, string $groupId, int $normalizer = 100): int public function build(string $id, string $groupId, int $normalizer = 100): int
{ {
if (!$id) { if (!$id) {
return 0; return 0;
......
...@@ -18,13 +18,19 @@ class FlexibleRolloutStrategyAlgorithm implements StrategyAlgorithm ...@@ -18,13 +18,19 @@ class FlexibleRolloutStrategyAlgorithm implements StrategyAlgorithm
/** @var LoggerInterface|Logger */ /** @var LoggerInterface|Logger */
protected $logger; protected $logger;
/** @var NormalizedValue */
protected $normalizedValue;
/** /**
* @inheritDoc * @inheritDoc
* @param NormalizedValue $normalizedValue
*/ */
public function __construct( public function __construct(
LoggerInterface $logger = null LoggerInterface $logger = null,
NormalizedValue $normalizedValue = null
) { ) {
$this->logger = $logger ?: new Logger(); $this->logger = $logger ?: new Logger();
$this->normalizedValue = $normalizedValue ?: new NormalizedValue();
} }
/** /**
...@@ -62,7 +68,8 @@ class FlexibleRolloutStrategyAlgorithm implements StrategyAlgorithm ...@@ -62,7 +68,8 @@ class FlexibleRolloutStrategyAlgorithm implements StrategyAlgorithm
return false; return false;
} }
$stickinessValue = NormalizedValue::build($stickinessId, $groupId); $stickinessValue = $this->normalizedValue
->build($stickinessId, $groupId);
$this->logger->debug(static::class, [ $this->logger->debug(static::class, [
$stickiness, $stickiness,
......
...@@ -18,13 +18,19 @@ class GradualRolloutSessionIdStrategyAlgorithm implements StrategyAlgorithm ...@@ -18,13 +18,19 @@ class GradualRolloutSessionIdStrategyAlgorithm implements StrategyAlgorithm
/** @var LoggerInterface|Logger */ /** @var LoggerInterface|Logger */
protected $logger; protected $logger;
/** @var NormalizedValue */
protected $normalizedValue;
/** /**
* @inheritDoc * @inheritDoc
* @param NormalizedValue $normalizedValue
*/ */
public function __construct( public function __construct(
LoggerInterface $logger = null LoggerInterface $logger = null,
NormalizedValue $normalizedValue = null
) { ) {
$this->logger = $logger ?: new Logger(); $this->logger = $logger ?: new Logger();
$this->normalizedValue = $normalizedValue ?: new NormalizedValue();
} }
/** /**
...@@ -42,7 +48,8 @@ class GradualRolloutSessionIdStrategyAlgorithm implements StrategyAlgorithm ...@@ -42,7 +48,8 @@ class GradualRolloutSessionIdStrategyAlgorithm implements StrategyAlgorithm
return false; return false;
} }
$sessionIdValue = NormalizedValue::build($sessionId, $groupId); $sessionIdValue = $this->normalizedValue
->build($sessionId, $groupId);
$this->logger->debug(static::class, [ $this->logger->debug(static::class, [
$sessionIdValue, $sessionIdValue,
......
...@@ -18,13 +18,19 @@ class GradualRolloutUserIdStrategyAlgorithm implements StrategyAlgorithm ...@@ -18,13 +18,19 @@ class GradualRolloutUserIdStrategyAlgorithm implements StrategyAlgorithm
/** @var LoggerInterface|Logger */ /** @var LoggerInterface|Logger */
protected $logger; protected $logger;
/** @var NormalizedValue */
protected $normalizedValue;
/** /**
* @inheritDoc * @inheritDoc
* @param NormalizedValue $normalizedValue
*/ */
public function __construct( public function __construct(
LoggerInterface $logger = null LoggerInterface $logger = null,
NormalizedValue $normalizedValue = null
) { ) {
$this->logger = $logger ?: new Logger(); $this->logger = $logger ?: new Logger();
$this->normalizedValue = $normalizedValue ?: new NormalizedValue();
} }
/** /**
...@@ -42,7 +48,8 @@ class GradualRolloutUserIdStrategyAlgorithm implements StrategyAlgorithm ...@@ -42,7 +48,8 @@ class GradualRolloutUserIdStrategyAlgorithm implements StrategyAlgorithm
return false; return false;
} }
$userIdValue = NormalizedValue::build($userId, $groupId); $userIdValue = $this->normalizedValue
->build($userId, $groupId);
$this->logger->debug(static::class, [ $this->logger->debug(static::class, [
$userIdValue, $userIdValue,
......