Class ArrayValueMatcher<T>

  • All Implemented Interfaces:
    LocationAwareValueMatcher<T>, ValueMatcher<T>

    public class ArrayValueMatcher<T>
    extends Object
    implements LocationAwareValueMatcher<T>

    A value matcher for arrays. This operates like STRICT_ORDER array match, however if expected array has less elements than actual array the matching process loops through the expected array to get expected elements for the additional actual elements. In general the expected array will contain a single element which is matched against each actual array element in turn. This allows simple verification of constant array element components and coupled with RegularExpressionValueMatcher can be used to match specific array element components against a regular expression pattern. As a convenience to reduce syntactic complexity of expected string, if the expected object is not an array, a one element expected array is created containing whatever is provided as the expected value.

    Some examples of typical usage idioms listed below.

    Assuming JSON to be verified is held in String variable ARRAY_OF_JSONOBJECTS and contains:

    
     {a:[{background:white, id:1, type:row},
         {background:grey,  id:2, type:row},
         {background:white, id:3, type:row},
         {background:grey,  id:4, type:row}]}
     

    then:

    To verify that the 'id' attribute of first element of array 'a' is '1':

    
     JSONComparator comparator = new DefaultComparator(JSONCompareMode.LENIENT);
     Customization customization = new Customization("a", new ArrayValueMatcher<Object>(comparator, 0));
     JSONAssert.assertEquals("{a:[{id:1}]}", ARRAY_OF_JSONOBJECTS,
         new CustomComparator(JSONCompareMode.LENIENT, customization));
     

    To simplify complexity of expected JSON string, the value "a:[{id:1}]}" may be replaced by "a:{id:1}}"

    To verify that the 'type' attribute of second and third elements of array 'a' is 'row':

    
     JSONComparator comparator = new DefaultComparator(JSONCompareMode.LENIENT);
     Customization customization = new Customization("a", new ArrayValueMatcher<Object>(comparator, 1, 2));
     JSONAssert.assertEquals("{a:[{type:row}]}", ARRAY_OF_JSONOBJECTS,
         new CustomComparator(JSONCompareMode.LENIENT, customization));
     

    To verify that the 'type' attribute of every element of array 'a' is 'row':

    
     JSONComparator comparator = new DefaultComparator(JSONCompareMode.LENIENT);
     Customization customization = new Customization("a", new ArrayValueMatcher<Object>(comparator));
     JSONAssert.assertEquals("{a:[{type:row}]}", ARRAY_OF_JSONOBJECTS,
         new CustomComparator(JSONCompareMode.LENIENT, customization));
     

    To verify that the 'id' attribute of every element of array 'a' matches regular expression '\d+'. This requires a custom comparator to specify regular expression to be used to validate each array element, hence the array of Customization instances:

    
     // get length of array we will verify
     int aLength = ((JSONArray)((JSONObject)JSONParser.parseJSON(ARRAY_OF_JSONOBJECTS)).get("a")).length();
     // create array of customizations one for each array element
     RegularExpressionValueMatcher<Object> regExValueMatcher =
         new RegularExpressionValueMatcher<Object>("\\d+");  // matches one or more digits
     Customization[] customizations = new Customization[aLength];
     for (int i=0; i<aLength; i++) {
         String contextPath = "a["+i+"].id";
         customizations[i] = new Customization(contextPath, regExValueMatcher);
     }
     CustomComparator regExComparator = new CustomComparator(JSONCompareMode.STRICT_ORDER, customizations);
     ArrayValueMatcher<Object> regExArrayValueMatcher = new ArrayValueMatcher<Object>(regExComparator);
     Customization regExArrayValueCustomization = new Customization("a", regExArrayValueMatcher);
     CustomComparator regExCustomArrayValueComparator =
         new CustomComparator(JSONCompareMode.STRICT_ORDER, new Customization[] { regExArrayValueCustomization });
     JSONAssert.assertEquals("{a:[{id:X}]}", ARRAY_OF_JSONOBJECTS, regExCustomArrayValueComparator);
     

    To verify that the 'background' attribute of every element of array 'a' alternates between 'white' and 'grey' starting with first element 'background' being 'white':

    
     JSONComparator comparator = new DefaultComparator(JSONCompareMode.LENIENT);
     Customization customization = new Customization("a", new ArrayValueMatcher<Object>(comparator));
     JSONAssert.assertEquals("{a:[{background:white},{background:grey}]}", ARRAY_OF_JSONOBJECTS,
         new CustomComparator(JSONCompareMode.LENIENT, customization));
     

    Assuming JSON to be verified is held in String variable ARRAY_OF_JSONARRAYS and contains:

    {a:[[6,7,8], [9,10,11], [12,13,14], [19,20,21,22]]}

    then:

    To verify that the first three elements of JSON array 'a' are JSON arrays of length 3:

    
     JSONComparator comparator = new ArraySizeComparator(JSONCompareMode.STRICT_ORDER);
     Customization customization = new Customization("a", new ArrayValueMatcher<Object>(comparator, 0, 2));
     JSONAssert.assertEquals("{a:[[3]]}", ARRAY_OF_JSONARRAYS, new CustomComparator(JSONCompareMode.LENIENT, customization));
     

    NOTE: simplified expected JSON strings are not possible in this case as ArraySizeComparator does not support them.

    To verify that the second elements of JSON array 'a' is a JSON array whose first element has the value 9:

    
     JSONComparator innerComparator = new DefaultComparator(JSONCompareMode.LENIENT);
     Customization innerCustomization = new Customization("a[1]", new ArrayValueMatcher<Object>(innerComparator, 0));
     JSONComparator comparator = new CustomComparator(JSONCompareMode.LENIENT, innerCustomization);
     Customization customization = new Customization("a", new ArrayValueMatcher<Object>(comparator, 1));
     JSONAssert.assertEquals("{a:[[9]]}", ARRAY_OF_JSONARRAYS, new CustomComparator(JSONCompareMode.LENIENT, customization));
     

    To simplify complexity of expected JSON string, the value "{a:[[9]]}" may be replaced by "{a:[9]}" or "{a:9}"

    Author:
    Duncan Mackinder
    • Constructor Detail

      • ArrayValueMatcher

        public ArrayValueMatcher​(JSONComparator comparator)
        Create ArrayValueMatcher to match every element in actual array against elements taken in sequence from expected array, repeating from start of expected array if necessary.
        Parameters:
        comparator - comparator to use to compare elements
      • ArrayValueMatcher

        public ArrayValueMatcher​(JSONComparator comparator,
                                 int index)
        Create ArrayValueMatcher to match specified element in actual array against first element of expected array.
        Parameters:
        comparator - comparator to use to compare elements
        index - index of the array element to be compared
      • ArrayValueMatcher

        public ArrayValueMatcher​(JSONComparator comparator,
                                 int from,
                                 int to)
        Create ArrayValueMatcher to match every element in specified range (inclusive) from actual array against elements taken in sequence from expected array, repeating from start of expected array if necessary.
        Parameters:
        comparator - comparator to use to compare elements
        from - first element in actual array to compared
        to - last element in actual array to compared
    • Method Detail

      • equal

        public boolean equal​(T o1,
                             T o2)
        Description copied from interface: ValueMatcher
        Compares the two provided objects whether they are equal.
        Specified by:
        equal in interface ValueMatcher<T>
        Parameters:
        o1 - the first object to check
        o2 - the object to check the first against
        Returns:
        true if the objects are equal, false otherwise
      • equal

        public boolean equal​(String prefix,
                             T actual,
                             T expected,
                             JSONCompareResult result)
        Description copied from interface: LocationAwareValueMatcher
        Match actual value with expected value. If match fails any of the following may occur, return false, pass failure details to specified JSONCompareResult and return true, or throw ValueMatcherException containing failure details. Passing failure details to JSONCompareResult or returning via ValueMatcherException enables more useful failure description for cases where expected value depends entirely or in part on configuration of the ValueMatcher and therefore expected value passed to this method will not give a useful indication of expected value.
        Specified by:
        equal in interface LocationAwareValueMatcher<T>
        Parameters:
        prefix - JSON path of the JSON item being tested
        actual - JSON value being tested
        expected - expected JSON value
        result - JSONCompareResult to which match failure may be passed
        Returns:
        true if expected and actual equal or any difference has already been passed to specified result instance, false otherwise.