예제 #1
0
    def compare(cls, expected, actual, type_compare=None):
        if type_compare is None:
            type_compare = {}
        elif isinstance(type_compare, str):
            type_compare = {"hash": type_compare, "ordered": True}
        default_type_compare = {"hash": "full", "ordered": True}
        type_compare = combine(default_type_compare, type_compare)

        if type(expected) == DontCare:
            if expected.compare_with(actual):
                return "match"
            else:
                return ("dontcare: %s" % expected.rule, actual)
        elif type(expected) == re._pattern_type and isinstance(actual, six.string_types):
            match = expected.match(actual)
            if match:
                return "match"
            else:
                return ("regex: %s" % expected.pattern, actual)
        elif type(expected).__name__ == "ParsingHint":
            return cls.compare(expected.payload, expected.parse(actual), type_compare)
        elif acts_like_a_hash(expected) and acts_like_a_hash(actual):
            return cls.hash_compare(expected, actual, type_compare)
        elif isinstance(expected, tuple) and isinstance(actual, tuple):
            return cls.list_compare(expected, actual, type_compare, iter_type=tuple)
        elif acts_like_a_list(expected) and acts_like_a_list(actual):
            return cls.list_compare(expected, actual, type_compare, iter_type=list)

        else:
            if expected == actual:
                return "match"
            else:
                return (expected, actual)
예제 #2
0
    def hash_compare(cls,
                     expected,
                     actual,
                     type_compare={}):
        default_type_compare =\
            {'hash' : 'full',
             'dontcare_keys' : [],
             'ordered' : True}
        type_compare =\
            combine(default_type_compare, type_compare)
        if '__compare' in expected:
            compare_override = expected['__compare']
            if acts_like_a_hash(compare_override):
                type_compare = combine(default_type_compare, compare_override)
            else:
                type_compare['hash'] = compare_override
            expected = dict((k, v) for (k, v) in expected.items() if k != '__compare')

        expected_return = {}
        actual_return = {}

        if type_compare['hash'] == 'full':
            keys = set([])
            keys.update(expected.keys())
            keys.update(actual.keys())
        else:
            keys = set(expected.keys())

        for key in keys:
            if key in type_compare['dontcare_keys']:
                result = cls.compare(DontCare(), 
                                     actual.get(key, NotPresent),
                                     type_compare)
            else:
                result = cls.compare(expected.get(key, NotPresent),
                                     actual.get(key, NotPresent),
                                     type_compare)

            if result != 'match':
                expected_sub, actual_sub = result
                expected_return[key] = expected_sub
                actual_return[key] = actual_sub

        if len(expected_return) == 0:
            return 'match'
        else:
            return (expected_return, actual_return)
예제 #3
0
    def hash_compare(cls, expected, actual, type_compare={}):
        default_type_compare = {"hash": "full", "dontcare_keys": [], "ordered": True}
        type_compare = combine(default_type_compare, type_compare)
        if "__compare" in expected:
            compare_override = expected["__compare"]
            if acts_like_a_hash(compare_override):
                type_compare = combine(default_type_compare, compare_override)
            else:
                type_compare["hash"] = compare_override
            expected = dict((k, v) for (k, v) in expected.items() if k != "__compare")

        expected_return = {}
        actual_return = {}

        if type_compare["hash"] == "full":
            keys = set([])
            keys.update(expected.keys())
            keys.update(actual.keys())
        else:
            keys = set(expected.keys())

        for key in keys:
            if key in type_compare["dontcare_keys"]:
                result = cls.compare(DontCare(), actual.get(key, NotPresent), type_compare)
            else:
                result = cls.compare(expected.get(key, NotPresent), actual.get(key, NotPresent), type_compare)

            if result != "match":
                expected_sub, actual_sub = result
                expected_return[key] = expected_sub
                actual_return[key] = actual_sub

        if len(expected_return) == 0:
            return "match"
        else:
            return (expected_return, actual_return)
