Skip to content

Commit

Permalink
Add count aggregate rule. Update wording in error messages (#38)
Browse files Browse the repository at this point in the history
Introduced a new aggregate rule, ComboCount in Csv-Blueprint. This
counts the total number of rows in the CSV file. Also updated the
existing 'average' aggregate rules to convert array values to float
before calculation. The schema examples and README are updated to
demonstrate the new 'count' aggregate rule. A new test case for the
'count' rule has also been added.
  • Loading branch information
SmetDenis committed Mar 17, 2024
1 parent b0b7941 commit 97e7e73
Show file tree
Hide file tree
Showing 12 changed files with 176 additions and 17 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,13 @@ columns:
average_min: 1.123
average_max: 10.123

# Total(!) count of rows in the CSV file.
# Since any values are taken into account, it only makes sense to use these rules once in any column.
count: 5
count_not: 4
count_min: 1
count_max: 10

- name: "another_column"

- name: "third_column"
Expand Down
7 changes: 6 additions & 1 deletion schema-examples/full.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,12 @@
"average" : 5.123,
"average_not" : 4.123,
"average_min" : 1.123,
"average_max" : 10.123
"average_max" : 10.123,

"count" : 5,
"count_not" : 4,
"count_min" : 1,
"count_max" : 10
}
},

Expand Down
5 changes: 5 additions & 0 deletions schema-examples/full.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@
'average_not' => 4.123,
'average_min' => 1.123,
'average_max' => 10.123,

'count' => 5,
'count_not' => 4,
'count_min' => 1,
'count_max' => 10,
],
],
['name' => 'another_column'],
Expand Down
7 changes: 7 additions & 0 deletions schema-examples/full.yml
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,13 @@ columns:
average_min: 1.123
average_max: 10.123

# Total(!) count of rows in the CSV file.
# Since any values are taken into account, it only makes sense to use these rules once in any column.
count: 5
count_not: 4
count_min: 1
count_max: 10

- name: "another_column"

- name: "third_column"
Expand Down
9 changes: 7 additions & 2 deletions src/Rules/Aggregate/AbstarctAggregateRuleCombo.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ protected function validateComboAggregate(array $colValues, string $mode): ?stri
$verb = static::VERBS[$mode];
$name = static::NAME;

$actual = $this->getActual(\array_map('floatval', $colValues));
$actual = $this->getActual($colValues);
$expected = $this->getExpected();

if (!self::compare($expected, $actual, $mode)) {
return "The {$name} of the column is \"<c>{$actual}</c>\", " .
return "The {$name} in the column is \"<c>{$actual}</c>\", " .
"which is {$verb} than the {$prefix}expected \"<green>{$expected}</green>\"";
}

Expand All @@ -64,4 +64,9 @@ protected function getRuleCode(?string $mode = null): string
{
return 'ag:' . parent::getRuleCode($mode);
}

protected static function stringsToFloat(array $colValues): array
{
return \array_map('floatval', $colValues);
}
}
2 changes: 1 addition & 1 deletion src/Rules/Aggregate/ComboAverage.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ final class ComboAverage extends AbstarctAggregateRuleCombo
protected function getActualAggregate(array $colValues): float
{
try {
return Average::mean($colValues);
return Average::mean(self::stringsToFloat($colValues));
} catch (\Exception) {
return 0;
}
Expand Down
39 changes: 39 additions & 0 deletions src/Rules/Aggregate/ComboCount.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

/**
* JBZoo Toolbox - Csv-Blueprint.
*
* This file is part of the JBZoo Toolbox project.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @license MIT
* @copyright Copyright (C) JBZoo.com, All rights reserved.
* @see https://github.com/JBZoo/Csv-Blueprint
*/

declare(strict_types=1);

namespace JBZoo\CsvBlueprint\Rules\Aggregate;

final class ComboCount extends AbstarctAggregateRuleCombo
{
protected const NAME = 'count of rows';

protected const HELP_TOP = [
'Total(!) count of rows in the CSV file.',
'Since any values are taken into account, it only makes sense to use these rules once in any column.',
];

protected const HELP_OPTIONS = [
self::EQ => ['5', ''],
self::NOT => ['4', ''],
self::MIN => ['1', ''],
self::MAX => ['10', ''],
];

protected function getActualAggregate(array $colValues): float
{
return \count($colValues);
}
}
4 changes: 2 additions & 2 deletions src/Rules/Aggregate/ComboSum.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@

final class ComboSum extends AbstarctAggregateRuleCombo
{
protected const NAME = 'sum';
protected const NAME = 'sum of numbers';

protected const HELP_TOP = ['Sum of the numbers in the column. Example: [1, 2, 3] => 6.'];

protected function getActualAggregate(array $colValues): float
{
return \array_sum($colValues);
return \array_sum(self::stringsToFloat($colValues));
}
}
8 changes: 4 additions & 4 deletions tests/Rules/Aggregate/ComboAverageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function testEqual(): void
isSame('', $rule->test(['1', '2', '3']));

isSame(
'The average of the column is "2.625", which is not equal than the expected "2"',
'The average in the column is "2.625", which is not equal than the expected "2"',
$rule->test(['1', '2', '3', '4.5']),
);
}
Expand All @@ -45,7 +45,7 @@ public function testNotEqual(): void
isSame('', $rule->test(['1', '2', '3', '4.5']));

