summaryrefslogtreecommitdiff
path: root/addons/gut/comparator.gd
blob: b34ef44388e35b112a2b64f00d403b8077c97cc9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
var _utils = load('res://addons/gut/utils.gd').get_instance()
var _strutils = _utils.Strutils.new()
var _max_length = 100
var _should_compare_int_to_float = true

const MISSING = '|__missing__gut__compare__value__|'
const DICTIONARY_DISCLAIMER = 'Dictionaries are compared-by-ref.  See assert_eq in wiki.'

func _cannot_comapre_text(v1, v2):
	return str('Cannot compare ', _strutils.types[typeof(v1)], ' with ',
		_strutils.types[typeof(v2)], '.')

func _make_missing_string(text):
	return '<missing ' + text + '>'

func _create_missing_result(v1, v2, text):
	var to_return = null
	var v1_str = format_value(v1)
	var v2_str = format_value(v2)

	if(typeof(v1) == TYPE_STRING and v1 == MISSING):
		v1_str = _make_missing_string(text)
		to_return = _utils.CompareResult.new()
	elif(typeof(v2) == TYPE_STRING and v2 == MISSING):
		v2_str = _make_missing_string(text)
		to_return = _utils.CompareResult.new()

	if(to_return != null):
		to_return.summary = str(v1_str, ' != ', v2_str)
		to_return.are_equal = false

	return to_return


func simple(v1, v2, missing_string=''):
	var missing_result = _create_missing_result(v1, v2, missing_string)
	if(missing_result != null):
		return missing_result

	var result = _utils.CompareResult.new()
	var cmp_str = null
	var extra = ''

	if(_should_compare_int_to_float and [2, 3].has(typeof(v1)) and [2, 3].has(typeof(v2))):
		result.are_equal = v1 == v2

	elif(_utils.are_datatypes_same(v1, v2)):
		result.are_equal = v1 == v2
		if(typeof(v1) == TYPE_DICTIONARY):
			if(result.are_equal):
				extra = '.  Same dictionary ref.  '
			else:
				extra = '.  Different dictionary refs.  '
			extra += DICTIONARY_DISCLAIMER

		if(typeof(v1) == TYPE_ARRAY):
			var array_result = _utils.DiffTool.new(v1, v2, _utils.DIFF.SHALLOW)
			result.summary = array_result.get_short_summary()
			if(!array_result.are_equal()):
				extra = ".\n" + array_result.get_short_summary()

	else:
		cmp_str = '!='
		result.are_equal = false
		extra = str('.  ', _cannot_comapre_text(v1, v2))

	cmp_str = get_compare_symbol(result.are_equal)
	result.summary = str(format_value(v1), ' ', cmp_str, ' ', format_value(v2), extra)

	return result


func shallow(v1, v2):
	var result =  null

	if(_utils.are_datatypes_same(v1, v2)):
		if(typeof(v1) in [TYPE_ARRAY, TYPE_DICTIONARY]):
			result = _utils.DiffTool.new(v1, v2, _utils.DIFF.SHALLOW)
		else:
			result = simple(v1, v2)
	else:
		result = simple(v1, v2)

	return result


func deep(v1, v2):
	var result =  null

	if(_utils.are_datatypes_same(v1, v2)):
		if(typeof(v1) in [TYPE_ARRAY, TYPE_DICTIONARY]):
			result = _utils.DiffTool.new(v1, v2, _utils.DIFF.DEEP)
		else:
			result = simple(v1, v2)
	else:
		result = simple(v1, v2)

	return result


func format_value(val, max_val_length=_max_length):
	return _strutils.truncate_string(_strutils.type2str(val), max_val_length)


func compare(v1, v2, diff_type=_utils.DIFF.SIMPLE):
	var result = null
	if(diff_type == _utils.DIFF.SIMPLE):
		result = simple(v1, v2)
	elif(diff_type == _utils.DIFF.SHALLOW):
		result = shallow(v1, v2)
	elif(diff_type ==  _utils.DIFF.DEEP):
		result = deep(v1, v2)

	return result


func get_should_compare_int_to_float():
	return _should_compare_int_to_float


func set_should_compare_int_to_float(should_compare_int_float):
	_should_compare_int_to_float = should_compare_int_float


func get_compare_symbol(is_equal):
	if(is_equal):
		return '=='
	else:
		return '!='