Skip to content

Commit

Permalink
Adding LHS and RHS accessors to help with walking
Browse files Browse the repository at this point in the history
  • Loading branch information
yazgazan committed Jan 17, 2018
1 parent cbb73bd commit c25d50a
Show file tree
Hide file tree
Showing 7 changed files with 263 additions and 0 deletions.
26 changes: 26 additions & 0 deletions diff/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,32 @@ func IsSlice(d Differ) bool {
return ok
}

type lhsGetter interface {
LHS() interface{}
}

type rhsGetter interface {
RHS() interface{}
}

// LHS returns the lhs value associated with the Differ.
func LHS(d Differ) (interface{}, error) {
if lhs, ok := d.(lhsGetter); ok {
return lhs.LHS(), nil
}

return nil, ErrLHSNotSupported{Diff: d}
}

// RHS returns the rhs value associated with the Differ.
func RHS(d Differ) (interface{}, error) {
if rhs, ok := d.(rhsGetter); ok {
return rhs.RHS(), nil
}

return nil, ErrRHSNotSupported{Diff: d}
}

type visited struct {
lhs []uintptr
rhs []uintptr
Expand Down
168 changes: 168 additions & 0 deletions diff/diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,174 @@ func TestIgnore(t *testing.T) {
}
}

func TestLHS(t *testing.T) {
validLHSTypesGetter := Differ(&types{
lhs: 42,
rhs: "hello",
})
v, err := LHS(validLHSTypesGetter)
if err != nil {
t.Errorf("LHS(%+v): unexpected error: %s", validLHSTypesGetter, err)
}
if i, ok := v.(int); !ok || i != 42 {
t.Errorf("LHS(%+v) = %v, expected %d", validLHSTypesGetter, v, 42)
}

validLHSMapGetter := Differ(&mapDiff{
lhs: 42,
rhs: "hello",
})
v, err = LHS(validLHSMapGetter)
if err != nil {
t.Errorf("LHS(%+v): unexpected error: %s", validLHSMapGetter, err)
}
if i, ok := v.(int); !ok || i != 42 {
t.Errorf("LHS(%+v) = %v, expected %d", validLHSMapGetter, v, 42)
}

validLHSSliceGetter := Differ(&slice{
lhs: 42,
rhs: "hello",
})
v, err = LHS(validLHSSliceGetter)
if err != nil {
t.Errorf("LHS(%+v): unexpected error: %s", validLHSSliceGetter, err)
}
if i, ok := v.(int); !ok || i != 42 {
t.Errorf("LHS(%+v) = %v, expected %d", validLHSSliceGetter, v, 42)
}

validLHSScalarGetter := Differ(&scalar{
lhs: 42,
rhs: "hello",
})
v, err = LHS(validLHSScalarGetter)
if err != nil {
t.Errorf("LHS(%+v): unexpected error: %s", validLHSScalarGetter, err)
}
if i, ok := v.(int); !ok || i != 42 {
t.Errorf("LHS(%+v) = %v, expected %d", validLHSScalarGetter, v, 42)
}

validLHSSliceMissingGetter := Differ(&sliceMissing{
value: 42,
})
v, err = LHS(validLHSSliceMissingGetter)
if err != nil {
t.Errorf("LHS(%+v): unexpected error: %s", validLHSSliceMissingGetter, err)
}
if i, ok := v.(int); !ok || i != 42 {
t.Errorf("LHS(%+v) = %v, expected %d", validLHSSliceMissingGetter, v, 42)
}

validLHSMapMissingGetter := Differ(&mapMissing{
value: 42,
})
v, err = LHS(validLHSMapMissingGetter)
if err != nil {
t.Errorf("LHS(%+v): unexpected error: %s", validLHSMapMissingGetter, err)
}
if i, ok := v.(int); !ok || i != 42 {
t.Errorf("LHS(%+v) = %v, expected %d", validLHSMapMissingGetter, v, 42)
}

invalidLHSGetter := ignore{}
_, err = LHS(invalidLHSGetter)
if err == nil {
t.Errorf("LHS(%+v): expected error, got nil instead", invalidLHSGetter)
}
if _, ok := err.(ErrLHSNotSupported); !ok {
t.Errorf("LHS(%+v): expected error to be of type %T, got %T instead", invalidLHSGetter, ErrLHSNotSupported{}, err)
}
if err.Error() == "" {
t.Errorf("LHS(%+v): unexpected empty error message")
}
}

