Skip to content

Commit 1a35d1b

Browse files
Add support for operator chaining
1 parent 0990f0e commit 1a35d1b

10 files changed

Lines changed: 103 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,16 @@ The format is based on [Keep a Changelog], and this project adheres to
88

99
## 7.0.0 - T.B.D.
1010

11+
### Added
12+
13+
- Added support for operator chaining (e.g. `a > b > c`).
14+
1115
### Changed
1216

1317
- Changed the minimum required PHP version to 8.1.
1418
- Changed the signature of many functions to use PHP 8 union types.
1519
- Changed the `Relationship::DIR_*` to the `Direction` enum.
16-
- Remove `$insertParentheses` from all methods, and automatically insert them based on precedence.
20+
- Remove `$insertParentheses` from all methods, and automatically insert them based on precedence. - No longer insert parentheses when chaining comparison operators.
1721

1822
### Removed
1923

src/Expressions/Operators/ComparisonBinaryOperator.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,16 @@ public function __construct(AnyType $left, AnyType $right)
4545
{
4646
parent::__construct($left, $right);
4747
}
48+
49+
/**
50+
* @inheritDoc
51+
*/
52+
protected function shouldInsertParentheses(AnyType $expression): bool
53+
{
54+
if ($expression instanceof ComparisonBinaryOperator) {
55+
return false;
56+
}
57+
58+
return parent::shouldInsertParentheses($expression);
59+
}
4860
}

src/Expressions/Operators/Operator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ abstract protected function getPrecedence(): Precedence;
3838
/**
3939
* Whether to insert parentheses around the given expression, given the precedence of this operator.
4040
*/
41-
final protected function shouldInsertParentheses(AnyType $expression): bool
41+
protected function shouldInsertParentheses(AnyType $expression): bool
4242
{
4343
if (!$expression instanceof self) {
4444
return false;

tests/unit/Expressions/Operators/EqualityTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public function testToQuery(): void
2828

2929
$equality = new Equality($equality, $equality);
3030

31-
$this->assertSame("(10 = 15) = (10 = 15)", $equality->toQuery());
31+
$this->assertSame("10 = 15 = 10 = 15", $equality->toQuery());
3232
}
3333

3434
public function testInstanceOfBooleanType(): void

tests/unit/Expressions/Operators/GreaterThanOrEqualTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function testToQuery(): void
2727

2828
$greaterThanOrEqual = new GreaterThanOrEqual($greaterThanOrEqual, $greaterThanOrEqual);
2929

30-
$this->assertSame("(10 >= 15) >= (10 >= 15)", $greaterThanOrEqual->toQuery());
30+
$this->assertSame("10 >= 15 >= 10 >= 15", $greaterThanOrEqual->toQuery());
3131
}
3232

3333
public function testInstanceOfBooleanType(): void

tests/unit/Expressions/Operators/GreaterThanTest.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,18 @@ public function testToQuery(): void
2727

2828
$greaterThan = new GreaterThan($greaterThan, $greaterThan, false);
2929

30-
$this->assertSame("(10 > 15) > (10 > 15)", $greaterThan->toQuery());
30+
$this->assertSame("10 > 15 > 10 > 15", $greaterThan->toQuery());
31+
}
32+
33+
public function testChainedComparisons(): void
34+
{
35+
$a = new Integer(10);
36+
$b = new Integer(5);
37+
$c = new Integer(1);
38+
39+
$expr = $a->gt($b)->gt($c);
40+
41+
$this->assertSame("10 > 5 > 1", $expr->toQuery());
3142
}
3243

3344
public function testInstanceOfBooleanType(): void

tests/unit/Expressions/Operators/InequalityTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public function testToQuery(): void
2828

2929
$inequality = new Inequality($inequality, $inequality);
3030

31-
$this->assertSame("(v.a <> v.b) <> (v.a <> v.b)", $inequality->toQuery());
31+
$this->assertSame("v.a <> v.b <> v.a <> v.b", $inequality->toQuery());
3232
}
3333

3434
public function testInstanceOfBooleanType(): void

tests/unit/Expressions/Operators/LessThanOrEqualTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function testToQuery(): void
2727

2828
$lessThanOrEqual = new LessThanOrEqual($lessThanOrEqual, $lessThanOrEqual, false);
2929

30-
$this->assertSame("(10 <= 15) <= (10 <= 15)", $lessThanOrEqual->toQuery());
30+
$this->assertSame("10 <= 15 <= 10 <= 15", $lessThanOrEqual->toQuery());
3131
}
3232

3333
public function testInstanceOfBooleanType(): void

tests/unit/Expressions/Operators/LessThanTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function testToQuery(): void
2727

2828
$lessThan = new LessThan($lessThan, $lessThan, false);
2929

