Skip to content

Commit eebc8bf

Browse files
committed
ISSUE-659 # add ability to refer CSV source value by header
1 parent b41ea94 commit eebc8bf

File tree

6 files changed

+124
-8
lines changed

6 files changed

+124
-8
lines changed

core/src/main/java/org/jsmart/zerocode/core/engine/preprocessor/ZeroCodeParameterizedProcessorImpl.java

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
import org.apache.commons.collections4.CollectionUtils;
88
import org.apache.commons.text.StringSubstitutor;
99
import org.jsmart.zerocode.core.domain.ScenarioSpec;
10+
import org.jsmart.zerocode.core.utils.TokenUtils;
1011
import org.slf4j.Logger;
1112

1213
import java.util.Arrays;
1314
import java.util.HashMap;
1415
import java.util.List;
1516
import java.util.Map;
16-
import java.util.concurrent.atomic.AtomicLong;
17+
import java.util.stream.IntStream;
18+
import java.util.stream.Stream;
1719

1820
import static org.jsmart.zerocode.core.constants.ZerocodeConstants.DSL_FORMAT;
1921
import static org.jsmart.zerocode.core.di.provider.CsvParserProvider.LINE_SEPARATOR;
@@ -115,10 +117,13 @@ private ScenarioSpec resolveParamsCsv(ScenarioSpec scenario, int paramIndex) {
115117
return scenario;
116118
}
117119

118-
Map<String, Object> valuesMap = new HashMap<>();
120+
String[] headers = retrieveCsvHeaders(parameterizedCsvList.get(0));
121+
122+
paramIndex = headers == null ? paramIndex : paramIndex+1;
123+
119124
String csvLine = parameterizedCsvList.get(paramIndex);
120125

121-
resolveCsvLine(valuesMap, csvLine);
126+
Map<String, Object> valuesMap = resolveCsvLine(csvLine, headers);
122127

123128
String resultantStepJson = replaceWithValues(stepJson, valuesMap);
124129

@@ -129,11 +134,26 @@ private ScenarioSpec resolveParamsCsv(ScenarioSpec scenario, int paramIndex) {
129134
}
130135
}
131136

