From c5150a4529f3d8aeac80c24fbbae3e26999581ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Fri, 13 Sep 2024 17:51:39 +0200 Subject: [PATCH] Fix types accepted by $round --- generator/config/expression/round.yaml | 20 ++++++++++---- src/Builder/Expression/FactoryTrait.php | 6 ++--- src/Builder/Expression/RoundOperator.php | 10 +++---- tests/Builder/Expression/Pipelines.php | 26 +++++++++++++++++++ .../Builder/Expression/RoundOperatorTest.php | 18 +++++++++++++ 5 files changed, 67 insertions(+), 13 deletions(-) diff --git a/generator/config/expression/round.yaml b/generator/config/expression/round.yaml index 52e6004a0..9bc6961c7 100644 --- a/generator/config/expression/round.yaml +++ b/generator/config/expression/round.yaml @@ -8,15 +8,12 @@ type: - resolvesToLong encode: array description: | - Rounds a number to to a whole integer or to a specified decimal place. + Rounds a number to a whole integer or to a specified decimal place. arguments: - name: number type: - - resolvesToInt - - resolvesToDouble - - resolvesToDecimal - - resolvesToLong + - resolvesToNumber description: | Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. $round returns an error if the expression resolves to a non-numeric data type. @@ -38,3 +35,16 @@ tests: $round: - '$value' - 1 + - + name: 'Round Average Rating' + pipeline: + - + $project: + roundedAverageRating: + $avg: + - + $round: + - + $avg: + - '$averageRating' + - 2 diff --git a/src/Builder/Expression/FactoryTrait.php b/src/Builder/Expression/FactoryTrait.php index 7828951ea..78f460fa0 100644 --- a/src/Builder/Expression/FactoryTrait.php +++ b/src/Builder/Expression/FactoryTrait.php @@ -1546,15 +1546,15 @@ public static function reverseArray(PackedArray|ResolvesToArray|BSONArray|array } /** - * Rounds a number to to a whole integer or to a specified decimal place. + * Rounds a number to a whole integer or to a specified decimal place. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/round/ - * @param Decimal128|Int64|ResolvesToDecimal|ResolvesToDouble|ResolvesToInt|ResolvesToLong|float|int $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. + * @param Decimal128|Int64|ResolvesToNumber|float|int $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. * $round returns an error if the expression resolves to a non-numeric data type. * @param Optional|ResolvesToInt|int $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. */ public static function round( - Decimal128|Int64|ResolvesToDecimal|ResolvesToDouble|ResolvesToInt|ResolvesToLong|float|int $number, + Decimal128|Int64|ResolvesToNumber|float|int $number, Optional|ResolvesToInt|int $place = Optional::Undefined, ): RoundOperator { return new RoundOperator($number, $place); diff --git a/src/Builder/Expression/RoundOperator.php b/src/Builder/Expression/RoundOperator.php index 7f3cad53e..323ae99eb 100644 --- a/src/Builder/Expression/RoundOperator.php +++ b/src/Builder/Expression/RoundOperator.php @@ -15,7 +15,7 @@ use MongoDB\Builder\Type\Optional; /** - * Rounds a number to to a whole integer or to a specified decimal place. + * Rounds a number to a whole integer or to a specified decimal place. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/round/ */ @@ -24,21 +24,21 @@ class RoundOperator implements ResolvesToInt, ResolvesToDouble, ResolvesToDecima public const ENCODE = Encode::Array; /** - * @var Decimal128|Int64|ResolvesToDecimal|ResolvesToDouble|ResolvesToInt|ResolvesToLong|float|int $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. + * @var Decimal128|Int64|ResolvesToNumber|float|int $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. * $round returns an error if the expression resolves to a non-numeric data type. */ - public readonly Decimal128|Int64|ResolvesToDecimal|ResolvesToDouble|ResolvesToInt|ResolvesToLong|float|int $number; + public readonly Decimal128|Int64|ResolvesToNumber|float|int $number; /** @var Optional|ResolvesToInt|int $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. */ public readonly Optional|ResolvesToInt|int $place; /** - * @param Decimal128|Int64|ResolvesToDecimal|ResolvesToDouble|ResolvesToInt|ResolvesToLong|float|int $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. + * @param Decimal128|Int64|ResolvesToNumber|float|int $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. * $round returns an error if the expression resolves to a non-numeric data type. * @param Optional|ResolvesToInt|int $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. */ public function __construct( - Decimal128|Int64|ResolvesToDecimal|ResolvesToDouble|ResolvesToInt|ResolvesToLong|float|int $number, + Decimal128|Int64|ResolvesToNumber|float|int $number, Optional|ResolvesToInt|int $place = Optional::Undefined, ) { $this->number = $number; diff --git a/tests/Builder/Expression/Pipelines.php b/tests/Builder/Expression/Pipelines.php index f5a4bcec1..f84d00984 100644 --- a/tests/Builder/Expression/Pipelines.php +++ b/tests/Builder/Expression/Pipelines.php @@ -4266,6 +4266,32 @@ enum Pipelines: string ] JSON; + /** Round Average Rating */ + case RoundRoundAverageRating = <<<'JSON' + [ + { + "$project": { + "roundedAverageRating": { + "$avg": [ + { + "$round": [ + { + "$avg": [ + "$averageRating" + ] + }, + { + "$numberInt": "2" + } + ] + } + ] + } + } + } + ] + JSON; + /** * Example * diff --git a/tests/Builder/Expression/RoundOperatorTest.php b/tests/Builder/Expression/RoundOperatorTest.php index accae5074..758668818 100644 --- a/tests/Builder/Expression/RoundOperatorTest.php +++ b/tests/Builder/Expression/RoundOperatorTest.php @@ -27,4 +27,22 @@ public function testExample(): void $this->assertSamePipeline(Pipelines::RoundExample, $pipeline); } + + public function testRoundAverageRating(): void + { + $pipeline = new Pipeline( + Stage::project( + roundedAverageRating: Expression::avg( + Expression::round( + Expression::avg( + Expression::doubleFieldPath('averageRating'), + ), + 2, + ), + ), + ), + ); + + $this->assertSamePipeline(Pipelines::RoundRoundAverageRating, $pipeline); + } }