From da5ec248b368281d7d5fa0befa4964f083994817 Mon Sep 17 00:00:00 2001 From: Vardan Date: Wed, 18 Oct 2023 19:00:36 +0300 Subject: [PATCH 1/8] add runnable parameters convertor Signed-off-by: Vardan --- .DS_Store | Bin 0 -> 8196 bytes src/.DS_Store | Bin 0 -> 6148 bytes src/Context/ApiContext.php | 44 +++++++++ tests/.DS_Store | Bin 0 -> 6148 bytes tests/Unit/.DS_Store | Bin 0 -> 6148 bytes tests/Unit/Context/ApiContextTest.php | 129 ++++++++++++++++++++++++++ 6 files changed, 173 insertions(+) create mode 100644 .DS_Store create mode 100644 src/.DS_Store create mode 100644 tests/.DS_Store create mode 100644 tests/Unit/.DS_Store create mode 100644 tests/Unit/Context/ApiContextTest.php diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..2e452ef242973d1ba0545b898c87ae2e01205510 GIT binary patch literal 8196 zcmeI1-D(p-7>2(|(q==jrlOD&VZqZ9W0gYjB<4pcXoPO6h)T?6gI&Ab3A;%nlt7O4 z9=ruly%O)mBYo$mWp|sP2Stj`z|1?l`@OR>&rY)aQX*o_sdta4N<nN28zpQumI=`q?C)D%O&5HJJ`0YktLxQYbu&KAX5@!nTgO=}1k0{<< z3Tq4otVoa4iFl}Wz#bC;g>$V7oHnc93DmyV{ zC#LVrbcVv@-QlxkII)IO(;5PXz(oQgcfTR?^)_`<`Foezbbu>8s?jlddjTK10e2BE zK4OnhYd>W{kLVf=i6d@|Hl`6paD70JQdPIf!vye{Y6#SHgpkD8cm z589Tw>pXZ?Zu!XM50m76UdP6mEBilo8!MhJQH(hog8Yw~I6#nS7j3s%W0^()oW z)9u}zE&D;eKHsuWcem^4-`|HDFcb|DDyp|6lfP&3J}@A#jBVutM8uH!-2JKXbBk6S=mH`VLhT5w}n(Eofvq i4wdOR^!y)&=-UVto`%+iQk+3CKLkh&rZEKmDuG`!nm(Wa literal 0 HcmV?d00001 diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..e698526d20ba947febb70d63297b88e5cedcb076 GIT binary patch literal 6148 zcmeHKO>fgc5S?uUcBqgd0a7_2S>jq1Q&6Rfi|d9%uQh@Lpb*CvF_>M;9}QI$$>;K8 zxbjQ*FPz}*M^WMc2M!2DJJQUX-JQ42KE=CUB4S~aJR}+rkqejDyMgcvljG9YY|HdG zK&IxX>6i-2=!C>twe7G9SOxw!1?0PXmqJQuN@H4ne>qwyeMAhYAx;V9Xz%0wo>Fm| zi%Fb|7;L$99K-j&D?>))s2$+v44vxFf3A*aRbl4-5*K+^)xQ6gZEg3iU3Xl^-Em(> zQ!$I`aotqmxO^#F&xFY1t9%?k&(hgwaQj5?dYtjJRD>)^QS$0V#uG6MMZ=RyaU(t8 z_TBzyusfe093Ad?k9~i!=gp4}eB_S~7mL1o=l+8yXQTJ|2QDtvDv4p&Q+Ctf6?{U{ z(cnBPc`o={j7Zik8bZwiE|ryWLKk!je23Nqs%O|k`Kog49+=BI_vsAP6)GDl!9w0) z$X~L|a414mN#~d!^_}W(ooY0#ZL9+3-|Oyd>XrooYDzK`+wr&pO`Tz9y_y1LrZCM4Z0vn|O>kXq}h$We`b!~C-to7h;;L>DW nt5H!9%yFy|c@*!$m0`@22{16&YD5preh4TTY_JOaQw4qiW5btx literal 0 HcmV?d00001 diff --git a/src/Context/ApiContext.php b/src/Context/ApiContext.php index 02a77e9..8383609 100644 --- a/src/Context/ApiContext.php +++ b/src/Context/ApiContext.php @@ -114,6 +114,7 @@ public function theRequestContainsParams(PyStringNode $params): void ); $newRequestParams = (array) json_decode($processedParams, true, 512, JSON_THROW_ON_ERROR); + $newRequestParams = $this->convertRunnableCodeParams($newRequestParams); $this->requestParams = array_merge($this->requestParams, $newRequestParams); $this->savedValues = array_merge($this->savedValues, $newRequestParams); } @@ -299,6 +300,49 @@ protected function compareStructureResponse(string $variableFields, PyStringNode } } + /** + * @param array $requestParams + * + * @When I have :requestParams with runnable values (placed in <>) + * + * @Then :requestParams should be converted with executing runnable code + */ + public function convertRunnableCodeParams(array $requestParams): array + { + foreach ($requestParams as $key => $value) { + if (is_array($value)) { + $requestParams[$key] = $this->convertRunnableCodeParams($value); + continue; + } + + if (!is_string($value)) { + continue; + } + + $pregMatchValue = preg_match('/^<.*>$/', $value); + + if ($pregMatchValue === 0 || $pregMatchValue === false) { + continue; + } + + $command = substr($value, 1, -1); + + $resultValue = eval('return ' . $command . ';'); + + if (is_null($resultValue)) { + throw new \Error( + sprintf( + 'Running code: \'%s\' - should not return the null', + $command + ) + ); + } + + $requestParams[$key] = $resultValue; + } + return $requestParams; + } + private function resetRequestOptions(): void { $this->headers = []; diff --git a/tests/.DS_Store b/tests/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..e5c191243ac704cce1498be11a06c0016ff4218c GIT binary patch literal 6148 zcmeHKO-~y!5FLlKY=n>^wUs!o#1+97DkRj)HVp@^U0M!MrP*xME^O^6*)&2?q&>rr z;mR-R-+?!_1EML{Dyn9r@f(k4yz6JnA4H^D`8&cqp2OFpl5#Snj|$UE3zH&)m&*s}_MH`2 zM0NU%jGW3p;%=UcODCg&@9#Dp6#1x(qTi~vQh)JsHCPSSg0IOBGfB#BIUcpT!&9yu z8&jlnyPJN=`;$)d^+%)2Zm#=7n~-OHgq)q^Ix~}&8S89ha}(DPG=fH_xiOvY9_(+0 z@1kh76;2O!BiMWUvsoi}v$^yBQ|F@ism+xg87Zu8E9)NTa1G;O+`p2cE{y&T-#mUE zCnyXE1H!;^G2nNpU~Rd6Oa4X}5C)cj0p1@%C}Zrga%i^>6!r-K9@cH-u(IKd*Loh)A_Z{VzmKBJ!Y&l{%Wg2#>QaNX2=oKxLkh z&@B~5neN5eLbN!Rkpcd9HQFalITiHc|LGVbyez&!KmRcTYau$G3~%DhMBm3ZSvo9& z;6YVZs;g@?ujVzpi|A5MqM}=jhVAa)JNHhs&f+J#8=t1hq|^Mkuk)gt=E=Y$r2PaT z=Vxi&*ORs$<^7?_jqHF|_v)SI#&p`+-P!cFgJ8DlPj_1Z?5{hsS>0Rzw6%BKxyr6{ zeP`xP3TxEJ2ZvAa3&txB#?c_pbp8_~oK>R;+ze<;DfK9^EBu+E--vk05V|75fG{8o zEHwjeKlB<)JxiIKFdz*43kG<9@S%*M!_uPJI?$LB0La%!Be40>$T_~l&|zs2BM@a% zfi_jS5<}T^_PbW*PPQ0~pjRVd259nbeoIH}O0w8DTeFwek>?Kb)RKYY9X zpHGsWFdz*4R}84?L3Gf@C%LnA;p6zM^`SqYEF4!_d`^L3j$*{}QM>^)0>94&Fmza2 Rga;xQ0Yif{!oa&S@CZ#createMock(RouterInterface::class); + $requestStackMock = $this->createMock(RequestStack::class); + $kernelMock = $this->createMock(KernelInterface::class); + + $this->apiContext = new ApiContext($routerMock, $requestStackMock, $kernelMock); + } + + /** + * @param array $paramsValues + * @param string $initialParamValue + * + * @dataProvider getConvertRunnableCodeParamsDataSuccess + */ + public function testConvertRunnableCodeParamsSuccess(array $paramsValues, string $initialParamValue): void + { + $this->assertEquals($initialParamValue, $paramsValues['dateFrom']); + $this->assertEquals($initialParamValue, $paramsValues['levelOne']['dateFrom']); + $this->assertEquals($initialParamValue, $paramsValues['levelOne']['levelTwo']['dateFrom']); + + $resultParamsValues = $this->apiContext->convertRunnableCodeParams($paramsValues); + + $this->assertIsInt($resultParamsValues['dateFrom']); + $this->assertIsInt($resultParamsValues['levelOne']['dateFrom']); + $this->assertIsInt($resultParamsValues['levelOne']['levelTwo']['dateFrom']); + $this->assertEquals(10, strlen((string)$resultParamsValues['dateFrom'])); + $this->assertEquals(10, strlen((string)$resultParamsValues['levelOne']['dateFrom'])); + $this->assertEquals(10, strlen((string)$resultParamsValues['levelOne']['levelTwo']['dateFrom'])); + $this->assertEquals($paramsValues['tripId'], $resultParamsValues['tripId']); + $this->assertEquals($paramsValues['dateTo'], $resultParamsValues['dateTo']); + $this->assertEquals($paramsValues['levelOne']['dateTo'], $resultParamsValues['levelOne']['dateTo']); + $this->assertEquals( + $paramsValues['levelOne']['levelTwo']['dateTo'], + $resultParamsValues['levelOne']['levelTwo']['dateTo'] + ); + } + + /** + * @param array $paramsValues + * + * @dataProvider getConvertRunnableCodeParamsDataError + */ + public function testConvertRunnableCodeParamsError(array $paramsValues): void + { + $this->expectException(\Error::class); + $this->apiContext->convertRunnableCodeParams($paramsValues); + } + + public function getConvertRunnableCodeParamsDataSuccess(): array + { + return [ + [ + self::PARAMS_VALUES => [ + 'tripId' => '26e185b9-a233-470e-b2d4-2818908a075f', + 'dateTo' => 1680361181, + 'dateFrom' => '<(new DateTimeImmutable())->getTimestamp()>', + 'levelOne' => [ + 'dateTo' => 1680343281, + 'dateFrom' => '<(new DateTimeImmutable())->getTimestamp()>', + 'levelTwo' => [ + 'dateTo' => 1680360351, + 'dateFrom' => '<(new DateTimeImmutable())->getTimestamp()>', + ] + ], + ], + self::INITIAL_PARAM_VALUE => '<(new DateTimeImmutable())->getTimestamp()>', + ], + ]; + } + + public function getConvertRunnableCodeParamsDataError(): array + { + return [ + [ + self::PARAMS_VALUES => [ + 'tripId' => '26e185b9-a233-470e-b2d4-2818908a075f', + 'dateTo' => 1680360081, + 'dateFrom' => '<(new DateTimeImutable())->getTimestamp()>', + ], + ], + [ + self::PARAMS_VALUES => [ + 'tripId' => '26e185b9-a233-470e-b2d4-2818908a075f', + 'levelOne' => [ + 'dateTo' => 1680360081, + 'dateFrom' => '<(DateTimeImmutable)->getTimestamp()>', + ], + ], + ], + [ + self::PARAMS_VALUES => [ + 'tripId' => '26e185b9-a233-470e-b2d4-2818908a075f', + 'levelOne' => [ + 'levelTwo' => [ + 'dateTo' => 1680360081, + 'dateFrom' => '<(ne DateTimeImmutable())->getTimestamp()>', + ] + ], + ], + ], + [ + self::PARAMS_VALUES => [ + 'tripId' => '26e185b9-a233-470e-b2d4-2818908a075f', + 'dateTo' => 1680360081, + 'dateFrom' => '<>', + ], + ], + ]; + } +} From a211d93ca345cca9fc3e212779b548d5e7360417 Mon Sep 17 00:00:00 2001 From: Vardan Date: Thu, 19 Oct 2023 12:08:10 +0300 Subject: [PATCH 2/8] add exception handling to convertRunnableCodeParams --- src/Context/ApiContext.php | 18 +++++++++++++++--- tests/Unit/Context/ApiContextTest.php | 3 ++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/Context/ApiContext.php b/src/Context/ApiContext.php index 8383609..b76f614 100644 --- a/src/Context/ApiContext.php +++ b/src/Context/ApiContext.php @@ -15,6 +15,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\Routing\RouterInterface; +use Throwable; class ApiContext implements Context { @@ -327,12 +328,22 @@ public function convertRunnableCodeParams(array $requestParams): array $command = substr($value, 1, -1); - $resultValue = eval('return ' . $command . ';'); + try { + $resultValue = eval('return ' . $command . ';'); + } catch (Throwable $exception) { + throw new RuntimeException( + sprintf( + 'Failed run your code %s, error message: %s', + $value, + $exception->getMessage() + ) + ); + } if (is_null($resultValue)) { - throw new \Error( + throw new \RuntimeException( sprintf( - 'Running code: \'%s\' - should not return the null', + 'Running code: %s - should not return the null', $command ) ); @@ -340,6 +351,7 @@ public function convertRunnableCodeParams(array $requestParams): array $requestParams[$key] = $resultValue; } + return $requestParams; } diff --git a/tests/Unit/Context/ApiContextTest.php b/tests/Unit/Context/ApiContextTest.php index 55bee07..f3ee4f4 100644 --- a/tests/Unit/Context/ApiContextTest.php +++ b/tests/Unit/Context/ApiContextTest.php @@ -6,6 +6,7 @@ use BehatApiContext\Context\ApiContext; use PHPUnit\Framework\TestCase; +use RuntimeException; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\Routing\RouterInterface; @@ -61,7 +62,7 @@ public function testConvertRunnableCodeParamsSuccess(array $paramsValues, string */ public function testConvertRunnableCodeParamsError(array $paramsValues): void { - $this->expectException(\Error::class); + $this->expectException(RuntimeException::class); $this->apiContext->convertRunnableCodeParams($paramsValues); } From c6c7939dfac1a66cff2e411ebe6c96bbb95b1ae0 Mon Sep 17 00:00:00 2001 From: Vardan Date: Thu, 19 Oct 2023 13:15:27 +0300 Subject: [PATCH 3/8] update phpstan ignoreErrors --- phpstan.neon.dist | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 537d67f..02a7abf 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -27,6 +27,10 @@ parameters: count: 1 path: ./src/DependencyInjection - - message: '#Cannot call method (.*)? on object|null.*#' - count: 2 + message: '#Call to an undefined method object::clear().*#' + count: 1 + path: ./src/Service/ResetManager/DoctrineResetManager + - + message: '#Call to an undefined method object::getConnection().*#' + count: 1 path: ./src/Service/ResetManager/DoctrineResetManager From 40202b287ecb2e5ff7825b953eabce51d123d620 Mon Sep 17 00:00:00 2001 From: Vardan Date: Thu, 19 Oct 2023 16:54:16 +0300 Subject: [PATCH 4/8] change tests on theRequestContainsParams method --- src/Context/ApiContext.php | 14 +-- tests/Unit/Context/ApiContextTest.php | 172 +++++++++++++++++--------- 2 files changed, 118 insertions(+), 68 deletions(-) diff --git a/src/Context/ApiContext.php b/src/Context/ApiContext.php index b76f614..d45cb15 100644 --- a/src/Context/ApiContext.php +++ b/src/Context/ApiContext.php @@ -301,14 +301,7 @@ protected function compareStructureResponse(string $variableFields, PyStringNode } } - /** - * @param array $requestParams - * - * @When I have :requestParams with runnable values (placed in <>) - * - * @Then :requestParams should be converted with executing runnable code - */ - public function convertRunnableCodeParams(array $requestParams): array + protected function convertRunnableCodeParams(array $requestParams): array { foreach ($requestParams as $key => $value) { if (is_array($value)) { @@ -370,4 +363,9 @@ protected function getResponse(): Response return $this->response; } + + public function geRequestParams(): array + { + return $this->requestParams; + } } diff --git a/tests/Unit/Context/ApiContextTest.php b/tests/Unit/Context/ApiContextTest.php index f3ee4f4..99ba9b0 100644 --- a/tests/Unit/Context/ApiContextTest.php +++ b/tests/Unit/Context/ApiContextTest.php @@ -4,6 +4,7 @@ namespace BehatApiContext\Tests\Unit\Context; +use Behat\Gherkin\Node\PyStringNode; use BehatApiContext\Context\ApiContext; use PHPUnit\Framework\TestCase; use RuntimeException; @@ -27,103 +28,154 @@ protected function setUp(): void } /** - * @param array $paramsValues + * @param PyStringNode $paramsValues * @param string $initialParamValue * - * @dataProvider getConvertRunnableCodeParamsDataSuccess + * @dataProvider getTheRequestContainsParamsSuccess */ - public function testConvertRunnableCodeParamsSuccess(array $paramsValues, string $initialParamValue): void + public function testTheRequestContainsParamsSuccess(PyStringNode $paramsValues, string $initialParamValue): void { - $this->assertEquals($initialParamValue, $paramsValues['dateFrom']); - $this->assertEquals($initialParamValue, $paramsValues['levelOne']['dateFrom']); - $this->assertEquals($initialParamValue, $paramsValues['levelOne']['levelTwo']['dateFrom']); + $this->assertTrue(str_contains($paramsValues->getStrings()[3], $initialParamValue)); + $this->assertTrue(str_contains($paramsValues->getStrings()[6], $initialParamValue)); + $this->assertTrue(str_contains($paramsValues->getStrings()[9], $initialParamValue)); - $resultParamsValues = $this->apiContext->convertRunnableCodeParams($paramsValues); + $this->apiContext->theRequestContainsParams($paramsValues); - $this->assertIsInt($resultParamsValues['dateFrom']); - $this->assertIsInt($resultParamsValues['levelOne']['dateFrom']); - $this->assertIsInt($resultParamsValues['levelOne']['levelTwo']['dateFrom']); - $this->assertEquals(10, strlen((string)$resultParamsValues['dateFrom'])); - $this->assertEquals(10, strlen((string)$resultParamsValues['levelOne']['dateFrom'])); - $this->assertEquals(10, strlen((string)$resultParamsValues['levelOne']['levelTwo']['dateFrom'])); - $this->assertEquals($paramsValues['tripId'], $resultParamsValues['tripId']); - $this->assertEquals($paramsValues['dateTo'], $resultParamsValues['dateTo']); - $this->assertEquals($paramsValues['levelOne']['dateTo'], $resultParamsValues['levelOne']['dateTo']); + $this->assertIsInt($this->apiContext->geRequestParams()['dateFrom']); + $this->assertIsInt($this->apiContext->geRequestParams()['levelOne']['dateFrom']); + $this->assertIsInt($this->apiContext->geRequestParams()['levelOne']['levelTwo']['dateFrom']); + + $this->assertEquals( + 10, + strlen((string)$this->apiContext->geRequestParams()['dateFrom']) + ); $this->assertEquals( - $paramsValues['levelOne']['levelTwo']['dateTo'], - $resultParamsValues['levelOne']['levelTwo']['dateTo'] + 10, + strlen((string)$this->apiContext->geRequestParams()['levelOne']['dateFrom']) + ); + $this->assertEquals( + 10, + strlen((string)$this->apiContext->geRequestParams()['levelOne']['levelTwo']['dateFrom']) + ); + + $this->assertTrue( + str_contains( + $paramsValues->getStrings()[1], + $this->apiContext->geRequestParams()['tripId'] + ) + ); + $this->assertTrue( + str_contains( + $paramsValues->getStrings()[2], + strval($this->apiContext->geRequestParams()['dateTo']) + ) + ); + $this->assertTrue( + str_contains( + $paramsValues->getStrings()[5], + strval($this->apiContext->geRequestParams()['levelOne']['dateTo']) + ) + ); + $this->assertTrue( + str_contains( + $paramsValues->getStrings()[8], + strval($this->apiContext->geRequestParams()['levelOne']['levelTwo']['dateTo']) + ) ); } /** - * @param array $paramsValues + * @param PyStringNode $paramsValues * - * @dataProvider getConvertRunnableCodeParamsDataError + * @dataProvider getTheRequestContainsParamsRuntimeException */ - public function testConvertRunnableCodeParamsError(array $paramsValues): void + public function testTheRequestContainsParamsRuntimeException(PyStringNode $paramsValues): void { $this->expectException(RuntimeException::class); - $this->apiContext->convertRunnableCodeParams($paramsValues); + $this->apiContext->theRequestContainsParams($paramsValues); } - public function getConvertRunnableCodeParamsDataSuccess(): array + public function getTheRequestContainsParamsSuccess(): array { return [ [ - self::PARAMS_VALUES => [ - 'tripId' => '26e185b9-a233-470e-b2d4-2818908a075f', - 'dateTo' => 1680361181, - 'dateFrom' => '<(new DateTimeImmutable())->getTimestamp()>', - 'levelOne' => [ - 'dateTo' => 1680343281, - 'dateFrom' => '<(new DateTimeImmutable())->getTimestamp()>', - 'levelTwo' => [ - 'dateTo' => 1680360351, - 'dateFrom' => '<(new DateTimeImmutable())->getTimestamp()>', - ] + self::PARAMS_VALUES => new PyStringNode( + [ + '{', + ' "tripId": "26e185b9-a233-470e-b2d4-2818908a075f",', + ' "dateTo": 1680361181,', + ' "dateFrom": "<(new DateTimeImmutable())->getTimestamp()>",', + ' "levelOne": {', + ' "dateTo": 1680343281,', + ' "dateFrom": "<(new DateTimeImmutable())->getTimestamp()>",', + ' "levelTwo": {', + ' "dateTo": 1680343281,', + ' "dateFrom": "<(new DateTimeImmutable())->getTimestamp()>"', + ' }', + ' }', + '}', ], - ], + 12 + ), self::INITIAL_PARAM_VALUE => '<(new DateTimeImmutable())->getTimestamp()>', ], ]; } - public function getConvertRunnableCodeParamsDataError(): array + public function getTheRequestContainsParamsRuntimeException(): array { return [ [ - self::PARAMS_VALUES => [ - 'tripId' => '26e185b9-a233-470e-b2d4-2818908a075f', - 'dateTo' => 1680360081, - 'dateFrom' => '<(new DateTimeImutable())->getTimestamp()>', - ], + self::PARAMS_VALUES => new PyStringNode( + [ + '{', + ' "tripId": "26e185b9-a233-470e-b2d4-2818908a075f",', + ' "dateTo": 1680361181,', + ' "dateFrom": "<(new DateTimeImutable())->getTimestamp()>"', + '}', + ], + 12 + ) ], [ - self::PARAMS_VALUES => [ - 'tripId' => '26e185b9-a233-470e-b2d4-2818908a075f', - 'levelOne' => [ - 'dateTo' => 1680360081, - 'dateFrom' => '<(DateTimeImmutable)->getTimestamp()>', + self::PARAMS_VALUES => new PyStringNode( + [ + '{', + ' "tripId": "26e185b9-a233-470e-b2d4-2818908a075f",', + ' "dateTo": 1680361181,', + ' "dateFrom": "<(DateTimeImmutable)->getTimestamp()>"', + '}', ], - ], + 12 + ) ], [ - self::PARAMS_VALUES => [ - 'tripId' => '26e185b9-a233-470e-b2d4-2818908a075f', - 'levelOne' => [ - 'levelTwo' => [ - 'dateTo' => 1680360081, - 'dateFrom' => '<(ne DateTimeImmutable())->getTimestamp()>', - ] + self::PARAMS_VALUES => new PyStringNode( + [ + '{', + ' "tripId": "26e185b9-a233-470e-b2d4-2818908a075f",', + ' "levelOne": {', + ' "levelTwo": {', + ' "dateTo": 1680343281,', + ' "dateFrom": "<(ne DateTimeImmutable())->getTimestamp()>"', + ' }', + ' }', + '}', ], - ], + 12 + ), ], [ - self::PARAMS_VALUES => [ - 'tripId' => '26e185b9-a233-470e-b2d4-2818908a075f', - 'dateTo' => 1680360081, - 'dateFrom' => '<>', - ], + self::PARAMS_VALUES => new PyStringNode( + [ + '{', + ' "tripId": "26e185b9-a233-470e-b2d4-2818908a075f",', + ' "dateTo": 1680361181,', + ' "dateFrom": "<>"', + '}', + ], + 12 + ) ], ]; } From 7809838702fdaeeb4feb9e0c2eabbf77317ff1e3 Mon Sep 17 00:00:00 2001 From: Vardan Date: Thu, 19 Oct 2023 17:48:25 +0300 Subject: [PATCH 5/8] add description to readme --- README.md | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 792ac5d..0d1980f 100644 --- a/README.md +++ b/README.md @@ -62,12 +62,44 @@ Step 2: Configure Behat Go to `behat.yml` ```yaml -... +# ... contexts: - BehatApiContext\Context\ApiContext -... +# ... ``` +Usage +============= + +Runnable request parameters +---------------------------------- +Main use case when tests need to use current date. +Instead of static data in some `testCaseName.feature`, like this: +```feature +""" +{ + "dateTo": 1680360081, + "dateFrom": 1680532881, +} +""" +``` +Can use, for example: +```feature +""" +{ + "dateTo": "<(new DateTimeImmutable())->add(new DateInterval('P6D'))->getTimeStamp()>", + "dateFrom": "<(new DateTimeImmutable())->add(new DateInterval('P2D'))->getTimeStamp()>", +} +""" +``` + +#### To accomplish this, several conditions must be met: +- Runnable code must be a string and placed in `<>` +- Should not add `return` keyword at the beginning, otherwise will get RuntimeException +- Should not add `;` keyword at the end, otherwise will get RuntimeException +- Should not use the code that returns `null`, otherwise will get RuntimeException + + [master Build Status]: https://github.com/macpaw/behat-api-context/actions?query=workflow%3ACI+branch%3Amaster [master Build Status Image]: https://github.com/macpaw/behat-api-context/workflows/CI/badge.svg?branch=master [develop Build Status]: https://github.com/macpaw/behat-api-context/actions?query=workflow%3ACI+branch%3Adevelop From 5042751aed5ffae66f1809d231203e51a332eedb Mon Sep 17 00:00:00 2001 From: Vardan Date: Thu, 19 Oct 2023 18:01:06 +0300 Subject: [PATCH 6/8] add trim in convertRunnableCodeParams method --- src/Context/ApiContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Context/ApiContext.php b/src/Context/ApiContext.php index d45cb15..b869096 100644 --- a/src/Context/ApiContext.php +++ b/src/Context/ApiContext.php @@ -313,7 +313,7 @@ protected function convertRunnableCodeParams(array $requestParams): array continue; } - $pregMatchValue = preg_match('/^<.*>$/', $value); + $pregMatchValue = preg_match('/^<.*>$/', trim($value)); if ($pregMatchValue === 0 || $pregMatchValue === false) { continue; From ab6e6f9a56e199a83011eeccba27efff21b9bf52 Mon Sep 17 00:00:00 2001 From: Vardan Date: Thu, 19 Oct 2023 18:13:37 +0300 Subject: [PATCH 7/8] add .DS_Store to gitignore --- .DS_Store | Bin 8196 -> 0 bytes .gitignore | 1 + src/.DS_Store | Bin 6148 -> 0 bytes tests/.DS_Store | Bin 6148 -> 0 bytes tests/Unit/.DS_Store | Bin 6148 -> 0 bytes 5 files changed, 1 insertion(+) delete mode 100644 .DS_Store delete mode 100644 src/.DS_Store delete mode 100644 tests/.DS_Store delete mode 100644 tests/Unit/.DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 2e452ef242973d1ba0545b898c87ae2e01205510..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeI1-D(p-7>2(|(q==jrlOD&VZqZ9W0gYjB<4pcXoPO6h)T?6gI&Ab3A;%nlt7O4 z9=ruly%O)mBYo$mWp|sP2Stj`z|1?l`@OR>&rY)aQX*o_sdta4N<nN28zpQumI=`q?C)D%O&5HJJ`0YktLxQYbu&KAX5@!nTgO=}1k0{<< z3Tq4otVoa4iFl}Wz#bC;g>$V7oHnc93DmyV{ zC#LVrbcVv@-QlxkII)IO(;5PXz(oQgcfTR?^)_`<`Foezbbu>8s?jlddjTK10e2BE zK4OnhYd>W{kLVf=i6d@|Hl`6paD70JQdPIf!vye{Y6#SHgpkD8cm z589Tw>pXZ?Zu!XM50m76UdP6mEBilo8!MhJQH(hog8Yw~I6#nS7j3s%W0^()oW z)9u}zE&D;eKHsuWcem^4-`|HDFcb|DDyp|6lfP&3J}@A#jBVutM8uH!-2JKXbBk6S=mH`VLhT5w}n(Eofvq i4wdOR^!y)&=-UVto`%+iQk+3CKLkh&rZEKmDuG`!nm(Wa diff --git a/.gitignore b/.gitignore index a9893ed..0f35a13 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /node_modules/ /.idea/ /package-lock.json +.DS_Store diff --git a/src/.DS_Store b/src/.DS_Store deleted file mode 100644 index e698526d20ba947febb70d63297b88e5cedcb076..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKO>fgc5S?uUcBqgd0a7_2S>jq1Q&6Rfi|d9%uQh@Lpb*CvF_>M;9}QI$$>;K8 zxbjQ*FPz}*M^WMc2M!2DJJQUX-JQ42KE=CUB4S~aJR}+rkqejDyMgcvljG9YY|HdG zK&IxX>6i-2=!C>twe7G9SOxw!1?0PXmqJQuN@H4ne>qwyeMAhYAx;V9Xz%0wo>Fm| zi%Fb|7;L$99K-j&D?>))s2$+v44vxFf3A*aRbl4-5*K+^)xQ6gZEg3iU3Xl^-Em(> zQ!$I`aotqmxO^#F&xFY1t9%?k&(hgwaQj5?dYtjJRD>)^QS$0V#uG6MMZ=RyaU(t8 z_TBzyusfe093Ad?k9~i!=gp4}eB_S~7mL1o=l+8yXQTJ|2QDtvDv4p&Q+Ctf6?{U{ z(cnBPc`o={j7Zik8bZwiE|ryWLKk!je23Nqs%O|k`Kog49+=BI_vsAP6)GDl!9w0) z$X~L|a414mN#~d!^_}W(ooY0#ZL9+3-|Oyd>XrooYDzK`+wr&pO`Tz9y_y1LrZCM4Z0vn|O>kXq}h$We`b!~C-to7h;;L>DW nt5H!9%yFy|c@*!$m0`@22{16&YD5preh4TTY_JOaQw4qiW5btx diff --git a/tests/.DS_Store b/tests/.DS_Store deleted file mode 100644 index e5c191243ac704cce1498be11a06c0016ff4218c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKO-~y!5FLlKY=n>^wUs!o#1+97DkRj)HVp@^U0M!MrP*xME^O^6*)&2?q&>rr z;mR-R-+?!_1EML{Dyn9r@f(k4yz6JnA4H^D`8&cqp2OFpl5#Snj|$UE3zH&)m&*s}_MH`2 zM0NU%jGW3p;%=UcODCg&@9#Dp6#1x(qTi~vQh)JsHCPSSg0IOBGfB#BIUcpT!&9yu z8&jlnyPJN=`;$)d^+%)2Zm#=7n~-OHgq)q^Ix~}&8S89ha}(DPG=fH_xiOvY9_(+0 z@1kh76;2O!BiMWUvsoi}v$^yBQ|F@ism+xg87Zu8E9)NTa1G;O+`p2cE{y&T-#mUE zCnyXE1H!;^G2nNpU~Rd6Oa4X}5C)cj0p1@%C}Zrga%i^>6!r-K9@cH-u(IKd*Loh)A_Z{VzmKBJ!Y&l{%Wg2#>QaNX2=oKxLkh z&@B~5neN5eLbN!Rkpcd9HQFalITiHc|LGVbyez&!KmRcTYau$G3~%DhMBm3ZSvo9& z;6YVZs;g@?ujVzpi|A5MqM}=jhVAa)JNHhs&f+J#8=t1hq|^Mkuk)gt=E=Y$r2PaT z=Vxi&*ORs$<^7?_jqHF|_v)SI#&p`+-P!cFgJ8DlPj_1Z?5{hsS>0Rzw6%BKxyr6{ zeP`xP3TxEJ2ZvAa3&txB#?c_pbp8_~oK>R;+ze<;DfK9^EBu+E--vk05V|75fG{8o zEHwjeKlB<)JxiIKFdz*43kG<9@S%*M!_uPJI?$LB0La%!Be40>$T_~l&|zs2BM@a% zfi_jS5<}T^_PbW*PPQ0~pjRVd259nbeoIH}O0w8DTeFwek>?Kb)RKYY9X zpHGsWFdz*4R}84?L3Gf@C%LnA;p6zM^`SqYEF4!_d`^L3j$*{}QM>^)0>94&Fmza2 Rga;xQ0Yif{!oa&S@CZ# Date: Fri, 20 Oct 2023 12:22:22 +0300 Subject: [PATCH 8/8] add trim to command forming Co-authored-by: Aleksey --- src/Context/ApiContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Context/ApiContext.php b/src/Context/ApiContext.php index b869096..0e99d3f 100644 --- a/src/Context/ApiContext.php +++ b/src/Context/ApiContext.php @@ -319,7 +319,7 @@ protected function convertRunnableCodeParams(array $requestParams): array continue; } - $command = substr($value, 1, -1); + $command = substr(trim($value), 1, -1); try { $resultValue = eval('return ' . $command . ';');