Skip to content

Commit c25d50a

Browse files
committed
Adding LHS and RHS accessors to help with walking
1 parent cbb73bd commit c25d50a

File tree

7 files changed

+263
-0
lines changed

7 files changed

+263
-0
lines changed

diff/diff.go

+26
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,32 @@ func IsSlice(d Differ) bool {
152152
return ok
153153
}
154154

155+
type lhsGetter interface {
156+
LHS() interface{}
157+
}
158+
159+
type rhsGetter interface {
160+
RHS() interface{}
161+
}
162+
163+
// LHS returns the lhs value associated with the Differ.
164+
func LHS(d Differ) (interface{}, error) {
165+
if lhs, ok := d.(lhsGetter); ok {
166+
return lhs.LHS(), nil
167+
}
168+
169+
return nil, ErrLHSNotSupported{Diff: d}
170+
}
171+
172+
// RHS returns the rhs value associated with the Differ.
173+
func RHS(d Differ) (interface{}, error) {
174+
if rhs, ok := d.(rhsGetter); ok {
175+
return rhs.RHS(), nil
176+
}
177+
178+
return nil, ErrRHSNotSupported{Diff: d}
179+
}
180+
155181
type visited struct {
156182
lhs []uintptr
157183
rhs []uintptr

diff/diff_test.go

+168
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,174 @@ func TestIgnore(t *testing.T) {
617617
}
618618
}
619619

