()
| 2007 | } |
| 2008 | |
| 2009 | func methodTests() []test { |
| 2010 | const label = "EqualMethod" |
| 2011 | |
| 2012 | // A common mistake that the Equal method is on a pointer receiver, |
| 2013 | // but only a non-pointer value is present in the struct. |
| 2014 | // A transform can be used to forcibly reference the value. |
| 2015 | addrTransform := cmp.FilterPath(func(p cmp.Path) bool { |
| 2016 | if len(p) == 0 { |
| 2017 | return false |
| 2018 | } |
| 2019 | t := p[len(p)-1].Type() |
| 2020 | if _, ok := t.MethodByName("Equal"); ok || t.Kind() == reflect.Ptr { |
| 2021 | return false |
| 2022 | } |
| 2023 | if m, ok := reflect.PtrTo(t).MethodByName("Equal"); ok { |
| 2024 | tf := m.Func.Type() |
| 2025 | return !tf.IsVariadic() && tf.NumIn() == 2 && tf.NumOut() == 1 && |
| 2026 | tf.In(0).AssignableTo(tf.In(1)) && tf.Out(0) == reflect.TypeOf(true) |
| 2027 | } |
| 2028 | return false |
| 2029 | }, cmp.Transformer("Addr", func(x interface{}) interface{} { |
| 2030 | v := reflect.ValueOf(x) |
| 2031 | vp := reflect.New(v.Type()) |
| 2032 | vp.Elem().Set(v) |
| 2033 | return vp.Interface() |
| 2034 | })) |
| 2035 | |
| 2036 | // For each of these types, there is an Equal method defined, which always |
| 2037 | // returns true, while the underlying data are fundamentally different. |
| 2038 | // Since the method should be called, these are expected to be equal. |
| 2039 | return []test{{ |
| 2040 | label: label + "/StructA/ValueEqual", |
| 2041 | x: ts.StructA{X: "NotEqual"}, |
| 2042 | y: ts.StructA{X: "not_equal"}, |
| 2043 | wantEqual: true, |
| 2044 | reason: "Equal method on StructA value called", |
| 2045 | }, { |
| 2046 | label: label + "/StructA/PointerEqual", |
| 2047 | x: &ts.StructA{X: "NotEqual"}, |
| 2048 | y: &ts.StructA{X: "not_equal"}, |
| 2049 | wantEqual: true, |
| 2050 | reason: "Equal method on StructA pointer called", |
| 2051 | }, { |
| 2052 | label: label + "/StructB/ValueInequal", |
| 2053 | x: ts.StructB{X: "NotEqual"}, |
| 2054 | y: ts.StructB{X: "not_equal"}, |
| 2055 | wantEqual: false, |
| 2056 | reason: "Equal method on StructB value not called", |
| 2057 | }, { |
| 2058 | label: label + "/StructB/ValueAddrEqual", |
| 2059 | x: ts.StructB{X: "NotEqual"}, |
| 2060 | y: ts.StructB{X: "not_equal"}, |
| 2061 | opts: []cmp.Option{addrTransform}, |
| 2062 | wantEqual: true, |
| 2063 | reason: "Equal method on StructB pointer called due to shallow copy transform", |
| 2064 | }, { |
| 2065 | label: label + "/StructB/PointerEqual", |
| 2066 | x: &ts.StructB{X: "NotEqual"}, |
no test coverage detected
searching dependent graphs…