Skip to content
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* Changed sort(), sort_by(), max(), min(), max_by() and min_by() to order strings by code point.
* Fixed max_by() and min_by() to error on mixed-type keys instead of returning arbitrary elements.
* Fixed max() returning null or erroring when the first array element is falsy, e.g. max([0, 1]).
* Fixed 0.0 to be truthy in filters and logical operators, like every other number.
* Fixed the compiled runtime to apply JMESPath truthiness to || and &&.
* Fixed @(foo), foo[-] and oversized index literals to throw syntax errors.
* Fixed PHP warnings emitted while parsing certain invalid expressions.
Expand Down
2 changes: 1 addition & 1 deletion src/Utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Utils
public static function isTruthy($value)
{
if (!$value) {
return $value === 0 || $value === '0';
return $value === 0 || $value === 0.0 || $value === '0';
} elseif ($value instanceof \stdClass) {
return (bool) get_object_vars($value);
} else {
Expand Down
41 changes: 41 additions & 0 deletions tests/CompilerRuntimeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,47 @@ public function testRuntimesUseJmesPathTruthinessForEmptyObjects(): void
}
}

public function testRuntimesTreatFloatZeroAsTruthy(): void
{
$dir = $this->createTempDir();
$data = ['orders' => [['price' => 0.0], ['price' => 1.0], ['price' => 2.0]]];

try {
foreach ([new AstRuntime(), new CompilerRuntime($dir)] as $runtime) {
$this->assertSame([0.0, 1.0, 2.0], $runtime('orders[?price].price', $data));
$this->assertSame(0.0, $runtime('a || b', ['a' => 0.0, 'b' => 'fallback']));
$this->assertSame('x', $runtime('a && b', ['a' => 0.0, 'b' => 'x']));
$this->assertFalse($runtime('!a', ['a' => 0.0]));
}
} finally {
$this->removeTempDir($dir);
}
}

public function testRuntimesApplyJmesPathTruthinessInFilters(): void
{
$dir = $this->createTempDir();
$data = ['orders' => [
['price' => 0],
['price' => 0.0],
['price' => '0'],
['price' => '0.0'],
['price' => ''],
['price' => null],
['price' => false],
['price' => []],
['price' => new \stdClass()],
]];

try {
foreach ([new AstRuntime(), new CompilerRuntime($dir)] as $runtime) {
$this->assertSame([0, 0.0, '0', '0.0'], $runtime('orders[?price].price', $data));
}
} finally {
$this->removeTempDir($dir);
}
}

public function testRuntimesUseJsonSemanticEqualityForNumbers(): void
{
$dir = $this->createTempDir();
Expand Down
28 changes: 28 additions & 0 deletions tests/UtilsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,34 @@ public function testChecksIfObject($given, $result): void
$this->assertSame($result, Utils::isObject($given));
}

public static function isTruthyProvider(): array
{
return [
[0, true],
[0.0, true],
[-0.0, true],
['0', true],
['0.0', true],
[1, true],
['a', true],
[[0], true],
[(object) ['a' => 1], true],
[null, false],
[false, false],
['', false],
[[], false],
[new \stdClass(), false],
];
}

/**
* @dataProvider isTruthyProvider
*/
public function testChecksTruthiness($given, bool $result): void
{
$this->assertSame($result, Utils::isTruthy($given));
}

public function testHasStableSort(): void
{
$data = [new _TestStr(), new _TestStr(), 0, 10, 2];
Expand Down
Loading