From 9551c5b56502dd407d582b38495edfc6f91bcf74 Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Fri, 8 Apr 2022 15:05:22 +0200 Subject: [PATCH 1/3] Require hhvm 4.128 and support autoloading with ext_watchman The hsl is always built-in. ext_watchman and HH\Facts are always available. varray eq vec and darray eq dict is always true. All legacy arrays have been replaced with Hack arrays. --- .gitattributes | 1 + .github/workflows/build-and-test.yml | 2 +- .gitignore | 1 + .hhvmconfig.hdf | 3 + composer.json | 3 +- hh_autoload.json | 3 +- tests/ExpectObjTest.hack | 120 +++++++++++++-------------- 7 files changed, 69 insertions(+), 64 deletions(-) create mode 100644 .hhvmconfig.hdf diff --git a/.gitattributes b/.gitattributes index 336bc07..1172819 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ tests/ export-ignore .hhconfig export-ignore +.hhvmconfig.hdf export-ignore *.hack linguist-language=Hack diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index d39f70b..1d2c578 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -13,7 +13,7 @@ jobs: matrix: os: [ ubuntu ] hhvm: - - '4.102' + - '4.128' - latest - nightly runs-on: ${{matrix.os}}-latest diff --git a/.gitignore b/.gitignore index 38dcf5b..12f1006 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ vendor/ *.orig composer.lock .*.hhast.*cache +.var/ diff --git a/.hhvmconfig.hdf b/.hhvmconfig.hdf new file mode 100644 index 0000000..e8800ca --- /dev/null +++ b/.hhvmconfig.hdf @@ -0,0 +1,3 @@ +Autoload { + Query = {"expression": ["allof", ["type", "f"], ["suffix", ["anyof", "hack", "php"]], ["not",["anyof",["dirname",".var"],["dirname",".git"]]]]} +} \ No newline at end of file diff --git a/composer.json b/composer.json index 447a586..5ef8a26 100644 --- a/composer.json +++ b/composer.json @@ -3,9 +3,8 @@ "description": "Unit test helpers for Facebook projects", "license": "MIT", "require": { - "hhvm": "^4.102", + "hhvm": "^4.128", "hhvm/hacktest": "^1.0|^2.0", - "hhvm/hsl": "^4.0", "facebook/difflib": "^1.3.0" }, "require-dev": { diff --git a/hh_autoload.json b/hh_autoload.json index f4f0b89..e6b432f 100644 --- a/hh_autoload.json +++ b/hh_autoload.json @@ -5,5 +5,6 @@ "devRoots": [ "tests" ], - "devFailureHandler": "Facebook\\AutoloadMap\\HHClientFallbackHandler" + "devFailureHandler": "Facebook\\AutoloadMap\\HHClientFallbackHandler", + "useFactsIfAvailable": true } diff --git a/tests/ExpectObjTest.hack b/tests/ExpectObjTest.hack index 0a18c4a..65e17e6 100644 --- a/tests/ExpectObjTest.hack +++ b/tests/ExpectObjTest.hack @@ -26,7 +26,7 @@ final class ExpectObjTest extends HackTest { expect(1)->toBePHPEqual(1, 'custom msg'); expect(true)->toNotBePHPEqual(false); - expect(varray[1, 2, 3])->toBePHPEqual(varray[1, 2, 3]); + expect(vec[1, 2, 3])->toBePHPEqual(vec[1, 2, 3]); expect(1)->toBeGreaterThan(0); expect(1)->toBeGreaterThanOrEqualTo(0); @@ -55,8 +55,8 @@ final class ExpectObjTest extends HackTest { // vec[] is keyed by int type. expect(vec[])->toBeType('KeyedContainer'); expect(dict[])->toBeType('KeyedContainer'); - expect(varray[1, 2, 3])->toContain(2); - expect(varray[1, 2, 3])->toNotContain(7); + expect(vec[1, 2, 3])->toContain(2); + expect(vec[1, 2, 3])->toNotContain(7); expect('foo')->toContainSubstring('foo'); expect('foo')->toContainSubstring('o'); expect('foo')->toNotContainSubstring('a'); @@ -85,13 +85,13 @@ final class ExpectObjTest extends HackTest { expect(dict[])->toNotContainKey('x'); // subsets are OK - expect(darray['k1' => 'v1', 'k2' => 'v2']) - ->toInclude(darray['k1' => 'v1']); + expect(dict['k1' => 'v1', 'k2' => 'v2']) + ->toInclude(dict['k1' => 'v1']); expect(dict['k1' => 'v1', 'k2' => 'v2'])->toInclude(dict['k1' => 'v1']); // same set is OK, even if order is different - expect(darray['k2' => 'v2', 'k1' => 'v1']) - ->toInclude(darray['k1' => 'v1', 'k2' => 'v2']); + expect(dict['k2' => 'v2', 'k1' => 'v1']) + ->toInclude(dict['k1' => 'v1', 'k2' => 'v2']); expect(dict['k1' => 'v1', 'k2' => 'v2']) ->toInclude(dict['k1' => 'v1', 'k2' => 'v2']); @@ -100,7 +100,7 @@ final class ExpectObjTest extends HackTest { expect('haystack')->toNotMatchRegExp('/needle/'); // sorting - expect(varray[1, 2, 3])->toBeSortedBy(function(int $prev, int $curr): bool { + expect(vec[1, 2, 3])->toBeSortedBy(function(int $prev, int $curr): bool { if ($prev <= $curr) { return true; } @@ -117,66 +117,66 @@ final class ExpectObjTest extends HackTest { * [method_name, test value, expected value (if necessary)] * */ - public function provideFailureCases(): vec> { + public function provideFailureCases(): vec> { $o = new \stdClass(); return vec[ - varray['toBePHPEqual', false, true], - varray['toNotBePHPEqual', false, false], - varray['toBeGreaterThan', 1, 1], - varray['toBeLessThan', 1, 1], - varray['toBeGreaterThanOrEqualTo', 1, 2], - varray['toBeLessThanOrEqualTo', 2, 1], - varray['toBeSame', $o, new \stdClass()], - varray['toNotBeSame', $o, $o], - varray['toBeTrue', false], - varray['toBeFalse', true], - varray['toBeNull', false], - varray['toNotBeNull', null], - varray['toBeEmpty', 1], - varray['toNotBeEmpty', 0], - varray['toNotBeInstanceOf', $o, 'stdClass'], - varray['toBeType', 'a', 'int'], - varray['toNotBeType', 1, 'int'], - varray['toContain', varray[1, 2, 3], 7], - varray['toNotContain', varray[1, 2, 3], 2], - varray['toAlmostEqual', null, 0.0], + vec['toBePHPEqual', false, true], + vec['toNotBePHPEqual', false, false], + vec['toBeGreaterThan', 1, 1], + vec['toBeLessThan', 1, 1], + vec['toBeGreaterThanOrEqualTo', 1, 2], + vec['toBeLessThanOrEqualTo', 2, 1], + vec['toBeSame', $o, new \stdClass()], + vec['toNotBeSame', $o, $o], + vec['toBeTrue', false], + vec['toBeFalse', true], + vec['toBeNull', false], + vec['toNotBeNull', null], + vec['toBeEmpty', 1], + vec['toNotBeEmpty', 0], + vec['toNotBeInstanceOf', $o, 'stdClass'], + vec['toBeType', 'a', 'int'], + vec['toNotBeType', 1, 'int'], + vec['toContain', vec[1, 2, 3], 7], + vec['toNotContain', vec[1, 2, 3], 2], + vec['toAlmostEqual', null, 0.0], // hack arrays - varray['toContain', keyset[1, 2, 3], 7], - varray['toNotContain', keyset[1, 2, 3], 2], - varray['toContain', keyset[], 2], + vec['toContain', keyset[1, 2, 3], 7], + vec['toNotContain', keyset[1, 2, 3], 2], + vec['toContain', keyset[], 2], - varray['toContain', vec[1, 2, 3], 7], - varray['toNotContain', vec[1, 2, 3], 2], - varray['toContain', vec[], 2], + vec['toContain', vec[1, 2, 3], 7], + vec['toNotContain', vec[1, 2, 3], 2], + vec['toContain', vec[], 2], - varray['toContain', dict['x' => 1, 'y' => 2, 'z' => 3], 7], - varray['toNotContain', dict['x' => 1, 'y' => 2, 'z' => 3], 2], - varray['toContain', dict[], 2], + vec['toContain', dict['x' => 1, 'y' => 2, 'z' => 3], 7], + vec['toNotContain', dict['x' => 1, 'y' => 2, 'z' => 3], 2], + vec['toContain', dict[], 2], - varray['toContainKey', dict['x' => 1, 'y' => 2, 'z' => 3], '1'], - varray['toNotContainKey', dict['x' => 1, 'y' => 2, 'z' => 3], 'y'], - varray['toContainKey', dict[], 'a'], + vec['toContainKey', dict['x' => 1, 'y' => 2, 'z' => 3], '1'], + vec['toNotContainKey', dict['x' => 1, 'y' => 2, 'z' => 3], 'y'], + vec['toContainKey', dict[], 'a'], // superset is not OK - varray[ + vec[ 'toInclude', - darray['k1' => 'v1'], - darray['k1' => 'v1', 'k2' => 'v2'], + dict['k1' => 'v1'], + dict['k1' => 'v1', 'k2' => 'v2'], ], - varray[ + vec[ 'toInclude', dict['k1' => 'v1'], dict['k1' => 'v1', 'k2' => 'v2'], ], // values have to equal - varray[ + vec[ 'toInclude', - darray['k1' => 'v1', 'k2' => 'v2'], - darray['k1' => 'v2'], + dict['k1' => 'v1', 'k2' => 'v2'], + dict['k1' => 'v2'], ], - varray[ + vec[ 'toInclude', dict['k1' => 'v1', 'k2' => 'v2'], dict['k1' => 'v2'], @@ -198,7 +198,7 @@ final class ExpectObjTest extends HackTest { ExpectationFailedException::class, ); } else { - expect(() ==> $rm->invokeArgs($obj, varray[$expected])) + expect(() ==> $rm->invokeArgs($obj, vec[$expected])) ->toThrow(ExpectationFailedException::class); } } @@ -213,10 +213,10 @@ final class ExpectObjTest extends HackTest { $rm = new \ReflectionMethod($obj, $func); if ($expected === self::EMPTY_VALUE) { - expect(() ==> $rm->invokeArgs($obj, varray['custom msg'])) + expect(() ==> $rm->invokeArgs($obj, vec['custom msg'])) ->toThrow(ExpectationFailedException::class, 'custom msg'); } else { - expect(() ==> $rm->invokeArgs($obj, varray[$expected, 'custom msg'])) + expect(() ==> $rm->invokeArgs($obj, vec[$expected, 'custom msg'])) ->toThrow(ExpectationFailedException::class, 'custom msg'); ; } @@ -224,14 +224,14 @@ final class ExpectObjTest extends HackTest { // And with funky sprintfification if ($expected === self::EMPTY_VALUE) { expect( - () ==> $rm->invokeArgs($obj, varray['custom %s %d %f', 'msg', 1, 2.1]), + () ==> $rm->invokeArgs($obj, vec['custom %s %d %f', 'msg', 1, 2.1]), ) ->toThrow(ExpectationFailedException::class, 'custom msg 1 2.1'); } else { expect( () ==> $rm->invokeArgs( $obj, - varray[$expected, 'custom %s %d %f', 'msg', 1, 2.1], + vec[$expected, 'custom %s %d %f', 'msg', 1, 2.1], ), )->toThrow(ExpectationFailedException::class, 'custom msg 1 2.1'); } @@ -304,13 +304,13 @@ final class ExpectObjTest extends HackTest { expect( () ==> { expect( - darray[ + dict[ 'a' => 5, 'b' => 4, 'c' => 3, ], )->toHaveSameShapeAs( - darray[ + dict[ 'b' => 4, 'c' => 3, 'a' => 5, @@ -343,13 +343,13 @@ final class ExpectObjTest extends HackTest { expect( () ==> { expect(Set {1, 2})->toHaveSameContentAs(Vector {2, 1}); - expect(varray[3])->toHaveSameContentAs(Map {1 => 3}); + expect(vec[3])->toHaveSameContentAs(Map {1 => 3}); }, )->notToThrow(); } public function testToHaveSameContentAsFailure(): void { - expect(() ==> expect(varray[1, 2])->toHaveSameContentAs(Vector {1})) + expect(() ==> expect(vec[1, 2])->toHaveSameContentAs(Vector {1})) ->toThrow(ExpectationFailedException::class); } @@ -393,13 +393,13 @@ final class ExpectObjTest extends HackTest { expect( () ==> { expect( - darray[ + dict[ 'a' => 5, 'b' => 4, 'c' => 3, ], )->toHaveSameShapeAs( - darray[ + dict[ 'a' => 4, 'b' => 3, 'c' => 5, From cd34fac69fad03b3c9bdcc37e82a9c887b5c9b35 Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Sat, 9 Apr 2022 00:18:32 +0200 Subject: [PATCH 2/3] Fix lints --- src/Constraint/IsType.hack | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Constraint/IsType.hack b/src/Constraint/IsType.hack index 7a18761..df4f2a8 100644 --- a/src/Constraint/IsType.hack +++ b/src/Constraint/IsType.hack @@ -17,7 +17,7 @@ class IsType { public static function getTypes(): ImmMap { return ImmMap { - 'numeric' => ($x ==> \is_numeric($x)), + 'numeric' => (\is_numeric<>), 'integer' => ($x ==> ($x is int)), 'int' => ($x ==> ($x is int)), 'double' => ($x ==> ($x is float)), @@ -27,8 +27,8 @@ class IsType { 'boolean' => ($x ==> ($x is bool)), 'bool' => ($x ==> ($x is bool)), 'null' => ($x ==> $x === null), - 'array' => ($x ==> \HH\is_php_array($x)), - 'object' => ($x ==> \is_object($x)), + 'array' => (\HH\is_php_array<>), + 'object' => (\is_object<>), 'resource' => ( $x ==> { if ($x is resource) { @@ -42,9 +42,9 @@ class IsType { return $is_resource; } ), - 'scalar' => ($x ==> \is_scalar($x)), - 'callable' => ($x ==> \is_callable($x)), - 'iterable' => ($x ==> is_iterable($x)), + 'scalar' => (\is_scalar<>), + 'callable' => (\is_callable<>), + 'iterable' => (is_iterable<>), 'vec' => ($x ==> ($x is vec<_>)), 'dict' => ($x ==> ($x is dict<_, _>)), 'keyset' => ($x ==> ($x is keyset<_>)), From 1cae924b447c2e9ae19ce14150eea6a438b754d8 Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Thu, 21 Apr 2022 19:08:13 +0200 Subject: [PATCH 3/3] Allow hhvm-autoload plugin --- composer.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/composer.json b/composer.json index 5ef8a26..41111c9 100644 --- a/composer.json +++ b/composer.json @@ -10,5 +10,10 @@ "require-dev": { "hhvm/hhvm-autoload": "^2.0|^3.0", "hhvm/hhast": "^4.0" + }, + "config": { + "allow-plugins": { + "hhvm/hhvm-autoload": true + } } }