summaryrefslogtreecommitdiff
path: root/vendor/github.com/smartystreets/assertions/equal_method.go
blob: c4fc38fab5e77590b2b61d6d1f373448d09ce5ff (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
package assertions

import "reflect"

type equalityMethodSpecification struct {
	a interface{}
	b interface{}

	aType reflect.Type
	bType reflect.Type

	equalMethod reflect.Value
}

func newEqualityMethodSpecification(a, b interface{}) *equalityMethodSpecification {
	return &equalityMethodSpecification{
		a: a,
		b: b,
	}
}

func (this *equalityMethodSpecification) IsSatisfied() bool {
	if !this.bothAreSameType() {
		return false
	}
	if !this.typeHasEqualMethod() {
		return false
	}
	if !this.equalMethodReceivesSameTypeForComparison() {
		return false
	}
	if !this.equalMethodReturnsBool() {
		return false
	}
	return true
}

func (this *equalityMethodSpecification) bothAreSameType() bool {
	this.aType = reflect.TypeOf(this.a)
	if this.aType == nil {
		return false
	}
	if this.aType.Kind() == reflect.Ptr {
		this.aType = this.aType.Elem()
	}
	this.bType = reflect.TypeOf(this.b)
	return this.aType == this.bType
}
func (this *equalityMethodSpecification) typeHasEqualMethod() bool {
	aInstance := reflect.ValueOf(this.a)
	this.equalMethod = aInstance.MethodByName("Equal")
	return this.equalMethod != reflect.Value{}
}

func (this *equalityMethodSpecification) equalMethodReceivesSameTypeForComparison() bool {
	signature := this.equalMethod.Type()
	return signature.NumIn() == 1 && signature.In(0) == this.aType
}

func (this *equalityMethodSpecification) equalMethodReturnsBool() bool {
	signature := this.equalMethod.Type()
	return signature.NumOut() == 1 && signature.Out(0) == reflect.TypeOf(true)
}

func (this *equalityMethodSpecification) AreEqual() bool {
	a := reflect.ValueOf(this.a)
	b := reflect.ValueOf(this.b)
	return areEqual(a, b) && areEqual(b, a)
}
func areEqual(receiver reflect.Value, argument reflect.Value) bool {
	equalMethod := receiver.MethodByName("Equal")
	argumentList := []reflect.Value{argument}
	result := equalMethod.Call(argumentList)
	return result[0].Bool()
}