Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert hardcoded strings to hintable fields in Contains{One, Many}Test #822

Merged
merged 3 commits into from
Jan 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/Model/ReferencesTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public function addRef(string $link, array $defaults): Reference
*
* @return Reference\HasOne
*/
public function hasOne(string $link, array $defaults = []): Reference
public function hasOne(string $link, array $defaults = []) //: Reference
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

otherwise autohinting (from phpdoc) does not work

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not add HasOne to Method Signature?

public function hasOne(string $link, array $defaults = []): Reference\HasOne

Copy link
Member Author

@mvorisek mvorisek Jan 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because it can be implemented by another class not based on this one

this is almost the no1 issue with Atk

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so you mean a child class could e.g. implement
public function hasOne(string $link, array $defaults = []): Some\Other\Reference
and that would fail if we set the parent signature to Reference\HasOne?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grml this is ugly. Do you really think adding Reference\HasOne would be an issue? I see return types in method signatures as an important part of good code. While this PR helps IDEs and phpstan and so on using comments, it weakens the method signatures which was something I liked about almost any of your PR: You created stricter, clearer method signatures.

{
return $this->_hasReference($this->_default_seed_hasOne, $link, $defaults); // @phpstan-ignore-line
}
Expand All @@ -90,7 +90,7 @@ public function hasOne(string $link, array $defaults = []): Reference
*
* @return Reference\HasMany
*/
public function hasMany(string $link, array $defaults = []): Reference
public function hasMany(string $link, array $defaults = []) //: Reference
{
return $this->_hasReference($this->_default_seed_hasMany, $link, $defaults); // @phpstan-ignore-line
}
Expand All @@ -100,7 +100,7 @@ public function hasMany(string $link, array $defaults = []): Reference
*
* @return Reference\ContainsOne
*/
public function containsOne(string $link, array $defaults = []): Reference
public function containsOne(string $link, array $defaults = []) //: Reference
{
return $this->_hasReference($this->_default_seed_containsOne, $link, $defaults); // @phpstan-ignore-line
}
Expand All @@ -110,7 +110,7 @@ public function containsOne(string $link, array $defaults = []): Reference
*
* @return Reference\ContainsMany
*/
public function containsMany(string $link, array $defaults = []): Reference
public function containsMany(string $link, array $defaults = []) //: Reference
{
return $this->_hasReference($this->_default_seed_containsMany, $link, $defaults); // @phpstan-ignore-line
}
Expand Down
3 changes: 0 additions & 3 deletions tests/BusinessModelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
use Atk4\Data\Tests\Model\Client;
use Atk4\Data\Tests\Model\User;

/**
* @coversDefaultClass \Atk4\Data\Model
*/
class BusinessModelTest extends AtkPhpunit\TestCase
{
/**
Expand Down
3 changes: 0 additions & 3 deletions tests/ConditionSqlTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
use Doctrine\DBAL\Platforms\SqlitePlatform;

/**
* @coversDefaultClass \Atk4\Data\Model
*/
class ConditionSqlTest extends \Atk4\Schema\PhpunitTestCase
{
public function testBasic()
Expand Down
3 changes: 0 additions & 3 deletions tests/ConditionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
use Atk4\Core\AtkPhpunit;
use Atk4\Data\Model;

/**
* @coversDefaultClass \Atk4\Data\Model
*/
class ConditionTest extends AtkPhpunit\TestCase
{
public function testException1()
Expand Down
24 changes: 24 additions & 0 deletions tests/ContainsMany/Discount.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Atk4\Data\Tests\ContainsMany;

use Atk4\Data\Model;

/**
* Each line can have multiple discounts.
*
* @property int $percent @Atk\Field()
* @property \DateTime $valid_till @Atk\Field()
*/
class Discount extends Model
{
protected function init(): void
{
parent::init();

$this->addField($this->fieldName()->percent, ['type' => 'integer', 'required' => true]);
$this->addField($this->fieldName()->valid_till, ['type' => 'datetime']);
}
}
54 changes: 54 additions & 0 deletions tests/ContainsMany/Invoice.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace Atk4\Data\Tests\ContainsMany;

use Atk4\Data\Model;

/**
* Invoice model.
*
* @property string $ref_no @Atk\Field()
* @property float $amount @Atk\Field()
* @property Line $lines @Atk\RefOne()
* @property string $total_gross @Atk\Field()
* @property float $discounts_total_sum @Atk\Field()
*/
class Invoice extends Model
{
public $table = 'invoice';

protected function init(): void
{
parent:: init();

$this->title_field = $this->fieldName()->ref_no;

$this->addField($this->fieldName()->ref_no, ['required' => true]);
$this->addField($this->fieldName()->amount, ['type' => 'money']);

// will contain many Lines
$this->containsMany($this->fieldName()->lines, ['model' => [Line::class], 'caption' => 'My Invoice Lines']);

// total_gross - calculated by php callback not by SQL expression
$this->addCalculatedField($this->fieldName()->total_gross, function (self $m) {
$total = 0;
foreach ($m->lines as $line) {
$total += $line->total_gross;
}

return $total;
});

// discounts_total_sum - calculated by php callback not by SQL expression
$this->addCalculatedField($this->fieldName()->discounts_total_sum, function (self $m) {
$total = 0;
foreach ($m->lines as $line) {
$total += $line->total_gross * $line->discounts_percent / 100;
}

return $total;
});
}
}
48 changes: 48 additions & 0 deletions tests/ContainsMany/Line.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

namespace Atk4\Data\Tests\ContainsMany;

use Atk4\Data\Model;

/**
* Invoice lines model.
*
* @property VatRate $vat_rate_id @Atk\RefOne()
* @property float $price @Atk\Field()
* @property float $qty @Atk\Field()
* @property \DateTime $add_date @Atk\Field()
* @property string $total_gross @Atk\Field()
* @property Discount $discounts @Atk\RefOne()
* @property float $discounts_percent @Atk\Field()
*/
class Line extends Model
{
protected function init(): void
{
parent::init();

$this->hasOne($this->fieldName()->vat_rate_id, ['model' => [VatRate::class]]);

$this->addField($this->fieldName()->price, ['type' => 'money', 'required' => true]);
$this->addField($this->fieldName()->qty, ['type' => 'float', 'required' => true]);
$this->addField($this->fieldName()->add_date, ['type' => 'datetime']);

$this->addExpression($this->fieldName()->total_gross, function (self $m) {
return $m->price * $m->qty * (1 + $m->vat_rate_id->rate / 100);
});

// each line can have multiple discounts and calculate total of these discounts
$this->containsMany($this->fieldName()->discounts, ['model' => [Discount::class]]);

$this->addCalculatedField($this->fieldName()->discounts_percent, function ($m) {
$total = 0;
foreach ($m->discounts as $d) {
$total += $d->percent;
}

return $total;
});
}
}
26 changes: 26 additions & 0 deletions tests/ContainsMany/VatRate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Atk4\Data\Tests\ContainsMany;

use Atk4\Data\Model;

/**
* VAT rate model.
*
* @property string $name @Atk\Field()
* @property int $rate @Atk\Field()
*/
class VatRate extends Model
{
public $table = 'vat_rate';

protected function init(): void
{
parent::init();

$this->addField($this->fieldName()->name);
$this->addField($this->fieldName()->rate, ['type' => 'integer']);
}
}
Loading