Skip to content

Commit

Permalink
tests for #482 (#485)
Browse files Browse the repository at this point in the history
  • Loading branch information
gam6itko authored May 27, 2024
1 parent 3986b0d commit 3181f93
Show file tree
Hide file tree
Showing 12 changed files with 476 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/Select/AbstractLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ public function loadRelation(

$relation = $this->resolvePath($relation);
$alias ??= $options['alias'] ?? $relation;
unset($options['alias']);
if (!empty($options['as'])) {
// ??
$this->registerPath($options['as'], $alias);
Expand Down
7 changes: 0 additions & 7 deletions tests/ORM/Functional/Driver/Common/BaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,6 @@ public function setUp(): void
$this->logger->display();
}

$this->logger = new TestLogger();
$this->getDriver()->setLogger($this->logger);

if (self::$config['debug']) {
$this->logger->display();
}

$this->orm = new ORM(
(new Factory(
$this->dbal,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<?php

declare(strict_types=1);

namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue482;

use Cycle\ORM\Select;
use Cycle\ORM\Select\QueryBuilder;
use Cycle\ORM\Tests\Functional\Driver\Common\BaseTest;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\IntegrationTestTrait;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue482\Entity\Country;
use Cycle\ORM\Tests\Traits\TableTrait;

abstract class AbstractTestCase extends BaseTest
{
use IntegrationTestTrait;
use TableTrait;

public function setUp(): void
{
// Init DB
parent::setUp();
$this->makeTables();
$this->fillData();

$this->loadSchema(__DIR__ . '/schema.php');
}

public function testSelect(): void
{
$select = $this->orm->getRepository(Country::class)
->select()
->where('is_friendly', true)
// User wants to search everywhere
->with('translations', [
'as' => 'trans',
'method' => 4, //JoinableLoader::LEFT_JOIN
'alias' => 'trans1',
])
// User wants to search everywhere
->where(function (QueryBuilder $qb): void {
$searchProperties = ['code', 'name', 'trans.title'];
foreach ($searchProperties as $propertyName) {
$qb->orWhere($propertyName, 'LIKE', "%eng%");
}
})
// User want to sort by translation
->with('translations', [
'as' => 'transEn',
'method' => 4, //JoinableLoader::LEFT_JOIN
'where' => [
'locale_id' => 1,
],
'alias' => 'trans2',
])
->orderBy('transEn.title', 'asc')
->load('translations', [
'using' => 'trans',
]);

$this->assertExpectedSql($select);

$data = $select->fetchData();
$this->assertCount(3, $data);
$this->assertEquals(
[
'America on english',
'China on english',
'Russia on english',
],
\array_column(
\array_merge(
...\array_column($data, 'translations')
),
'title'
)
);

$all = $select->fetchAll();
$this->assertCount(3, $all);
$this->assertEquals(
[
'America on english',
'China on english',
'Russia on english',
],
\array_map(
static function (Country $c) {
self::assertCount(1, $c->translations);
return $c->translations[0]->title;
},
$all
)
);
}

private function makeTables(): void
{
// Make tables
$this->makeTable('country', [
'id' => 'primary', // autoincrement
'name' => 'string',
'code' => 'string',
'is_friendly' => 'bool',
]);

$this->makeTable('locale', [
'id' => 'primary',
'code' => 'string',
]);

$this->makeTable('translation', [
'id' => 'primary',
'title' => 'string',
'country_id' => 'int',
'locale_id' => 'int',
]);
$this->makeFK('translation', 'country_id', 'country', 'id', 'NO ACTION', 'NO ACTION');
$this->makeFK('translation', 'locale_id', 'locale', 'id', 'NO ACTION', 'NO ACTION');
}

private function fillData(): void
{
$this->getDatabase()->table('translation')->delete()->run();
$this->getDatabase()->table('country')->delete()->run();
$this->getDatabase()->table('locale')->delete()->run();

$en = 1;
$this->getDatabase()->table('locale')->insertMultiple(
['code'],
[
['en'],
],
);
$this->getDatabase()->table('country')->insertMultiple(
['name', 'code', 'is_friendly'],
[
['Russia', 'RUS', true],
['USA', 'USA', true],
['China', 'CHN', true],
],
);

$this->getDatabase()->table('translation')->insertMultiple(
['country_id', 'locale_id', 'title'],
[
[1, $en, 'Russia on english'],
[2, $en, 'America on english'],
[3, $en, 'China on english'],
],
);
}

abstract protected function assertExpectedSql(Select $select): void;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue482\Entity;

class Country
{
public ?int $id = null;
public string $name;
public string $code;
public bool $isFriendly = true;

/** @var iterable<Translation> */
public iterable $translations = [];

public function __construct(string $name, string $code)
{
$this->name = $name;
$this->code = $code;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue482\Entity;

class Locale
{
public ?int $id = null;
public string $code;

/** @var iterable<Translation> */
public iterable $translations = [];

public function __construct(string $code)
{
$this->code = $code;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue482\Entity;


class Translation
{
public ?int $id = null;
public Country $country;
public Locale $locale;
public string $title;

public function __construct(Country $country, Locale $locale, string $title)
{
$this->country = $country;
$this->locale = $locale;
$this->title = $title;
}
}
134 changes: 134 additions & 0 deletions tests/ORM/Functional/Driver/Common/Integration/Issue482/schema.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<?php

declare(strict_types=1);

use Cycle\ORM\Mapper\Mapper;
use Cycle\ORM\Relation;
use Cycle\ORM\SchemaInterface as Schema;
use Cycle\ORM\Select\Repository;
use Cycle\ORM\Select\Source;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue482\Entity\Translation;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue482\Entity\Country;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue482\Entity\Locale;

return [
'country' => [
Schema::ENTITY => Country::class,
Schema::SOURCE => Source::class,
Schema::DATABASE => 'default',
Schema::MAPPER => Mapper::class,
Schema::TABLE => 'country',
Schema::PRIMARY_KEY => ['id'],
Schema::FIND_BY_KEYS => ['id'],
Schema::COLUMNS => [
'id' => 'id',
'name' => 'name',
'code' => 'code',
'isFriendly' => 'is_friendly',
],
Schema::RELATIONS => [
'translations' => [
Relation::TYPE => Relation::HAS_MANY,
Relation::TARGET => 'translation',
Relation::COLLECTION_TYPE => 'array',
Relation::LOAD => Relation::LOAD_PROMISE,
Relation::SCHEMA => [
Relation::CASCADE => true,
Relation::NULLABLE => false,
Relation::WHERE => [],
Relation::ORDER_BY => [],
Relation::INNER_KEY => ['id'],
Relation::OUTER_KEY => 'country_id',
],
],
],
Schema::TYPECAST => [
'id' => 'int',
'name' => 'string',
'code' => 'string',
'isFriendly' => 'bool',
],
Schema::SCHEMA => [],
],
'translation' => [
Schema::ENTITY => Translation::class,
Schema::SOURCE => Source::class,
Schema::DATABASE => 'default',
Schema::TABLE => 'translation',
Schema::PRIMARY_KEY => ['id'],
Schema::FIND_BY_KEYS => ['id'],
Schema::COLUMNS => [
'id' => 'id',
'country_id' => 'country_id',
'locale_id' => 'locale_id',
'title' => 'title',
],
Schema::RELATIONS => [
'country' => [
Relation::TYPE => Relation::BELONGS_TO,
Relation::TARGET => 'country',
Relation::LOAD => Relation::LOAD_EAGER,
Relation::SCHEMA => [
Relation::CASCADE => true,
Relation::NULLABLE => false,
Relation::INNER_KEY => 'country_id',
Relation::OUTER_KEY => ['id'],
],
],
'locale' => [
Relation::TYPE => Relation::BELONGS_TO,
Relation::TARGET => 'locale',
Relation::LOAD => Relation::LOAD_PROMISE,
Relation::SCHEMA => [
Relation::CASCADE => true,
Relation::NULLABLE => false,
Relation::INNER_KEY => 'locale_id',
Relation::OUTER_KEY => ['id'],
],
],
],
Schema::TYPECAST => [
'id' => 'int',
'country_id' => 'int',
'locale_id' => 'int',
'title' => 'string',
],
Schema::SCHEMA => [],
],
'locale' => [
Schema::ENTITY => Locale::class,
Schema::MAPPER => Mapper::class,
Schema::SOURCE => Source::class,
Schema::REPOSITORY => Repository::class,
Schema::DATABASE => 'default',
Schema::TABLE => 'locale',
Schema::PRIMARY_KEY => ['id'],
Schema::FIND_BY_KEYS => ['id'],
Schema::COLUMNS => [
'id' => 'id',
'code' => 'code',
],
Schema::RELATIONS => [
'translations' => [
Relation::TYPE => Relation::HAS_MANY,
Relation::TARGET => 'translation',
Relation::COLLECTION_TYPE => 'array',
Relation::LOAD => Relation::LOAD_PROMISE,
Relation::SCHEMA => [
Relation::CASCADE => true,
Relation::NULLABLE => false,
Relation::WHERE => [],
Relation::ORDER_BY => [],
Relation::INNER_KEY => ['id'],
Relation::OUTER_KEY => 'locale_id',
],
],
],
Schema::SCOPE => null,
Schema::TYPECAST => [
'id' => 'int',
'code' => 'string',
],
Schema::SCHEMA => [],
],
];
Loading

0 comments on commit 3181f93

Please sign in to comment.