isSame(
'The average of the column is "2", which is equal than the not expected "2"',
'The average in the column is "2", which is equal than the not expected "2"',
$rule->test(['1', '2', '3']),
);
}
Expand All @@ -57,7 +57,7 @@ public function testMin(): void
isSame('', $rule->test(['1', '2', '3']));

isSame(
'The average of the column is "1.5", which is less than the expected "1.999"',
'The average in the column is "1.5", which is less than the expected "1.999"',
$rule->test(['1', '2']),
);
}
Expand All @@ -69,7 +69,7 @@ public function testMax(): void
isSame('', $rule->test(['1', '2', '3']));

isSame(
'The average of the column is "2.625", which is greater than the expected "2"',
'The average in the column is "2.625", which is greater than the expected "2"',
$rule->test(['1', '2', '3', '4.5']),
);
}
Expand Down
91 changes: 91 additions & 0 deletions tests/Rules/Aggregate/ComboCountTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

/**
* JBZoo Toolbox - Csv-Blueprint.
*
* This file is part of the JBZoo Toolbox project.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @license MIT
* @copyright Copyright (C) JBZoo.com, All rights reserved.
* @see https://github.com/JBZoo/Csv-Blueprint
*/

declare(strict_types=1);

namespace JBZoo\PHPUnit\Rules\Aggregate;

use JBZoo\CsvBlueprint\Rules\AbstarctRule as Combo;
use JBZoo\CsvBlueprint\Rules\Aggregate\ComboCount;
use JBZoo\PHPUnit\Rules\AbstractAggregateRuleCombo;

use function JBZoo\PHPUnit\isSame;

class ComboCountTest extends AbstractAggregateRuleCombo
{
protected string $ruleClass = ComboCount::class;

public function testEqual(): void
{
$rule = $this->create(3, Combo::EQ);

isSame('', $rule->test(['1', '2', '3']));

isSame(
'The count of rows in the column is "4", which is not equal than the expected "3"',
$rule->test(['1', '2', '3', '4.5']),
);
}

public function testNotEqual(): void
{
$rule = $this->create(3, Combo::NOT);

isSame('', $rule->test(['1', '2', '3', '4.5']));

isSame(
'The count of rows in the column is "3", which is equal than the not expected "3"',
$rule->test(['1', '2', '3']),
);
}

public function testMin(): void
{
$rule = $this->create(3, Combo::MIN);

isSame('', $rule->test(['1', '2', '3']));

isSame(
'The count of rows in the column is "2", which is less than the expected "3"',
$rule->test(['1', '2']),
);
}

public function testMax(): void
{
$rule = $this->create(3, Combo::MAX);

isSame('', $rule->test(['1', '2', '3']));

isSame(
'The count of rows in the column is "4", which is greater than the expected "3"',
$rule->test(['1', '2', '3', '4.5']),
);
}

public function testInvalidOption(): void
{
$this->expectExceptionMessage(
'Invalid option "[1, 2]" for the "ag:count_max" rule. It should be integer/float.',
);
$rule = $this->create([1, 2], Combo::MAX);
$rule->validate(['1', '2', '3']);
}

public function testInvalidParsing(): void
{
$rule = $this->create(0, Combo::EQ);
isSame('', $rule->test([]));
}
}
8 changes: 4 additions & 4 deletions tests/Rules/Aggregate/ComboSumTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function testEqual(): void
isSame('', $rule->test(['1', '2', '3']));

isSame(
'The sum of the column is "10.5", which is not equal than the expected "6"',
'The sum of numbers in the column is "10.5", which is not equal than the expected "6"',
$rule->test(['1', '2', '3', '4.5']),
);
}
Expand All @@ -45,7 +45,7 @@ public function testNotEqual(): void
isSame('', $rule->test(['1', '2', '3', '4.5']));

isSame(
'The sum of the column is "6", which is equal than the not expected "6"',
'The sum of numbers in the column is "6", which is equal than the not expected "6"',
$rule->test(['1', '2', '3']),
);
}
Expand All @@ -57,7 +57,7 @@ public function testMin(): void
isSame('', $rule->test(['1', '2', '3']));

isSame(
'The sum of the column is "3", which is less than the expected "6"',
'The sum of numbers in the column is "3", which is less than the expected "6"',
$rule->test(['1', '2']),
);
}
Expand All @@ -69,7 +69,7 @@ public function testMax(): void
isSame('', $rule->test(['1', '2', '3']));

isSame(
'The sum of the column is "10.5", which is greater than the expected "6"',
'The sum of numbers in the column is "10.5", which is greater than the expected "6"',
$rule->test(['1', '2', '3', '4.5']),
);
}
Expand Down
6 changes: 3 additions & 3 deletions tests/Validators/CsvValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ public function testAggregateRuleCombo(): void

$csv = new CsvFile(Tools::DEMO_CSV, Tools::getAggregateRule('Float', 'sum', 20));
isSame(
'"ag:sum" at line 1, column "0:Float". The sum of the column is "4691.3235", ' .
'which is not equal than the expected "20".' . "\n",
\strip_tags((string)$csv->validate()),
'"ag:sum" at line <red>1</red>, column "0:Float". The sum of numbers in the column is ' .
'"<c>4691.3235</c>", which is not equal than the expected "<green>20</green>".' . "\n",
(string)$csv->validate(),
);
}

Expand Down

0 comments on commit 97e7e73

Please sign in to comment.