Repository: authorjapps/zerocode
Pull request #102 (2018-07-07 14:45:46)

ISS-101 # Regex match using String matches()


Patch:
diff --git a/src/main/java/org/jsmart/zerocode/core/engine/assertion/ArraySizeAsserter.java b/src/main/java/org/jsmart/zerocode/core/engine/assertion/ArraySizeAsserter.java
index 55170b45..4f459df8 100644
--- a/src/main/java/org/jsmart/zerocode/core/engine/assertion/ArraySizeAsserter.java
+++ b/src/main/java/org/jsmart/zerocode/core/engine/assertion/ArraySizeAsserter.java
@@ -27,7 +27,10 @@ public class ArraySizeAsserter implements JsonAsserter {
                 return AssertionReport.createFieldMatchesReport();
             }
 
-            return AssertionReport.createFieldDoesNotMatchReport(path, String.format("Array of size %d", expectedSize), result);
+            return AssertionReport.createFieldDoesNotMatchReport(
+                    path,
+                    String.format("Array of size %d", expectedSize),
+                    actualArrayValue.size());
 
         } else {
 
diff --git a/src/main/java/org/jsmart/zerocode/core/engine/assertion/FieldMatchesRegexPatternAsserter.java b/src/main/java/org/jsmart/zerocode/core/engine/assertion/FieldMatchesRegexPatternAsserter.java
new file mode 100644
index 00000000..fa505ef6
--- /dev/null
+++ b/src/main/java/org/jsmart/zerocode/core/engine/assertion/FieldMatchesRegexPatternAsserter.java
@@ -0,0 +1,32 @@
+package org.jsmart.zerocode.core.engine.assertion;
+
+public class FieldMatchesRegexPatternAsserter implements JsonAsserter {
+    private final String path;
+    private final String expected;
+
+    public FieldMatchesRegexPatternAsserter(String path, String expected) {
+        this.path = path;
+        this.expected = expected;
+    }
+
+    @Override
+    public String getPath() {
+        return path;
+    }
+
+    @Override
+    public AssertionReport actualEqualsToExpected(Object result) {
+        boolean areEqual;
+        if (result instanceof String && expected instanceof String) {
+            String s1 = (String) result;
+            String s2 = expected;
+            areEqual = s1.matches(s2);
+        } else {
+            areEqual = false;
+        }
+
+        return areEqual ?
+                AssertionReport.createFieldMatchesReport() :
+                AssertionReport.createFieldDoesNotMatchReport(path, "containing sub-string:" + expected, result);
+    }
+}


Test patch:
diff --git a/src/main/java/org/jsmart/zerocode/core/engine/preprocessor/ZeroCodeJsonTestProcesorImpl.java b/src/main/java/org/jsmart/zerocode/core/engine/preprocessor/ZeroCodeJsonTestProcesorImpl.java
index be90c405..f79f979b 100644
--- a/src/main/java/org/jsmart/zerocode/core/engine/preprocessor/ZeroCodeJsonTestProcesorImpl.java
+++ b/src/main/java/org/jsmart/zerocode/core/engine/preprocessor/ZeroCodeJsonTestProcesorImpl.java
@@ -6,19 +6,7 @@ import com.fasterxml.jackson.databind.node.JsonNodeType;
 import com.google.inject.Inject;
 import com.jayway.jsonpath.JsonPath;
 import org.apache.commons.lang.text.StrSubstitutor;
-import org.jsmart.zerocode.core.engine.assertion.ArrayIsEmptyAsserter;
-import org.jsmart.zerocode.core.engine.assertion.ArraySizeAsserter;
-import org.jsmart.zerocode.core.engine.assertion.AssertionReport;
-import org.jsmart.zerocode.core.engine.assertion.FieldHasEqualNumberValueAsserter;
-import org.jsmart.zerocode.core.engine.assertion.FieldHasExactValueAsserter;
-import org.jsmart.zerocode.core.engine.assertion.FieldHasGreaterThanValueAsserter;
-import org.jsmart.zerocode.core.engine.assertion.FieldHasInEqualNumberValueAsserter;
-import org.jsmart.zerocode.core.engine.assertion.FieldHasLesserThanValueAsserter;
-import org.jsmart.zerocode.core.engine.assertion.FieldHasSubStringIgnoreCaseValueAsserter;
-import org.jsmart.zerocode.core.engine.assertion.FieldHasSubStringValueAsserter;
-import org.jsmart.zerocode.core.engine.assertion.FieldIsNotNullAsserter;
-import org.jsmart.zerocode.core.engine.assertion.FieldIsNullAsserter;
-import org.jsmart.zerocode.core.engine.assertion.JsonAsserter;
+import org.jsmart.zerocode.core.engine.assertion.*;
 import org.jsmart.zerocode.core.utils.SmartUtils;
 
 import java.io.IOException;
@@ -78,6 +66,7 @@ public class ZeroCodeJsonTestProcesorImpl implements ZeroCodeJsonTestProcesor {
     public static final String ASSERT_VALUE_EMPTY_ARRAY = "$[]";
     public static final String ASSERT_PATH_SIZE = ".SIZE";
     public static final String ASSERT_VALUE_CONTAINS_STRING = "$CONTAINS.STRING:";
+    public static final String ASSERT_VALUE_MATCHES_STRING = "$MATCHES.STRING:";
     public static final String ASSERT_VALUE_CONTAINS_STRING_IGNORE_CASE = "$CONTAINS.STRING.IGNORECASE:";
     public static final String ASSERT_VALUE_EQUAL_TO_NUMBER = "$EQ.";
     public static final String ASSERT_VALUE_NOT_EQUAL_TO_NUMBER = "$NOT.EQ.";
@@ -217,9 +206,6 @@ public class ZeroCodeJsonTestProcesorImpl implements ZeroCodeJsonTestProcesor {
     @Override
     public List<JsonAsserter> createAssertersFrom(String resolvedAssertionJson) {
         List<JsonAsserter> asserters = new ArrayList<>();
-//        if(parsable resolvedAssertionJson){
-//
-//        }
         try {
             JsonNode jsonNode = mapper.readTree(resolvedAssertionJson);
 
@@ -248,6 +234,10 @@ public class ZeroCodeJsonTestProcesorImpl implements ZeroCodeJsonTestProcesor {
                     String expected = ((String) value).substring(ASSERT_VALUE_CONTAINS_STRING.length());
                     asserter = new FieldHasSubStringValueAsserter(path, expected);
                 }
+                else if (value instanceof String && ((String) value).startsWith(ASSERT_VALUE_MATCHES_STRING)) {
+                    String expected = ((String) value).substring(ASSERT_VALUE_MATCHES_STRING.length());
+                    asserter = new FieldMatchesRegexPatternAsserter(path, expected);
+                }
                 else if (value instanceof String && ((String) value).startsWith(ASSERT_VALUE_CONTAINS_STRING_IGNORE_CASE)) {
                     String expected = ((String) value).substring(ASSERT_VALUE_CONTAINS_STRING_IGNORE_CASE.length());
                     asserter = new FieldHasSubStringIgnoreCaseValueAsserter(path, expected);
@@ -272,10 +262,8 @@ public class ZeroCodeJsonTestProcesorImpl implements ZeroCodeJsonTestProcesor {
                     asserter = new FieldHasExactValueAsserter(path, value);
                 }
 
-                //System.out.println("### Asserter: " + asserter.toString());
                 asserters.add(asserter);
             }
-            //System.out.println("### Asserters size: " + asserters.size());
         } catch (IOException parEx) {
             throw new RuntimeException(parEx);
         }
diff --git a/src/test/java/org/jsmart/zerocode/core/engine/preprocessor/ZeroCodeJsonTestProcesorImplTest.java b/src/test/java/org/jsmart/zerocode/core/engine/preprocessor/ZeroCodeJsonTestProcesorImplTest.java
index a313c74d..5669a772 100644
--- a/src/test/java/org/jsmart/zerocode/core/engine/preprocessor/ZeroCodeJsonTestProcesorImplTest.java
+++ b/src/test/java/org/jsmart/zerocode/core/engine/preprocessor/ZeroCodeJsonTestProcesorImplTest.java
@@ -362,4 +362,93 @@ public class ZeroCodeJsonTestProcesorImplTest {
 
         assertThat(failedReports.size(), is(0));
     }
+
+    @Test
+    public void testString_regexMatch() throws Exception {
+        ScenarioSpec scenarioSpec = smartUtils.jsonFileToJava(
+                "regex_match/string_matches_regex_test.json",
+                ScenarioSpec.class);
+
+        final String assertionsSectionAsString = scenarioSpec.getSteps().get(0).getAssertions().toString();
+        String mockScenarioState = "{}";
+
+        final String resolvedAssertions = jsonPreProcessor.resolveStringJson(assertionsSectionAsString, mockScenarioState);
+        assertThat(resolvedAssertions, containsString("{\"dob\":\"$MATCHES.STRING:\\\\d{4}-\\\\d{2}-\\\\d{2}\"}}"));
+
+        List<JsonAsserter> asserters = jsonPreProcessor.createAssertersFrom(resolvedAssertions);
+        assertThat(asserters.size(), is(2));
+
+        String mockTestResponse = "{\n" +
+                "  \"status\": 201,\n" +
+                "  \"body\": {\n" +
+                "    \"dob\": \"2018-06-26\"\n" +
+                "  }\n" +
+                "}";
+        List<AssertionReport> failedReports = jsonPreProcessor.assertAllAndReturnFailed(asserters, mockTestResponse);
+
+        assertThat(failedReports.size(), is(0));
+    }
+
+    @Test
+    public void testArraySize_numberOnly() throws Exception {
+        ScenarioSpec scenarioSpec = smartUtils.jsonFileToJava(
+                "array_size/array_size_number_only_test.json",
+                ScenarioSpec.class);
+
+        final String assertionsSectionAsString = scenarioSpec.getSteps().get(0).getAssertions().toString();
+        String mockScenarioState = "{}";
+
+        final String resolvedAssertions = jsonPreProcessor.resolveStringJson(assertionsSectionAsString, mockScenarioState);
+        assertThat(resolvedAssertions, containsString("{\"persons.SIZE\":2}"));
+
+        List<JsonAsserter> asserters = jsonPreProcessor.createAssertersFrom(resolvedAssertions);
+        assertThat(asserters.size(), is(2));
+
+        String mockTestResponse = "{\n" +
+                "    \"status\": 201,\n" +
+                "    \"body\": {\n" +
+                "        \"persons\": [\n" +
+                "            {\n" +
+                "                \"name\": \"Tom\"\n" +
+                "            },\n" +
+                "            {\n" +
+                "                \"name\": \"Mady\"\n" +
+                "            }\n" +
+                "        ]\n" +
+                "    }\n" +
+                "}";
+        List<AssertionReport> failedReports = jsonPreProcessor.assertAllAndReturnFailed(asserters, mockTestResponse);
+
+        assertThat(failedReports.size(), is(0));
+    }
+
+    @Test
+    public void testArraySize_numberOnlyNegative() throws Exception {
+        ScenarioSpec scenarioSpec = smartUtils.jsonFileToJava(
+                "array_size/array_size_number_only_test.json",
+                ScenarioSpec.class);
+
+        final String assertionsSectionAsString = scenarioSpec.getSteps().get(0).getAssertions().toString();
+        String mockScenarioState = "{}";
+
+        final String resolvedAssertions = jsonPreProcessor.resolveStringJson(assertionsSectionAsString, mockScenarioState);
+        assertThat(resolvedAssertions, containsString("{\"persons.SIZE\":2}"));
+
+        List<JsonAsserter> asserters = jsonPreProcessor.createAssertersFrom(resolvedAssertions);
+        assertThat(asserters.size(), is(2));
+
+        String mockTestResponse = "{\n" +
+                "    \"status\": 201,\n" +
+                "    \"body\": {\n" +
+                "        \"persons\": [\n" +
+                "            {\n" +
+                "                \"name\": \"Tom\"\n" +
+                "            }\n" +
+                "        ]\n" +
+                "    }\n" +
+                "}";
+        List<AssertionReport> failedReports = jsonPreProcessor.assertAllAndReturnFailed(asserters, mockTestResponse);
+
+        assertThat(failedReports.size(), is(1));
+    }
 }
\ No newline at end of file
diff --git a/src/test/resources/array_size/array_size_number_only_test.json b/src/test/resources/array_size/array_size_number_only_test.json
new file mode 100644
index 00000000..f9164918
--- /dev/null
+++ b/src/test/resources/array_size/array_size_number_only_test.json
@@ -0,0 +1,28 @@
+{
+    "scenarioName": "Array SIZE Number only test",
+    "steps": [
+        {
+            "name": "StepNameWithoutSpaceEgCREATESD",
+            "url": "/persons",
+            "operation": "POST",
+            "request": {
+                "body": {
+                    "persons": [
+                        {
+                            "name": "Tom"
+                        },
+                        {
+                            "name": "Mady"
+                        }
+                    ]
+                }
+            },
+            "assertions": {
+                "status": 201,
+                "body": {
+                    "persons.SIZE": 2
+                }
+            }
+        }
+    ]
+}
diff --git a/src/test/resources/load/github_get_api_sample_test.json b/src/test/resources/load/github_get_api_sample_test.json
index 3cde9827..d0d622a4 100644
--- a/src/test/resources/load/github_get_api_sample_test.json
+++ b/src/test/resources/load/github_get_api_sample_test.json
@@ -12,7 +12,8 @@
                 "body": {
                     "login" : "octocat",
                     "id" : 583231,
-                    "type" : "User"
+                    "type" : "User",
+                    "location" : "$MATCHES.STRING:San Fra(.*)"
                 }
             }
         }
diff --git a/src/test/resources/regex_match/string_matches_regex_test.json b/src/test/resources/regex_match/string_matches_regex_test.json
new file mode 100644
index 00000000..1bab8cb5
--- /dev/null
+++ b/src/test/resources/regex_match/string_matches_regex_test.json
@@ -0,0 +1,23 @@
+{
+    "scenarioName": "Testing string matches a regex pattern",
+    "steps": [
+        {
+            "name": "StepNameWithoutSpaceEgCREATESD",
+            "url": "/persons",
+            "operation": "POST",
+            "request": {
+                "body": {
+                    "persons": {
+                        "dob": "2018-06-26"
+                    }
+                }
+            },
+            "assertions": {
+                "status": 201,
+                "body": {
+                    "dob": "$MATCHES.STRING:\\d{4}-\\d{2}-\\d{2}"
+                }
+            }
+        }
+    ]
+}