620+
func TestLHS(t *testing.T) {
621+
validLHSTypesGetter := Differ(&types{
622+
lhs: 42,
623+
rhs: "hello",
624+
})
625+
v, err := LHS(validLHSTypesGetter)
626+
if err != nil {
627+
t.Errorf("LHS(%+v): unexpected error: %s", validLHSTypesGetter, err)
628+
}
629+
if i, ok := v.(int); !ok || i != 42 {
630+
t.Errorf("LHS(%+v) = %v, expected %d", validLHSTypesGetter, v, 42)
631+
}
632+
633+
validLHSMapGetter := Differ(&mapDiff{
634+
lhs: 42,
635+
rhs: "hello",
636+
})
637+
v, err = LHS(validLHSMapGetter)
638+
if err != nil {
639+
t.Errorf("LHS(%+v): unexpected error: %s", validLHSMapGetter, err)
640+
}
641+
if i, ok := v.(int); !ok || i != 42 {
642+
t.Errorf("LHS(%+v) = %v, expected %d", validLHSMapGetter, v, 42)
643+
}
644+
645+
validLHSSliceGetter := Differ(&slice{
646+
lhs: 42,
647+
rhs: "hello",
648+
})
649+
v, err = LHS(validLHSSliceGetter)
650+
if err != nil {
651+
t.Errorf("LHS(%+v): unexpected error: %s", validLHSSliceGetter, err)
652+
}
653+
if i, ok := v.(int); !ok || i != 42 {
654+
t.Errorf("LHS(%+v) = %v, expected %d", validLHSSliceGetter, v, 42)
655+
}
656+
657+
validLHSScalarGetter := Differ(&scalar{
658+
lhs: 42,
659+
rhs: "hello",
660+
})
661+
v, err = LHS(validLHSScalarGetter)
662+
if err != nil {
663+
t.Errorf("LHS(%+v): unexpected error: %s", validLHSScalarGetter, err)
664+
}
665+
if i, ok := v.(int); !ok || i != 42 {
666+
t.Errorf("LHS(%+v) = %v, expected %d", validLHSScalarGetter, v, 42)
667+
}
668+
669+
validLHSSliceMissingGetter := Differ(&sliceMissing{
670+
value: 42,
671+
})
672+
v, err = LHS(validLHSSliceMissingGetter)
673+
if err != nil {
674+
t.Errorf("LHS(%+v): unexpected error: %s", validLHSSliceMissingGetter, err)
675+
}
676+
if i, ok := v.(int); !ok || i != 42 {
677+
t.Errorf("LHS(%+v) = %v, expected %d", validLHSSliceMissingGetter, v, 42)
678+
}
679+
680+
validLHSMapMissingGetter := Differ(&mapMissing{
681+
value: 42,
682+
})
683+
v, err = LHS(validLHSMapMissingGetter)
684+
if err != nil {
685+
t.Errorf("LHS(%+v): unexpected error: %s", validLHSMapMissingGetter, err)
686+
}
687+
if i, ok := v.(int); !ok || i != 42 {
688+
t.Errorf("LHS(%+v) = %v, expected %d", validLHSMapMissingGetter, v, 42)
689+
}
690+
691+
invalidLHSGetter := ignore{}
692+
_, err = LHS(invalidLHSGetter)
693+
if err == nil {
694+
t.Errorf("LHS(%+v): expected error, got nil instead", invalidLHSGetter)
695+
}
696+
if _, ok := err.(ErrLHSNotSupported); !ok {
697+
t.Errorf("LHS(%+v): expected error to be of type %T, got %T instead", invalidLHSGetter, ErrLHSNotSupported{}, err)
698+
}
699+
if err.Error() == "" {
700+
t.Errorf("LHS(%+v): unexpected empty error message")
701+
}
702+
}
703+
704+
func TestRHS(t *testing.T) {
705+
validRHSTypesGetter := Differ(&types{
706+
lhs: 42,
707+
rhs: "hello",
708+
})
709+
v, err := RHS(validRHSTypesGetter)
710+
if err != nil {
711+
t.Errorf("RHS(%+v): unexpected error: %s", validRHSTypesGetter, err)
712+
}
713+
if s, ok := v.(string); !ok || s != "hello" {
714+
t.Errorf("RHS(%+v) = %v, expected %q", validRHSTypesGetter, v, "hello")
715+
}
716+
717+
validRHSMapGetter := Differ(&mapDiff{
718+
lhs: 42,
719+
rhs: "hello",
720+
})
721+
v, err = RHS(validRHSMapGetter)
722+
if err != nil {
723+
t.Errorf("RHS(%+v): unexpected error: %s", validRHSMapGetter, err)
724+
}
725+
if s, ok := v.(string); !ok || s != "hello" {
726+
t.Errorf("RHS(%+v) = %v, expected %q", validRHSMapGetter, v, "hello")
727+
}
728+
729+
validRHSSliceGetter := Differ(&slice{
730+
lhs: 42,
731+
rhs: "hello",
732+
})
733+
v, err = RHS(validRHSSliceGetter)
734+
if err != nil {
735+
t.Errorf("RHS(%+v): unexpected error: %s", validRHSSliceGetter, err)
736+
}
737+
if s, ok := v.(string); !ok || s != "hello" {
738+
t.Errorf("RHS(%+v) = %v, expected %q", validRHSSliceGetter, v, "hello")
739+
}
740+
741+
validRHSScalarGetter := Differ(&scalar{
742+
lhs: 42,
743+
rhs: "hello",
744+
})
745+
v, err = RHS(validRHSScalarGetter)
746+
if err != nil {
747+
t.Errorf("RHS(%+v): unexpected error: %s", validRHSScalarGetter, err)
748+
}
749+
if s, ok := v.(string); !ok || s != "hello" {
750+
t.Errorf("RHS(%+v) = %v, expected %q", validRHSScalarGetter, v, "hello")
751+
}
752+
753+
validRHSSliceExcessGetter := Differ(&sliceExcess{
754+
value: "hello",
755+
})
756+
v, err = RHS(validRHSSliceExcessGetter)
757+
if err != nil {
758+
t.Errorf("RHS(%+v): unexpected error: %s", validRHSSliceExcessGetter, err)
759+
}
760+
if s, ok := v.(string); !ok || s != "hello" {
761+
t.Errorf("RHS(%+v) = %v, expected %q", validRHSSliceExcessGetter, v, "hello")
762+
}
763+
764+
validRHSMapExcessGetter := Differ(&mapExcess{
765+
value: "hello",
766+
})
767+
v, err = RHS(validRHSMapExcessGetter)
768+
if err != nil {
769+
t.Errorf("RHS(%+v): unexpected error: %s", validRHSMapExcessGetter, err)
770+
}
771+
if s, ok := v.(string); !ok || s != "hello" {
772+
t.Errorf("RHS(%+v) = %v, expected %q", validRHSMapExcessGetter, v, "hello")
773+
}
774+
775+
invalidRHSGetter := ignore{}
776+
_, err = RHS(invalidRHSGetter)
777+
if err == nil {
778+
t.Errorf("RHS(%+v): expected error, got nil instead", invalidRHSGetter)
779+
}
780+
if _, ok := err.(ErrRHSNotSupported); !ok {
781+
t.Errorf("RHS(%+v): expected error to be of type %T, got %T instead", invalidRHSGetter, ErrLHSNotSupported{}, err)
782+
}
783+
if err.Error() == "" {
784+
t.Errorf("RHS(%+v): unexpected empty error message")
785+
}
786+
}
787+
620788
func TestReport(t *testing.T) {
621789
want := []string{
622790
"content",

diff/errors.go

+20
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,25 @@ func (e errInvalidType) Error() string {
2525
return fmt.Sprintf("%T is not a valid type for %s", e.Value, e.For)
2626
}
2727

28+
// ErrLHSNotSupported is returned when calling diff.LHS on a Differ that does not contain
29+
// an LHS value (i.e Ignore)
30+
type ErrLHSNotSupported struct {
31+
Diff Differ
32+
}
33+
34+
func (e ErrLHSNotSupported) Error() string {
35+
return fmt.Sprintf("%T does not contain an LHS value", e.Diff)
36+
}
37+
38+
// ErrRHSNotSupported is returned when calling diff.EHS on a Differ that does not contain
39+
// an RHS value (i.e Ignore)
40+
type ErrRHSNotSupported struct {
41+
Diff Differ
42+
}
43+
44+
func (e ErrRHSNotSupported) Error() string {
45+
return fmt.Sprintf("%T does not contain an RHS value", e.Diff)
46+
}
47+
2848
// ErrCyclic is returned when one of the compared values contain circular references
2949
var ErrCyclic = errors.New("circular references not supported")

diff/map.go

+17
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,15 @@ func (m mapDiff) Walk(path string, fn WalkFn) error {
201201

202202
return nil
203203
}
204+
205+
func (m mapDiff) LHS() interface{} {
206+
return m.lhs
207+
}
208+
209+
func (m mapDiff) RHS() interface{} {
210+
return m.rhs
211+
}
212+
204213
func getKeys(lhs, rhs reflect.Value) []reflect.Value {
205214
keys := lhs.MapKeys()
206215

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

248+
func (m mapMissing) LHS() interface{} {
249+
return m.value
250+
}
251+
239252
func (e mapExcess) Diff() Type {
240253
return ContentDiffer
241254
}
@@ -249,3 +262,7 @@ func (e mapExcess) Strings() []string {
249262
func (e mapExcess) StringIndent(key, prefix string, conf Output) string {
250263
return "+" + prefix + key + conf.green(e.value)
251264
}
265+
266+
func (e mapExcess) RHS() interface{} {
267+
return e.value
268+
}

diff/scalar.go

+8
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,11 @@ func (s scalar) StringIndent(key, prefix string, conf Output) string {
4545
return "-" + prefix + key + conf.red(s.lhs) + "\n" +
4646
"+" + prefix + key + conf.green(s.rhs)
4747
}
48+
49+
func (s scalar) LHS() interface{} {
50+
return s.lhs
51+
}
52+
53+
func (s scalar) RHS() interface{} {
54+
return s.rhs
55+
}

diff/slice.go

+16
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,14 @@ func (s slice) Walk(path string, fn WalkFn) error {
245245
return nil
246246
}
247247

248+
func (s slice) LHS() interface{} {
249+
return s.lhs
250+
}
251+
252+
func (s slice) RHS() interface{} {
253+
return s.rhs
254+
}
255+
248256
func (m sliceMissing) Diff() Type {
249257
return ContentDiffer
250258
}
@@ -259,6 +267,10 @@ func (m sliceMissing) StringIndent(key, prefix string, conf Output) string {
259267
return "-" + prefix + key + conf.red(m.value)
260268
}
261269

270+
func (m sliceMissing) LHS() interface{} {
271+
return m.value
272+
}
273+
262274
func (e sliceExcess) Diff() Type {
263275
return ContentDiffer
264276
}
@@ -272,3 +284,7 @@ func (e sliceExcess) Strings() []string {
272284
func (e sliceExcess) StringIndent(key, prefix string, conf Output) string {
273285
return "+" + prefix + key + conf.green(e.value)
274286
}
287+
288+
func (e sliceExcess) RHS() interface{} {
289+
return e.value
290+
}

diff/types.go

+8
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,11 @@ func (t types) StringIndent(key, prefix string, conf Output) string {
2424
return "-" + prefix + key + conf.red(t.lhs) + "\n" +
2525
"+" + prefix + key + conf.green(t.rhs)
2626
}
27+
28+
func (t types) LHS() interface{} {
29+
return t.lhs
30+
}
31+
32+
func (t types) RHS() interface{} {
33+
return t.rhs
34+
}

0 commit comments

Comments
 (0)