Skip to content

Conversation

@ThomasLandauer
Copy link
Member

@ThomasLandauer ThomasLandauer commented Oct 26, 2020

Removing flow/jsonpath dependency, see #24 (comment)

Closes #24

Removing `flow/jsonpath` dependency, see Codeception#24 (comment)
@SoftCreatR
Copy link
Contributor

This would break the lib, since JSONPath is used here: https://github.com/Codeception/module-rest/blob/master/src/Codeception/Util/JsonArray.php

A better solution has been provided: #24 (comment)

@ThomasLandauer
Copy link
Member Author

See #31 for the current plan: Remove it as a dependency, and explain users how to install it by themselves.

@SoftCreatR
Copy link
Contributor

See #31 for the current plan: Remove it as a dependency, and explain users how to install it by themselves.

That doesn't change the fact, that your PR would break the lib ;)

@TavoNiievez
Copy link
Member

@ThomasLandauer what SoftCreatR is trying to say is that if the goal was to remove the library, you would have to remove this functions as well:

/**
* Checks if json structure in response matches [JsonPath](http://goessner.net/articles/JsonPath/).
* JsonPath is XPath equivalent for querying Json structures.
* Try your JsonPath expressions [online](http://jsonpath.curiousconcept.com/).
* This assertion allows you to check the structure of response json.
*
* This method **require [`flow/jsonpath` > 0.2](https://github.com/FlowCommunications/JSONPath/) library to be installed**.
*
* ```json
* { "store": {
* "book": [
* { "category": "reference",
* "author": "Nigel Rees",
* "title": "Sayings of the Century",
* "price": 8.95
* },
* { "category": "fiction",
* "author": "Evelyn Waugh",
* "title": "Sword of Honour",
* "price": 12.99
* }
* ],
* "bicycle": {
* "color": "red",
* "price": 19.95
* }
* }
* }
* ```
*
* ```php
* <?php
* // at least one book in store has author
* $I->seeResponseJsonMatchesJsonPath('$.store.book[*].author');
* // first book in store has author
* $I->seeResponseJsonMatchesJsonPath('$.store.book[0].author');
* // at least one item in store has price
* $I->seeResponseJsonMatchesJsonPath('$.store..price');
* ?>
* ```
*
* @param string $jsonPath
* @part json
* @version 2.0.9
*/
public function seeResponseJsonMatchesJsonPath($jsonPath)
{
$response = $this->connectionModule->_getResponseContent();
$this->assertNotEmpty(
(new JsonArray($response))->filterByJsonPath($jsonPath),
"Received JSON did not match the JsonPath `$jsonPath`.\nJson Response: \n" . $response
);
}
/**
* Opposite to seeResponseJsonMatchesJsonPath
*
* @param string $jsonPath
* @part json
*/
public function dontSeeResponseJsonMatchesJsonPath($jsonPath)
{
$response = $this->connectionModule->_getResponseContent();
$this->assertEmpty(
(new JsonArray($response))->filterByJsonPath($jsonPath),
"Received JSON matched the JsonPath `$jsonPath`.\nJson Response: \n" . $response
);
}
/**
* Opposite to seeResponseContainsJson
*
* @part json
* @param array $json
*/
public function dontSeeResponseContainsJson($json = [])
{
$jsonResponseArray = new JsonArray($this->connectionModule->_getResponseContent());
$this->assertFalse(
$jsonResponseArray->containsArray($json),
"Response JSON contains provided JSON\n"
. "- <info>" . var_export($json, true) . "</info>\n"
. "+ " . var_export($jsonResponseArray->toArray(), true)
);
}
/**
* Checks that JSON matches provided types.
* In case you don't know the actual values of JSON data returned you can match them by type.
* It starts the check with a root element. If JSON data is an array it will check all elements of it.
* You can specify the path in the json which should be checked with JsonPath
*
* Basic example:
*
* ```php
* <?php
* // {'user_id': 1, 'name': 'davert', 'is_active': false}
* $I->seeResponseMatchesJsonType([
* 'user_id' => 'integer',
* 'name' => 'string|null',
* 'is_active' => 'boolean'
* ]);
*
* // narrow down matching with JsonPath:
* // {"users": [{ "name": "davert"}, {"id": 1}]}
* $I->seeResponseMatchesJsonType(['name' => 'string'], '$.users[0]');
* ?>
* ```
*
* You can check if the record contains fields with the data types you expect.
* The list of possible data types:
*
* * string
* * integer
* * float
* * array (json object is array as well)
* * boolean
* * null
*
* You can also use nested data type structures, and define multiple types for the same field:
*
* ```php
* <?php
* // {'user_id': 1, 'name': 'davert', 'company': {'name': 'Codegyre'}}
* $I->seeResponseMatchesJsonType([
* 'user_id' => 'integer|string', // multiple types
* 'company' => ['name' => 'string']
* ]);
* ?>
* ```
*
* You can also apply filters to check values. Filter can be applied with a `:` char after the type declaration,
* or after another filter if you need more than one.
*
* Here is the list of possible filters:
*
* * `integer:>{val}` - checks that integer is greater than {val} (works with float and string types too).
* * `integer:<{val}` - checks that integer is lower than {val} (works with float and string types too).
* * `string:url` - checks that value is valid url.
* * `string:date` - checks that value is date in JavaScript format: https://weblog.west-wind.com/posts/2014/Jan/06/JavaScript-JSON-Date-Parsing-and-real-Dates
* * `string:email` - checks that value is a valid email according to http://emailregex.com/
* * `string:regex({val})` - checks that string matches a regex provided with {val}
*
* This is how filters can be used:
*
* ```php
* <?php
* // {'user_id': 1, 'email' => '[email protected]'}
* $I->seeResponseMatchesJsonType([
* 'user_id' => 'string:>0:<1000', // multiple filters can be used
* 'email' => 'string:regex(~\@~)' // we just check that @ char is included
* ]);
*
* // {'user_id': '1'}
* $I->seeResponseMatchesJsonType([
* 'user_id' => 'string:>0', // works with strings as well
* ]);
* ?>
* ```
*
* You can also add custom filters by using `{@link JsonType::addCustomFilter()}`.
* See [JsonType reference](http://codeception.com/docs/reference/JsonType).
*
* @part json
* @param array $jsonType
* @param string $jsonPath
* @see JsonType
* @version 2.1.3
*/
public function seeResponseMatchesJsonType(array $jsonType, $jsonPath = null)
{
$jsonArray = new JsonArray($this->connectionModule->_getResponseContent());
if ($jsonPath) {
$jsonArray = $jsonArray->filterByJsonPath($jsonPath);
}
\PHPUnit\Framework\Assert::assertThat($jsonArray, new JsonTypeConstraint($jsonType));
}
/**
* Opposite to `seeResponseMatchesJsonType`.
*
* @part json
* @param $jsonType jsonType structure
* @param null $jsonPath optionally set specific path to structure with JsonPath
* @see seeResponseMatchesJsonType
* @version 2.1.3
*/
public function dontSeeResponseMatchesJsonType($jsonType, $jsonPath = null)
{
$jsonArray = new JsonArray($this->connectionModule->_getResponseContent());
if ($jsonPath) {
$jsonArray = $jsonArray->filterByJsonPath($jsonPath);
}
\PHPUnit\Framework\Assert::assertThat($jsonArray, new JsonTypeConstraint($jsonType, false));
}

public function filterByJsonPath($jsonPath)
{
if (!class_exists('Flow\JSONPath\JSONPath')) {
throw new \Exception('JSONPath library not installed. Please add `flow/jsonpath` to composer.json');
}
return (new JSONPath($this->jsonArray))->find($jsonPath)->data();
}

So as not to break the installation and the tests themselves.

However, it is better to wait for the owners to decide whether the changes made by SoftCreatR to make the semantic versioning less confusing are enough to keep that code unchanged.

@Naktibalda
Copy link
Member

Replaced by #35

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Abandoned dependency

4 participants