132-
private void resolveCsvLine(Map<String, Object> valuesMap, String csvLine) {
137+
private String[] retrieveCsvHeaders(String csvHeaderLine) {
138+
String[] parsedHeaderLine = csvParser.parseLine(csvHeaderLine + LINE_SEPARATOR);
139+
Stream<String> headers = Arrays.stream(parsedHeaderLine);
140+
boolean hasHeader = parsedHeaderLine.length > 0 && headers.allMatch(s -> s.matches("^\\|.*\\|$"));
141+
return !hasHeader ? null : headers.map(s -> s.substring(1,s.length()-1)).toArray(String[]::new);
142+
}
143+
144+
private Map<String, Object> resolveCsvLine(String csvLine, String[] headers) {
145+
Map<String, Object> valuesMap = new HashMap<>();
133146
String[] parsedLine = csvParser.parseLine(csvLine + LINE_SEPARATOR);
134-
AtomicLong index = new AtomicLong(0);
135-
Arrays.stream(parsedLine)
136-
.forEach(thisValue -> valuesMap.put(index.getAndIncrement() + "", thisValue));
147+
IntStream.range(0, parsedLine.length).forEach(i -> valuesMap.put(i + "", parsedLine[i]));
148+
149+
if (headers != null){
150+
IntStream.range(0, headers.length).forEach(i -> {
151+
if(!headers[i].contains(" ") && !headers[i].isEmpty()){
152+
valuesMap.put("PARAM."+headers[i], TokenUtils.resolveKnownTokens(parsedLine[i]).toString());
153+
}
154+
});
155+
}
156+
return valuesMap;
137157
}
138158

139159
private String replaceWithValues(String stepJson, Map<String, Object> valuesMap) {

core/src/test/java/org/jsmart/zerocode/core/engine/preprocessor/ZeroCodeParameterizedProcessorImplTest.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package org.jsmart.zerocode.core.engine.preprocessor;
22

3+
import com.fasterxml.jackson.databind.JsonNode;
34
import com.fasterxml.jackson.databind.ObjectMapper;
45
import com.univocity.parsers.csv.CsvParser;
56
import jakarta.inject.Inject;
67
import org.jsmart.zerocode.core.di.main.ApplicationMainModule;
78
import org.jsmart.zerocode.core.domain.ScenarioSpec;
9+
import org.jsmart.zerocode.core.domain.Step;
810
import org.jsmart.zerocode.core.utils.SmartUtils;
911
import org.jukito.JukitoRunner;
1012
import org.jukito.TestModule;
@@ -75,7 +77,7 @@ public void testProcessParameterized_values() throws Exception {
7577
@Test
7678
public void testProcessParameterized_csv() throws Exception {
7779
String jsonDocumentAsString = smartUtils
78-
.getJsonDocumentAsString("unit_test_files/engine_unit_test_jsons/11_scenario_parameterized_csv.json");
80+
.getJsonDocumentAsString("unit_test_files/engine_unit_test_jsons/11.1_scenario_parameterized_csv.json");
7981
ScenarioSpec scenarioSpec = mapper.readValue(jsonDocumentAsString, ScenarioSpec.class);
8082

8183
ScenarioSpec scenarioSpecResolved = parameterizedProcessor.resolveParameterized(scenarioSpec, 0);
@@ -87,4 +89,23 @@ public void testProcessParameterized_csv() throws Exception {
8789
assertThat(scenarioSpecResolved.getSteps().get(0).getAssertions().get("status").asInt(), is(400));
8890

8991
}
92+
93+
@Test
94+
public void testProcessParameterized_csv_with_named_random() throws Exception {
95+
String jsonDocumentAsString = smartUtils
96+
.getJsonDocumentAsString("unit_test_files/engine_unit_test_jsons/11.2_scenario_parameterized_csv_with_named_random.json");
97+
ScenarioSpec scenarioSpec = mapper.readValue(jsonDocumentAsString, ScenarioSpec.class);
98+
99+
ScenarioSpec scenarioSpecResolved = parameterizedProcessor.resolveParameterized(scenarioSpec, 0);
100+
Step step = scenarioSpecResolved.getSteps().get(0);
101+
assertThat(step.getUrl(), is("/anUrl/${RANDOM.NUMBER}/${RANDOM.NUMBER}"));
102+
JsonNode queryParams = step.getRequest().get("queryParams");
103+
assertThat(queryParams.get("id1"), is(queryParams.get("id2")));
104+
assertThat(queryParams.get("addressId1"), is(queryParams.get("addressId2")));
105+
assertThat(scenarioSpecResolved.getSteps().get(0).getAssertions().get("status").asInt(), is(200));
106+
107+
scenarioSpecResolved = parameterizedProcessor.resolveParameterized(scenarioSpec, 1);
108+
assertThat(scenarioSpecResolved.getSteps().get(0).getUrl(), is("/anUrl/11/22"));
109+
assertThat(scenarioSpecResolved.getSteps().get(0).getAssertions().get("status").asInt(), is(400));
110+
}
90111
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.jsmart.zerocode.parameterized;
2+
3+
import org.jsmart.zerocode.core.domain.JsonTestCase;
4+
import org.jsmart.zerocode.core.domain.TargetEnv;
5+
import org.jsmart.zerocode.core.runner.ZeroCodeUnitRunner;
6+
import org.junit.Test;
7+
import org.junit.runner.RunWith;
8+
9+
@TargetEnv("app_config.properties")
10+
@RunWith(ZeroCodeUnitRunner.class)
11+
public class ParameterisedCsvHeadersDemoTest {
12+
13+
@Test
14+
@JsonTestCase("integration_test_files/parameterized/parameterized_sample_csv_test.json")
15+
public void testParameterizedCsv() throws Exception {
16+
}
17+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"scenarioName": "Parameterized test scenario demo",
3+
"steps": [
4+
{
5+
"name": "get_user",
6+
"url": "",
7+
"operation": "",
8+
"request": {
9+
"status": "${2}",
10+
"body": {
11+
"login": "octocat-${PARAM.id}-${PARAM.AddressId}"
12+
}
13+
},
14+
"assertions": {
15+
"status": "${$.get_user.response.status}",
16+
"body": {
17+
"login": "octocat-${PARAM.id}-${PARAM.AddressId}"
18+
}
19+
}
20+
}
21+
],
22+
"parameterized": {
23+
"csvSource":[
24+
"|id|, |AddressId|, |status|",
25+
"${RANDOM.NUMBER}, ${RANDOM.NUMBER}, 200",
26+
"11, 22, 400"
27+
]
28+
}
29+
}

core/src/test/resources/unit_test_files/engine_unit_test_jsons/11_scenario_parameterized_csv.json renamed to core/src/test/resources/unit_test_files/engine_unit_test_jsons/11.1_scenario_parameterized_csv.json

File renamed without changes.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"scenarioName": "For deserialize only",
3+
"ignoreStepFailures": true,
4+
"steps": [
5+
{
6+
"name": "step1",
7+
"url": "/anUrl/${0}/${1}",
8+
"operation": "GET",
9+
"request": {
10+
"queryParams": {
11+
"id1": "${PARAM.id}",
12+
"id2": "${PARAM.id}",
13+
"addressId1": "${PARAM.AddressId}",
14+
"addressId2": "${PARAM.AddressId}"
15+
}
16+
},
17+
"assertions": {
18+
"status": "${PARAM.status}"
19+
}
20+
}
21+
],
22+
"parameterized": {
23+
"csvSource": [
24+
"|id|, |AddressId|, |status|",
25+
"${RANDOM.NUMBER}, ${RANDOM.NUMBER}, 200",
26+
"11, 22, 400"
27+
]
28+
}
29+
}

0 commit comments

Comments
 (0)