at the end of the day, it was inevitable
This commit is contained in:
@@ -0,0 +1,338 @@
|
||||
<?php
|
||||
|
||||
namespace Common\Context;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Behat\Gherkin\Node\PyStringNode;
|
||||
use Common\Util\DatabaseHelper;
|
||||
use Common\Util\Index\InternalSourceConnection;
|
||||
use Common\Util\Processor\DataProcessor;
|
||||
use Common\Util\Index\ExternalIndexConnection;
|
||||
use Common\Util\Index\InternalIndexConnection;
|
||||
use Common\Util\Matcher\AppMatcher;
|
||||
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use IndexBundle\Fixture\Executor\Factory\IndexFixtureExecutorFactory;
|
||||
use IndexBundle\Fixture\Executor\Factory\IndexFixtureExecutorFactoryInterface;
|
||||
use IndexBundle\Fixture\Loader\IndexFixtureLoader;
|
||||
use Seld\JsonLint\JsonParser;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Class AbstractContext
|
||||
* Base class for all application test context's.
|
||||
*
|
||||
* @package Common\Context
|
||||
*/
|
||||
class AbstractContext extends \PHPUnit_Framework_Assert implements Context
|
||||
{
|
||||
|
||||
use DatabaseContextTrait,
|
||||
IndexContextTrait;
|
||||
|
||||
/**
|
||||
* True if test running with debug.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $debug;
|
||||
|
||||
/**
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* Path to data fixtures directory.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fixturesDir;
|
||||
|
||||
/**
|
||||
* @var DataProcessor
|
||||
*/
|
||||
protected $processor;
|
||||
|
||||
/**
|
||||
* @var IndexFixtureExecutorFactoryInterface
|
||||
*/
|
||||
protected $indexExecutorFactory;
|
||||
|
||||
/**
|
||||
* True if all indices initialized.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private static $indexInitialized = false;
|
||||
|
||||
/**
|
||||
* Setup database schemas.
|
||||
*
|
||||
* @BeforeSuite
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function setup()
|
||||
{
|
||||
if (strtolower(trim(getenv('WITHOUT_CLEAR'))) !== 'true') {
|
||||
system('./bin/console --env=test cache:clear');
|
||||
system('./bin/console --env=test doctrine:database:create --if-not-exists -n');
|
||||
system('./bin/console --env=test doctrine:schema:update --force -n');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear external index and load fixtures before scenario.
|
||||
*
|
||||
* @BeforeScenario @external-index-fixtures
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setupExternalIndexFixtures()
|
||||
{
|
||||
$this->createIndexes();
|
||||
|
||||
echo 'Purge external index ... ';
|
||||
$this->externalIndex->purge();
|
||||
echo 'done'. PHP_EOL;
|
||||
|
||||
echo 'Load indices fixtures: '. PHP_EOL;
|
||||
|
||||
$loader = new IndexFixtureLoader($this->container);
|
||||
$loader->loadFromDirectory($this->fixturesDir);
|
||||
$this->indexExecutorFactory->external($this->externalIndex->getIndex())
|
||||
->setLogger(function ($message) {
|
||||
echo " > {$message}". PHP_EOL;
|
||||
})
|
||||
->execute($loader->getFixtures());
|
||||
|
||||
// Wait to insure that all fixtures was indexed.
|
||||
sleep(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear external index and load fixtures before scenario.
|
||||
*
|
||||
* @BeforeScenario @internal-index-fixtures
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setupInternalIndexFixtures()
|
||||
{
|
||||
$this->createIndexes();
|
||||
|
||||
echo 'Purge internal index ... ';
|
||||
$this->internalIndex->purge();
|
||||
echo 'done'. PHP_EOL;
|
||||
|
||||
echo 'Load indices fixtures: '. PHP_EOL;
|
||||
|
||||
$loader = new IndexFixtureLoader($this->container);
|
||||
$loader->loadFromDirectory($this->fixturesDir);
|
||||
$this->indexExecutorFactory->internal($this->internalIndex->getIndex())
|
||||
->setLogger(function ($message) {
|
||||
echo " > {$message}". PHP_EOL;
|
||||
})
|
||||
->execute($loader->getFixtures());
|
||||
|
||||
// Wait to insure that all fixtures was indexed.
|
||||
sleep(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear external index and load fixtures before scenario.
|
||||
*
|
||||
* @BeforeScenario @source-index-fixtures
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setupSourceIndexFixtures()
|
||||
{
|
||||
//
|
||||
// Remove source_update.date
|
||||
//
|
||||
// NOTICE: Insure that you don't run test in production :)
|
||||
//
|
||||
unlink(realpath(__DIR__ . '/../../../var/source_update.date'));
|
||||
|
||||
$this->createIndexes();
|
||||
$this->setupExternalIndexFixtures();
|
||||
|
||||
echo 'Purge source index ... ';
|
||||
$this->sourceIndex->purge();
|
||||
echo 'done'. PHP_EOL;
|
||||
|
||||
echo 'Load indices fixtures: '. PHP_EOL;
|
||||
|
||||
$loader = new IndexFixtureLoader($this->container);
|
||||
$loader->loadFromDirectory($this->fixturesDir);
|
||||
$this->indexExecutorFactory->source($this->sourceIndex->getIndex())
|
||||
->setLogger(function ($message) {
|
||||
echo " > {$message}". PHP_EOL;
|
||||
})
|
||||
->execute($loader->getFixtures());
|
||||
|
||||
// Wait to insure that all fixtures was indexed.
|
||||
sleep(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create indexes if we want to upload index fixtures.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function createIndexes()
|
||||
{
|
||||
if (! self::$indexInitialized
|
||||
&& (strtolower(trim(getenv('WITHOUT_CLEAR'))) !== 'true')) {
|
||||
$this->externalIndex->setup();
|
||||
$this->internalIndex->setup();
|
||||
$this->sourceIndex->setup();
|
||||
|
||||
self::$indexInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ContainerInterface $container A ContainerInterface instance.
|
||||
* @param string $fixturesDir Path to fixtures directory.
|
||||
*/
|
||||
public function __construct(ContainerInterface $container, $fixturesDir)
|
||||
{
|
||||
$this->debug = getenv('DEBUG') !== false;
|
||||
|
||||
$this->container = $container;
|
||||
$this->fixturesDir = realpath($fixturesDir);
|
||||
|
||||
if ($container->getParameter('kernel.environment') !== 'test') {
|
||||
$message = 'You should run test in test environment /:|';
|
||||
throw new \InvalidArgumentException($message);
|
||||
}
|
||||
|
||||
// Create database helper.
|
||||
// See Common\Context\DatabaseContextTrait
|
||||
$this->dataBaseHelper = new DatabaseHelper($container->get('doctrine'));
|
||||
|
||||
// Get serializer metadata for all entities.
|
||||
// We make it for simplification testing process. With this information
|
||||
// we can make more powerful expanders and matchers which help as to
|
||||
// write less but make more.
|
||||
/** @var EntityManagerInterface $em */
|
||||
$em = $this->container->get('doctrine.orm.default_entity_manager');
|
||||
|
||||
// Get all available entity fqcn's.
|
||||
$fqcnList = array_map(function (ClassMetadata $metadata) {
|
||||
return $metadata->getName();
|
||||
}, $em->getMetadataFactory()->getAllMetadata());
|
||||
|
||||
$entities = $this->processEntityMetadata($em, $fqcnList);
|
||||
// Register all entities.
|
||||
AppMatcher::registerEntities($entities);
|
||||
|
||||
$this->processor = new DataProcessor($container);
|
||||
|
||||
// Decorate indices connections.
|
||||
$this->externalIndex = new ExternalIndexConnection(
|
||||
$this->get('index.external')
|
||||
);
|
||||
|
||||
$this->internalIndex = new InternalIndexConnection(
|
||||
$this->get('index.articles')
|
||||
);
|
||||
|
||||
$this->sourceIndex = new InternalSourceConnection(
|
||||
$this->get('index.sources')
|
||||
);
|
||||
|
||||
$this->indexExecutorFactory = new IndexFixtureExecutorFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* @When /^(?:|I )[Ww]ait (?P<milliseconds>\d+) millisecond(?: until| for)?[\w\s]*$/
|
||||
*
|
||||
* @param integer $milliseconds Seconds count.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function wait($milliseconds)
|
||||
{
|
||||
usleep($milliseconds * 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a service.
|
||||
*
|
||||
* @param string $id The service identifier.
|
||||
*
|
||||
* @return object The associated service.
|
||||
*/
|
||||
protected function get($id)
|
||||
{
|
||||
return $this->container->get($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a parameter.
|
||||
*
|
||||
* @param string $name The parameter name.
|
||||
*
|
||||
* @return mixed The parameter value.
|
||||
*/
|
||||
protected function getParameter($name)
|
||||
{
|
||||
return $this->container->getParameter($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Match value against specified pattern.
|
||||
*
|
||||
* @param mixed $value Matched value.
|
||||
* @param mixed $pattern Pattern.
|
||||
* @param string $error Occurred error.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function match($value, $pattern, &$error)
|
||||
{
|
||||
$value = $this->processor->process($value);
|
||||
|
||||
$pattern = preg_replace('/\\s{2,}/', '', $pattern);
|
||||
|
||||
// Lint pattern only if it contains json.
|
||||
if (($pattern[0] === '{') || ($pattern[0] === '[')) {
|
||||
// Lint pattern.
|
||||
$lint = new JsonParser();
|
||||
$exception = $lint->lint($pattern);
|
||||
if ($exception !== null) {
|
||||
throw new \RuntimeException('Pattern lint: ' . $exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Process expressions between ##.
|
||||
$pattern = $this->processor->process($pattern);
|
||||
|
||||
return AppMatcher::match($value, $pattern, $error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lint json.
|
||||
*
|
||||
* @param PyStringNode|string $json Json to lint.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function lintJson($json)
|
||||
{
|
||||
if ($json instanceof PyStringNode) {
|
||||
$json = $json->getRaw();
|
||||
}
|
||||
|
||||
$linter = new JsonParser();
|
||||
$exception = $linter->lint($json);
|
||||
|
||||
if ($exception !== null) {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
<?php
|
||||
|
||||
namespace Common\Context;
|
||||
|
||||
use ApiBundle\Entity\NormalizableEntityInterface;
|
||||
use ApiBundle\Serializer\Metadata\Metadata;
|
||||
use AppBundle\Utils\Purger\TruncateORMPurger;
|
||||
use Behat\Gherkin\Node\TableNode;
|
||||
use Common\Util\DatabaseHelper;
|
||||
use Common\Util\Metadata\EntityMetadata;
|
||||
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
|
||||
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||
use Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader;
|
||||
|
||||
/**
|
||||
* Class DatabaseContextTrait
|
||||
* Contains steps definitions for working with database.
|
||||
*
|
||||
* @package Common\Context
|
||||
*/
|
||||
trait DatabaseContextTrait
|
||||
{
|
||||
|
||||
/**
|
||||
* @var DatabaseHelper
|
||||
*/
|
||||
private $dataBaseHelper;
|
||||
|
||||
/**
|
||||
* Clear database and load fixtures before scenario.
|
||||
*
|
||||
* @BeforeScenario @db-fixtures
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setupDbFixtures()
|
||||
{
|
||||
/** @var EntityManagerInterface $em */
|
||||
$em = $this->get('doctrine.orm.entity_manager');
|
||||
|
||||
echo 'Purge database ... ';
|
||||
$purger = new TruncateORMPurger(new ORMPurger($em));
|
||||
$purger->purge();
|
||||
echo 'done'. PHP_EOL;
|
||||
|
||||
$loader = new ContainerAwareLoader($this->container);
|
||||
$loader->loadFromDirectory($this->fixturesDir);
|
||||
|
||||
echo 'Load database fixtures:'. PHP_EOL;
|
||||
$executor = new ORMExecutor($em);
|
||||
$executor
|
||||
->setLogger(function ($message) {
|
||||
echo " > {$message}". PHP_EOL;
|
||||
});
|
||||
$executor->execute($loader->getFixtures(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^(?:|[Dd]atabase )[Hh]as entity (?P<name>.+)$/
|
||||
*
|
||||
* @param string $name Entity short name like AppBundle:Entity or FQCN.
|
||||
* @param TableNode $table Search parameters in table format.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function hasEntity($name, TableNode $table)
|
||||
{
|
||||
$params = [];
|
||||
|
||||
$tableData = $table->getTable();
|
||||
foreach ($tableData as $row) {
|
||||
$params[current($row)] = next($row);
|
||||
}
|
||||
|
||||
$entity = $this->dataBaseHelper->getEntity($name, $params);
|
||||
|
||||
self::assertNotNull(
|
||||
$entity,
|
||||
"Can't find entity {$name} with parameters " . PHP_EOL
|
||||
. json_encode($params, JSON_PRETTY_PRINT)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^(?:|[Dd]atabase )[Hh]as (?P<count>\d+) entity (?P<name>.+)$/
|
||||
* @Then /?[Dd]on't has entity (?P<name>.+)$?
|
||||
*
|
||||
* @param string $name Entity short name like AppBundle:Entity or FQCN.
|
||||
* @param integer $count Expected entities count.
|
||||
* @param TableNode $table Search parameters in table format.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function hasEntities($name, $count, TableNode $table)
|
||||
{
|
||||
$params = [];
|
||||
|
||||
$tableData = $table->getTable();
|
||||
foreach ($tableData as $row) {
|
||||
$params[current($row)] = next($row);
|
||||
}
|
||||
|
||||
$entities = $this->dataBaseHelper->getEntities($name, $params);
|
||||
|
||||
self::assertCount(
|
||||
(int) $count,
|
||||
$entities,
|
||||
"Can't find {$count} entity {$name} with parameters " . PHP_EOL
|
||||
. json_encode($params, JSON_PRETTY_PRINT) .PHP_EOL .
|
||||
'Actually found: '. count($entities)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^[Ii] want to delete entity (?P<name>.+)$/
|
||||
*
|
||||
* @param string $name Entity short name like AppBundle:Entity or FQCN.
|
||||
* @param TableNode $table Search parameters in table format.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deleteEntity($name, TableNode $table)
|
||||
{
|
||||
$params = [];
|
||||
|
||||
$tableData = $table->getTable();
|
||||
foreach ($tableData as $row) {
|
||||
$params[current($row)] = next($row);
|
||||
}
|
||||
|
||||
$this->dataBaseHelper->deleteEntity($name, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^(?:|[Dd]atabase )[Dd]on't has entity (?P<name>.+)$/
|
||||
* @Then /?[Hh]as entity (?P<name>.+)$?
|
||||
*
|
||||
* @param string $name Entity short name like AppBundle:Entity or FQCN.
|
||||
* @param TableNode $table Search parameters ikn table format.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function entityNotExists($name, TableNode $table)
|
||||
{
|
||||
$params = [];
|
||||
|
||||
$tableData = $table->getTable();
|
||||
foreach ($tableData as $row) {
|
||||
$params[current($row)] = next($row);
|
||||
}
|
||||
|
||||
$entities = $this->dataBaseHelper->getEntities($name, $params);
|
||||
|
||||
self::assertCount(
|
||||
0,
|
||||
$entities,
|
||||
"Entity {$name} with parameters " . PHP_EOL
|
||||
. json_encode($params, JSON_PRETTY_PRINT) . PHP_EOL .'exists!'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EntityManagerInterface $em A EntityManagerInterface instance.
|
||||
* @param array $fqcnList List of available fqcn's.
|
||||
*
|
||||
* @return array|mixed
|
||||
*/
|
||||
protected function processEntityMetadata(EntityManagerInterface $em, array $fqcnList)
|
||||
{
|
||||
$entities = [];
|
||||
|
||||
foreach ($fqcnList as $fqcn) {
|
||||
$reflection = new \ReflectionClass($fqcn);
|
||||
if ($reflection->implementsInterface(NormalizableEntityInterface::class)) {
|
||||
$name = \app\c\entityFqcnToShort($fqcn);
|
||||
|
||||
if ($reflection->isAbstract()) {
|
||||
$entities[$name] = new EntityMetadata($this->processAbstractMetadata($em, $reflection));
|
||||
} else {
|
||||
/** @var NormalizableEntityInterface $entity */
|
||||
$entity = $reflection->newInstanceWithoutConstructor();
|
||||
$entities[$name] = new EntityMetadata($entity->getMetadata());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $entities;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EntityManagerInterface $em A EntityManagerInterface
|
||||
* instance.
|
||||
* @param \ReflectionClass $reflection A ReflectionClass instance.
|
||||
*
|
||||
* @return Metadata
|
||||
*/
|
||||
protected function processAbstractMetadata(
|
||||
EntityManagerInterface $em,
|
||||
\ReflectionClass $reflection
|
||||
) {
|
||||
/** @var ClassMetadataInfo $doctrineMetadata */
|
||||
$doctrineMetadata = $em->getClassMetadata($reflection->getName());
|
||||
$map = $doctrineMetadata->discriminatorMap;
|
||||
|
||||
if (! is_array($map) || (count($map) === 0)) {
|
||||
// Parsed abstract class don't has discriminator column.
|
||||
$message = 'Abstract class without discriminator column not allowed';
|
||||
throw new \InvalidArgumentException($message);
|
||||
}
|
||||
|
||||
$metadata = new Metadata($reflection->getName());
|
||||
|
||||
$metadataList = array_map(function ($fqcn) use ($em) {
|
||||
$reflection = new \ReflectionClass($fqcn);
|
||||
if ($reflection->isAbstract()) {
|
||||
/** @var ClassMetadataInfo $doctrineMetadata */
|
||||
$doctrineMetadata = $em->getClassMetadata($fqcn);
|
||||
$map = $doctrineMetadata->discriminatorMap;
|
||||
return $this->processAbstractMetadata($em, $map);
|
||||
}
|
||||
|
||||
/** @var NormalizableEntityInterface $entity */
|
||||
$entity = $reflection->newInstanceWithoutConstructor();
|
||||
return $entity->getMetadata();
|
||||
}, $map);
|
||||
|
||||
return $metadata->admixList($metadataList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
namespace Common\Context;
|
||||
|
||||
use Behat\Gherkin\Node\TableNode;
|
||||
use Common\Util\Index\ExternalIndexConnection;
|
||||
use Common\Util\Index\InternalIndexConnection;
|
||||
use Common\Util\Index\InternalSourceConnection;
|
||||
use Common\Util\Index\TestIndexConnectionInterface;
|
||||
|
||||
/**
|
||||
* Class IndexContextTrait
|
||||
* Contains steps definitions for working with indices.
|
||||
*
|
||||
* @package Common\Context
|
||||
*/
|
||||
trait IndexContextTrait
|
||||
{
|
||||
|
||||
/**
|
||||
* @var ExternalIndexConnection
|
||||
*/
|
||||
protected $externalIndex;
|
||||
|
||||
/**
|
||||
* @var InternalIndexConnection
|
||||
*/
|
||||
protected $internalIndex;
|
||||
|
||||
/**
|
||||
* @var InternalSourceConnection
|
||||
*/
|
||||
protected $sourceIndex;
|
||||
|
||||
/**
|
||||
* @Transform /^([Ee]xternal|[Ii]nternal|[Ss]ource)$/
|
||||
*
|
||||
* @param string $index Index name.
|
||||
*
|
||||
* @return TestIndexConnectionInterface
|
||||
*/
|
||||
public function getConnectionByName($index)
|
||||
{
|
||||
$index = strtolower($index);
|
||||
|
||||
switch ($index) {
|
||||
case 'external':
|
||||
return $this->externalIndex;
|
||||
|
||||
case 'internal':
|
||||
return $this->internalIndex;
|
||||
|
||||
case 'source':
|
||||
return $this->sourceIndex;
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException("Unknown index '{$index}'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Json parameters should have only necessary fields. Over will be auto
|
||||
* generated.
|
||||
*
|
||||
* @Given /^(?:I add|[Hh]as) new document (?:in|to) (?P<connection>(external|internal|source)) index$/
|
||||
*
|
||||
* @param TestIndexConnectionInterface $index A TestIndexConnectionInterface
|
||||
* instance.
|
||||
* @param TableNode $table A TableNode instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function indexDocument(
|
||||
TestIndexConnectionInterface $index,
|
||||
TableNode $table
|
||||
) {
|
||||
/** @var AbstractContext $this */
|
||||
$document = $index->createDocument();
|
||||
|
||||
$params = [];
|
||||
$tableData = $table->getTable();
|
||||
foreach ($tableData as $row) {
|
||||
$params[current($row)] = $this->processor->process(next($row));
|
||||
}
|
||||
|
||||
foreach ($params as $name => $value) {
|
||||
$document[$name] = $value;
|
||||
}
|
||||
|
||||
$index->index($document);
|
||||
// Wait to insure that all fixtures was indexed.
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^(?P<connection>([Ee]xternal|[Ii]nternal|[Ss]ource)) index has (?P<count>\d+) document[s]?$/
|
||||
*
|
||||
* @param TestIndexConnectionInterface $connection A
|
||||
* TestIndexConnectionInterface
|
||||
* instance.
|
||||
* @param integer $count A expected documents
|
||||
* count.
|
||||
* @param TableNode $table A TableNode instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function hasDocuments(
|
||||
TestIndexConnectionInterface $connection,
|
||||
$count,
|
||||
TableNode $table
|
||||
) {
|
||||
/** @var AbstractContext $this */
|
||||
$tableData = $table->getTable();
|
||||
$factory = $connection->getFilterFactory();
|
||||
$filters = [];
|
||||
foreach ($tableData as $row) {
|
||||
$field = current($row);
|
||||
$type = next($row);
|
||||
$value = next($row);
|
||||
|
||||
if ($type === 'in') {
|
||||
$value = array_filter(array_map('trim', explode(',', $value)));
|
||||
}
|
||||
|
||||
$filters[] =
|
||||
$factory->{$type}($field, $this->processor->process($value));
|
||||
}
|
||||
|
||||
$results = $connection->createRequestBuilder()
|
||||
->setFilters($filters)
|
||||
->build()
|
||||
->execute();
|
||||
|
||||
self::assertCount((int) $count, $results);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user