summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMateu Aguiló Bosch2017-09-16 14:28:34 +0200
committerMateu Aguiló Bosch2017-09-16 14:28:34 +0200
commite54d8e7ba6b8ada8b8605506988a4c671fe5ca0e (patch)
tree39213092d55ae404316a9c10cd9d9ce280dcf3dd
parent45ed3e84aa787657a9d6412422c45a237164c5f4 (diff)
fix(Replacements): Fix the replacements multiplicity
-rw-r--r--src/JsonPathReplacer.php70
1 files changed, 60 insertions, 10 deletions
diff --git a/src/JsonPathReplacer.php b/src/JsonPathReplacer.php
index 2b8a4c4..6cd1dcf 100644
--- a/src/JsonPathReplacer.php
+++ b/src/JsonPathReplacer.php
@@ -84,20 +84,32 @@ class JsonPathReplacer {
* @private
*/
protected function doReplaceTokensInLocation(array $token_replacements, $tokenized_subrequest, $token_location) {
- $index = 0;
$replacements = [];
- foreach ($token_replacements[$token_location] as $tokens) {
+ // For each subrequest, we need to replace all the tokens.
+ $tr = [];
+ // Go from the flat array with the $id_tuple to an array of arrays.
+ foreach ($token_replacements[$token_location] as $id_tuple => $key_val) {
+ list($req_id, $idx) = explode('::', $id_tuple);
+ $tr[$req_id] = empty($tr[$req_id]) ? [] : $tr[$req_id];
+ $tr[$req_id][$idx] = $key_val;
+ }
+ $points = $this->getPoints($tr);
+ $keys = array_keys($tr);
+ foreach ($points as $index => $point) {
// Clone the subrequest.
$cloned = clone $tokenized_subrequest;
$cloned->requestId = sprintf(
'%s#%s{%s}',
$tokenized_subrequest->requestId,
- $token_location, $index
+ $token_location,
+ $index
);
- $index++;
// Now replace all the tokens in the request member (body or URI).
$token_subject = $this->serializeMember($token_location, $cloned->{$token_location});
- foreach ($tokens as $token => $value) {
+ foreach ($point as $axis => $position) {
+ $replacement_info = $tr[$keys[$axis]][$position];
+ $value = reset($replacement_info);
+ $token = key($replacement_info);
$regexp = sprintf('/%s/', preg_quote($token), '/');
$token_subject = preg_replace($regexp, $value, $token_subject);
}
@@ -108,6 +120,41 @@ class JsonPathReplacer {
}
/**
+ * Generates a list of sets of coordinates for the token replacements.
+ *
+ * Each point (coordinates set) end up creating a new clone of the tokenized
+ * subrequest.
+ *
+ * @param array $tr
+ * Token replacements array structure.
+ *
+ * @return array
+ * The coordinates sets.
+ */
+ protected function getPoints($tr) {
+ $indices_matrix = array_reduce($tr, function ($carry, array $found_replacements) {
+ $carry[] = array_keys($found_replacements);
+ return $carry;
+ }, []);
+ $points = [];
+ foreach ($indices_matrix as $current) {
+ $new_points = [];
+ foreach ($current as $index) {
+ if (empty($points)) {
+ $new_points[] = [$index];
+ }
+ else {
+ foreach ($points as $coordinate_set) {
+ $new_points[] = array_merge($coordinate_set, [$index]);
+ }
+ }
+ }
+ $points = $new_points;
+ }
+ return $points;
+ }
+
+ /**
* Makes sure that the subject for replacement is a string.
*
* This is an abstraction to be able to treat 'uri' and 'body' replacements
@@ -187,10 +234,11 @@ class JsonPathReplacer {
$provided_id = preg_replace('/\.body$/', '', $match[1]);
// Calculate what are the subjects to execute the JSONPath against.
$subjects = array_filter($pool, function (Response $response) use ($provided_id) {
- $content_id = preg_replace('/#.*/', '', $this->getContentId($response));
// The response is considered a subject if it matches the content ID or
- // it is a generated copy based of that content ID.
- return $content_id === $provided_id;
+ // it is a generated copy based of that content ID.
+ $pattern = sprintf('/%s(#.*)?/', preg_quote($provided_id));
+ $content_id = $this->getContentId($response);
+ return preg_match($pattern, $content_id);
});
if (count($subjects) === 0) {
$candidates = array_map(function ($response) {
@@ -203,7 +251,9 @@ class JsonPathReplacer {
implode(', ', $candidates)
));
}
- // Find the replacements for this match given a subject.
+ // Find the replacements for this match given a subject. If there is more
+ // than one response object (a subject) for a given subrequest, then we
+ // generate one parallel subrequest per subject.
foreach ($subjects as $subject) {
$this->addReplacementsForSubject($match, $subject, $token_replacements);
}
@@ -275,7 +325,7 @@ class JsonPathReplacer {
// The replacements need to be strings. If not, then the replacement
// is not valid.
$this->validateJsonPathReplacements($to_replace);
- // Place all the replacement items in the tokenReplacements.
+ // Place all the replacement items in the $token_replacements.
foreach ($to_replace as $index => $replacement_token_value) {
// Set the match for the Response ID + match item.
$id_tuple = implode('::', [