예제 #4
0
    def list_compare(cls, expected, actual, type_compare, iter_type=list):
        default_type_compare = {"hash": "full", "ordered": True}

        type_compare = combine(default_type_compare, type_compare)

        if type(expected) == set and type(actual) == set:
            isset = True
            expected = list(expected)
            actual = list(actual)
        else:
            isset = False

        if type_compare["ordered"] and not isset:
            ret = cls.ordered_list_compare(expected, actual, type_compare, iter_type=iter_type)
        else:
            ret = cls.unordered_list_compare(expected, actual, type_compare, iter_type=iter_type)
        if ret == "match" or not isset:
            return ret
        else:
            ret_exp, ret_act = ret
            ret_exp = [x for x in ret_exp if x != "_"]
            ret_act = [x for x in ret_act if x != "_"]
            return (set(ret_exp), set(ret_act))
예제 #5
0
    def list_compare(cls,
                     expected,
                     actual,
                     type_compare,
                     iter_type=list):
        default_type_compare =\
            {'hash' : 'full',
             'ordered' : True}

        type_compare =\
            combine(default_type_compare, type_compare)

        if type(expected) == set and type(actual) == set:
            isset = True
            expected = list(expected)
            actual = list(actual)
        else:
            isset = False

        if type_compare['ordered'] and not isset:
            ret = cls.ordered_list_compare(expected,
                                           actual,
                                           type_compare,
                                           iter_type=iter_type)
        else:
            ret = cls.unordered_list_compare(expected,
                                             actual,
                                             type_compare,
                                             iter_type=iter_type)
        if ret == 'match' or not isset:
            return ret
        else:
            ret_exp, ret_act = ret
            ret_exp = [x for x in ret_exp if x != '_']
            ret_act = [x for x in ret_act if x != '_']
            return (set(ret_exp), set(ret_act))
예제 #6
0
    def compare(cls,
                expected,
                actual,
                type_compare=None):
        '''
        Compare two arguments against each other.  If they are 
        dicts or lists, recursively compare their components.
        Return the difference.  If there is no difference, return the string
        'match'.  

        The third, optional argument is type_compare, which gives compare
        some information about how it should do matching.  The value may
        be either a string or a dictionary.  If it is a dictionary,
        the two keys are "hash" and "ordered".  If type_compare is a 
        string, the value is treated as the value for "hash".  

        The hash key may either be "full" or "existing".  Full means that
        two dictionaries must match entirely.  Existing means that only
        the keys in the first dictionary must match in the second
        dictionary (ie. the keys that are only in the second dictionary
        are ignored).

        The ordered key may be either True or False.  If it is True,
        lists that are compared against each other are expected
        to be ordered the same way.  If it is False, lists that are
        compared against each other are expected to have the same
        elements, but in any order.

        hash defaults to "full", and ordered defaults to True.

        The hash comparison mode may be overridden in a sub-hash, 
        by specifying a special key "__compare".  The mode names
        are the same - "full" and "existing"
        '''

        if type_compare is None:
            type_compare = {}
        elif isinstance(type_compare, str):
            type_compare = {'hash' : type_compare,
                            'ordered' : True}
        default_type_compare = {'hash' : 'full',
                                'ordered' : True}
        type_compare =\
            combine(default_type_compare, type_compare)

        if type(expected) == DontCare:
            if expected.compare_with(actual):
                return 'match'
            else:
                return ("dontcare: %s" % expected.rule,
                        actual)
        elif (type(expected) == pattern_type and 
              isinstance(actual, six.string_types)):
            match = expected.match(actual)
            if match:
                return 'match'
            else:
                return ('regex: %s' % expected.pattern, actual)
        elif (type(expected).__name__ == 'ParsingHint'):
            return cls.compare(
                    expected.payload,
                    expected.parse(actual),
                    type_compare)
        elif (acts_like_a_hash(expected) and 
              acts_like_a_hash(actual)):
            return cls.hash_compare(expected, 
                                    actual, 
                                    type_compare)
        elif (isinstance(expected, tuple) and isinstance(actual, tuple)):
            return cls.list_compare(expected,
                                    actual,
                                    type_compare,
                                    iter_type=tuple)
        elif (acts_like_a_list(expected) and 
              acts_like_a_list(actual)):
            return cls.list_compare(expected, 
                                    actual,
                                    type_compare,
                                    iter_type=list)

        else:
            if expected == actual:
                return 'match'
            else:
                return (expected, actual)