30-
$this->assertSame("(10 < 15) < (10 < 15)", $lessThan->toQuery());
30+
$this->assertSame("10 < 15 < 10 < 15", $lessThan->toQuery());
3131
}
3232

3333
public function testInstanceOfBooleanType(): void

tests/unit/Expressions/Operators/PrecedenceTest.php

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public function testComparisonWithAdditive(): void
106106
$this->assertSame('10 + 5 > 10 - 5', $expr->toQuery());
107107

108108
$expr = new Equality(new Inequality($num1, $num2), new Boolean(true));
109-
$this->assertSame('(10 <> 5) = true', $expr->toQuery());
109+
$this->assertSame('10 <> 5 = true', $expr->toQuery());
110110
}
111111

112112
public function testAdditiveWithMultiplicative(): void
@@ -380,7 +380,7 @@ public function testMixedUnaryBinaryNesting(): void
380380
new LessThan($num, $num),
381381
$num
382382
);
383-
$this->assertSame('(3.0 < 3.0) < 3.0', $expr->toQuery());
383+
$this->assertSame('3.0 < 3.0 < 3.0', $expr->toQuery());
384384

385385
$expr = new Multiplication(
386386
new UnaryMinus(new Exponentiation($num, $num)),
@@ -452,10 +452,10 @@ public function testAllSamePrecedenceCombinations(): void
452452
$this->assertSame('NOT (NOT true)', $expr->toQuery());
453453

454454
$expr = new Equality(new LessThan($num, $num), $true);
455-
$this->assertSame('(7.0 < 7.0) = true', $expr->toQuery());
455+
$this->assertSame('7.0 < 7.0 = true', $expr->toQuery());
456456

457457
$expr = new LessThanOrEqual(new GreaterThanOrEqual($num, $num), $num);
458-
$this->assertSame('(7.0 >= 7.0) <= 7.0', $expr->toQuery());
458+
$this->assertSame('7.0 >= 7.0 <= 7.0', $expr->toQuery());
459459

460460
$expr = new Addition(new Subtraction($num, $num), $num);
461461
$this->assertSame('(7.0 - 7.0) + 7.0', $expr->toQuery());
@@ -478,4 +478,68 @@ public function testAllSamePrecedenceCombinations(): void
478478
$expr = new Equality(new Contains($var, $var), new StartsWith($var, $var));
479479
$this->assertSame('y CONTAINS y = y STARTS WITH y', $expr->toQuery());
480480
}
481+
482+
public function testChainedComparison(): void
483+
{
484+
$a = new Integer(10);
485+
$b = new Integer(5);
486+
$c = new Integer(1);
487+
488+
$expr = new GreaterThan(new GreaterThan($a, $b), $c);
489+
$this->assertSame("10 > 5 > 1", $expr->toQuery());
490+
}
491+
492+
public function testChainedComparisonRhs(): void
493+
{
494+
$a = new Integer(10);
495+
$b = new Integer(5);
496+
$c = new Integer(1);
497+
498+
$expr = new GreaterThan($a, new GreaterThan($b, $c));
499+
$this->assertSame("10 > 5 > 1", $expr->toQuery());
500+
}
501+
502+
public function testChainedComparisonRhsCheck(): void
503+
{
504+
$a = new Integer(10);
505+
$b = new Integer(5);
506+
$c = new Integer(1);
507+
$d = new Integer(0);
508+
509+
$expr = new GreaterThan($a, new GreaterThan($b, new GreaterThan($c, $d)));
510+
$this->assertSame("10 > 5 > 1 > 0", $expr->toQuery());
511+
}
512+
513+
public function testChainedMixedComparisons(): void
514+
{
515+
$a = new Integer(10);
516+
$b = new Integer(5);
517+
$c = new Integer(5);
518+
519+
$expr = new GreaterThanOrEqual(new GreaterThan($a, $b), $c);
520+
$this->assertSame("10 > 5 >= 5", $expr->toQuery());
521+
}
522+
523+
public function testChainedInequality(): void
524+
{
525+
$a = new Integer(10);
526+
$b = new Integer(5);
527+
$c = new Integer(10);
528+
529+
$expr = new Inequality(new Inequality($a, $b), $c);
530+
$this->assertSame("10 <> 5 <> 10", $expr->toQuery());
531+
}
532+
533+
public function testChainedEquality(): void
534+
{
535+
$a = new Integer(1);
536+
$b = new Integer(1);
537+
$c = new Integer(1);
538+
539+
$expr = new Equality(new Equality($a, $b), $c);
540+
$this->assertSame("1 = 1 = 1", $expr->toQuery());
541+
542+
$expr = new Equality($a, new Equality($b, $c));
543+
$this->assertSame("1 = 1 = 1", $expr->toQuery());
544+
}
481545
}

0 commit comments

Comments
 (0)