func TestRHS(t *testing.T) {
validRHSTypesGetter := Differ(&types{
lhs: 42,
rhs: "hello",
})
v, err := RHS(validRHSTypesGetter)
if err != nil {
t.Errorf("RHS(%+v): unexpected error: %s", validRHSTypesGetter, err)
}
if s, ok := v.(string); !ok || s != "hello" {
t.Errorf("RHS(%+v) = %v, expected %q", validRHSTypesGetter, v, "hello")
}

validRHSMapGetter := Differ(&mapDiff{
lhs: 42,
rhs: "hello",
})
v, err = RHS(validRHSMapGetter)
if err != nil {
t.Errorf("RHS(%+v): unexpected error: %s", validRHSMapGetter, err)
}
if s, ok := v.(string); !ok || s != "hello" {
t.Errorf("RHS(%+v) = %v, expected %q", validRHSMapGetter, v, "hello")
}

validRHSSliceGetter := Differ(&slice{
lhs: 42,
rhs: "hello",
})
v, err = RHS(validRHSSliceGetter)
if err != nil {
t.Errorf("RHS(%+v): unexpected error: %s", validRHSSliceGetter, err)
}
if s, ok := v.(string); !ok || s != "hello" {
t.Errorf("RHS(%+v) = %v, expected %q", validRHSSliceGetter, v, "hello")
}

validRHSScalarGetter := Differ(&scalar{
lhs: 42,
rhs: "hello",
})
v, err = RHS(validRHSScalarGetter)
if err != nil {
t.Errorf("RHS(%+v): unexpected error: %s", validRHSScalarGetter, err)
}
if s, ok := v.(string); !ok || s != "hello" {
t.Errorf("RHS(%+v) = %v, expected %q", validRHSScalarGetter, v, "hello")
}

validRHSSliceExcessGetter := Differ(&sliceExcess{
value: "hello",
})
v, err = RHS(validRHSSliceExcessGetter)
if err != nil {
t.Errorf("RHS(%+v): unexpected error: %s", validRHSSliceExcessGetter, err)
}
if s, ok := v.(string); !ok || s != "hello" {
t.Errorf("RHS(%+v) = %v, expected %q", validRHSSliceExcessGetter, v, "hello")
}

validRHSMapExcessGetter := Differ(&mapExcess{
value: "hello",
})
v, err = RHS(validRHSMapExcessGetter)
if err != nil {
t.Errorf("RHS(%+v): unexpected error: %s", validRHSMapExcessGetter, err)
}
if s, ok := v.(string); !ok || s != "hello" {
t.Errorf("RHS(%+v) = %v, expected %q", validRHSMapExcessGetter, v, "hello")
}

invalidRHSGetter := ignore{}
_, err = RHS(invalidRHSGetter)
if err == nil {
t.Errorf("RHS(%+v): expected error, got nil instead", invalidRHSGetter)
}
if _, ok := err.(ErrRHSNotSupported); !ok {
t.Errorf("RHS(%+v): expected error to be of type %T, got %T instead", invalidRHSGetter, ErrLHSNotSupported{}, err)
}
if err.Error() == "" {
t.Errorf("RHS(%+v): unexpected empty error message")
}
}

func TestReport(t *testing.T) {
want := []string{
"content",
Expand Down
20 changes: 20 additions & 0 deletions diff/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,25 @@ func (e errInvalidType) Error() string {
return fmt.Sprintf("%T is not a valid type for %s", e.Value, e.For)
}

// ErrLHSNotSupported is returned when calling diff.LHS on a Differ that does not contain
// an LHS value (i.e Ignore)
type ErrLHSNotSupported struct {
Diff Differ
}

func (e ErrLHSNotSupported) Error() string {
return fmt.Sprintf("%T does not contain an LHS value", e.Diff)
}

// ErrRHSNotSupported is returned when calling diff.EHS on a Differ that does not contain
// an RHS value (i.e Ignore)
type ErrRHSNotSupported struct {
Diff Differ
}

func (e ErrRHSNotSupported) Error() string {
return fmt.Sprintf("%T does not contain an RHS value", e.Diff)
}

// ErrCyclic is returned when one of the compared values contain circular references
var ErrCyclic = errors.New("circular references not supported")
17 changes: 17 additions & 0 deletions diff/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,15 @@ func (m mapDiff) Walk(path string, fn WalkFn) error {

return nil
}

func (m mapDiff) LHS() interface{} {
return m.lhs
}

func (m mapDiff) RHS() interface{} {
return m.rhs
}

func getKeys(lhs, rhs reflect.Value) []reflect.Value {
keys := lhs.MapKeys()

Expand Down Expand Up @@ -236,6 +245,10 @@ func (m mapMissing) StringIndent(key, prefix string, conf Output) string {
return "-" + prefix + key + conf.red(m.value)
}

func (m mapMissing) LHS() interface{} {
return m.value
}

func (e mapExcess) Diff() Type {
return ContentDiffer
}
Expand All @@ -249,3 +262,7 @@ func (e mapExcess) Strings() []string {
func (e mapExcess) StringIndent(key, prefix string, conf Output) string {
return "+" + prefix + key + conf.green(e.value)
}

func (e mapExcess) RHS() interface{} {
return e.value
}
8 changes: 8 additions & 0 deletions diff/scalar.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,11 @@ func (s scalar) StringIndent(key, prefix string, conf Output) string {
return "-" + prefix + key + conf.red(s.lhs) + "\n" +
"+" + prefix + key + conf.green(s.rhs)
}

func (s scalar) LHS() interface{} {
return s.lhs
}

func (s scalar) RHS() interface{} {
return s.rhs
}
16 changes: 16 additions & 0 deletions diff/slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,14 @@ func (s slice) Walk(path string, fn WalkFn) error {
return nil
}

func (s slice) LHS() interface{} {
return s.lhs
}

func (s slice) RHS() interface{} {
return s.rhs
}

func (m sliceMissing) Diff() Type {
return ContentDiffer
}
Expand All @@ -259,6 +267,10 @@ func (m sliceMissing) StringIndent(key, prefix string, conf Output) string {
return "-" + prefix + key + conf.red(m.value)
}

func (m sliceMissing) LHS() interface{} {
return m.value
}

func (e sliceExcess) Diff() Type {
return ContentDiffer
}
Expand All @@ -272,3 +284,7 @@ func (e sliceExcess) Strings() []string {
func (e sliceExcess) StringIndent(key, prefix string, conf Output) string {
return "+" + prefix + key + conf.green(e.value)
}

func (e sliceExcess) RHS() interface{} {
return e.value
}
8 changes: 8 additions & 0 deletions diff/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,11 @@ func (t types) StringIndent(key, prefix string, conf Output) string {
return "-" + prefix + key + conf.red(t.lhs) + "\n" +
"+" + prefix + key + conf.green(t.rhs)
}

func (t types) LHS() interface{} {
return t.lhs
}

func (t types) RHS() interface{} {
return t.rhs
}

0 comments on commit c25d50a

Please sign in to comment.