Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
package org.apache.jmeter.extractor;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.Set;

import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.threads.JMeterContext;
Expand Down Expand Up @@ -108,4 +112,48 @@ public void testOnlyRightBoundary() {
assertEquals("on", vars.get("varname_1"), "First match is incorrect");
assertEquals("1", vars.get("varname_matchNr"), "MatchNumber is incorrect");
}

/**
* matchNumber=0 means the result must be one of the available matches.
*/
@Test
public void testMatchNumberZeroMultipleMatches() {
vars.put("content", "left-A-right left-B-right left-C-right");
extractor.setLeftBoundary("left-");
extractor.setRightBoundary("-right");
extractor.setMatchNumber(0);
extractor.setRefName("varname");
extractor.setScopeVariable("content");
extractor.setThreadContext(jmctx);
extractor.process();
String found = vars.get("varname");
assertTrue(Set.of("A", "B", "C").contains(found),
"matchNumber=0 result '" + found + "' should be one of the available matches");
assertNull(vars.get("varname_matchNr"),
"matchNr variable should not be set for matchNumber=0");
}

/**
* An empty Match No. is treated as 0.
*/
@Test
public void testEmptyMatchNumber() {
// Deterministic check: getMatchNumber() must return 0 for an empty field.
extractor.setMatchNumber("");
assertEquals(0, extractor.getMatchNumber(), "getMatchNumber() for an empty Match No.");

// Behavioural check: empty field behaves like 0, not like -1.
// With matchNumber=0 the non-indexed variable is set and the indexed
// variables (_1, _matchNr) are not.
vars.put("content", "left-A-right left-B-right left-C-right");
extractor.setLeftBoundary("left-");
extractor.setRightBoundary("-right");
extractor.setRefName("varname");
extractor.setScopeVariable("content");
extractor.setThreadContext(jmctx);
extractor.process();
assertNotNull(vars.get("varname"), "varname should be set");
assertNull(vars.get("varname_1"), "varname_1 should not be set for matchNumber=0");
assertNull(vars.get("varname_matchNr"), "varname_matchNr should not be set for matchNumber=0");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,15 @@ public void testVariableExtraction0() {
assertEquals("value", vars.get("regVal"));
}

/**
* An empty Match No. is treated as 0.
*/
@Test
public void testEmptyMatchNumber() {
extractor.setMatchNumber("");
assertEquals(0, extractor.getMatchNumber(), "getMatchNumber() for an empty Match No.");
}

@Test
public void testVariableExtraction() {
extractor.setRegex("<value field=\"(pinposition\\d+)\">(\\d+)</value>");
Expand Down
9 changes: 6 additions & 3 deletions xdocs/usermanual/component_reference.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5739,11 +5739,12 @@ generate the template string, and store the result into the given variable name.
<property name="Template" required="Yes">The template used to create a string from the matches found. This is an arbitrary string
with special elements to refer to groups within the regular expression. The syntax to refer to a group is: '<code>$1$</code>' to refer to
group <code>1</code>, '<code>$2$</code>' to refer to group <code>2</code>, etc. <code>$0$</code> refers to whatever the entire expression matches.</property>
<property name="Match No. (0 for Random)" required="Yes">Indicates which match to use. The regular expression may match multiple times.
<property name="Match No. (0 for Random)" required="No">Indicates which match to use. The regular expression may match multiple times.
<ul>
<li>Use a value of zero to indicate JMeter should choose a match at random.</li>
<li>A positive number N means to select the n<sup>th</sup> match.</li>
<li> Negative numbers are used in conjunction with the <complink name="ForEach Controller"/> - see below.</li>
<li>An empty field is treated as <code>0</code>.</li>
</ul>
</property>
<property name="Default Value" required="No, but recommended">
Expand Down Expand Up @@ -5853,11 +5854,12 @@ extracting the node as text or attribute value and store the result into the giv
If empty this is the equivalent of <a href="http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#text%28%29">Element#text()</a> function for JSoup if not value is set for attribute.
<figure width="825" height="275" image="css_extractor_noattr.png">CSS Extractor with no attribute set</figure>
</property>
<property name="Match No. (0 for Random)" required="Yes">Indicates which match to use. The CSS/JQuery selector may match multiple times.
<property name="Match No. (0 for Random)" required="No">Indicates which match to use. The CSS/JQuery selector may match multiple times.
<ul>
<li>Use a value of zero to indicate JMeter should choose a match at random.</li>
<li>A positive number <code>N</code> means to select the n<sup>th</sup> match.</li>
<li> Negative numbers are used in conjunction with the <complink name="ForEach Controller"/> - see below.</li>
<li>An empty field is treated as <code>0</code>.</li>
</ul>
</property>
<property name="Default Value" required="No, but recommended">
Expand Down Expand Up @@ -6307,11 +6309,12 @@ generate the template string, and store the result into the given variable name.
<property name="Name of created variable" required="Yes">The name of the JMeter variable in which to store the result. Also note that each group is stored as <code>[refname]_g#</code>, where <code>[refname]</code> is the string you entered as the reference name, and <code>#</code> is the group number, where group <code>0</code> is the entire match, group <code>1</code> is the match from the first set of parentheses, etc.</property>
<property name="Left Boundary" required="No">Left boundary of value to find</property>
<property name="Right Boundary" required="No">Right boundary of value to find</property>
<property name="Match No. (0 for Random)" required="Yes">Indicates which match to use. The boundaries may match multiple times.
<property name="Match No. (0 for Random)" required="No">Indicates which match to use. The boundaries may match multiple times.
<ul>
<li>Use a value of zero to indicate JMeter should choose a match at random.</li>
<li>A positive number N means to select the n<sup>th</sup> match.</li>
<li> Negative numbers are used in conjunction with the <complink name="ForEach Controller"/> - see below.</li>
<li>An empty field is treated as <code>0</code>.</li>
</ul>
</property>
<property name="Default Value" required="No, but recommended">
Expand Down