Commit 1880b90a authored by Rob Pike's avatar Rob Pike

DeepEqual for maps

R=rsc
DELTA=47  (30 added, 16 deleted, 1 changed)
OCL=31455
CL=31455
parent 981f4b43
...@@ -337,18 +337,6 @@ type Basic struct { ...@@ -337,18 +337,6 @@ type Basic struct {
type NotBasic Basic type NotBasic Basic
type Recursive struct {
x int;
r *Recursive
}
type Complex struct {
a int;
b [3]*Complex;
c *string;
d map[float]float
}
type DeepEqualTest struct { type DeepEqualTest struct {
a, b interface{}; a, b interface{};
eq bool; eq bool;
...@@ -365,6 +353,7 @@ var deepEqualTests = []DeepEqualTest { ...@@ -365,6 +353,7 @@ var deepEqualTests = []DeepEqualTest {
DeepEqualTest{ &[3]int{ 1, 2, 3 }, &[3]int{ 1, 2, 3 }, true }, DeepEqualTest{ &[3]int{ 1, 2, 3 }, &[3]int{ 1, 2, 3 }, true },
DeepEqualTest{ Basic{ 1, 0.5 }, Basic{ 1, 0.5 }, true }, DeepEqualTest{ Basic{ 1, 0.5 }, Basic{ 1, 0.5 }, true },
DeepEqualTest{ os.Error(nil), os.Error(nil), true }, DeepEqualTest{ os.Error(nil), os.Error(nil), true },
DeepEqualTest{ map[int]string{ 1:"one", 2:"two" }, map[int]string{ 2:"two", 1:"one" }, true },
// Inequalities // Inequalities
DeepEqualTest{ 1, 2, false }, DeepEqualTest{ 1, 2, false },
...@@ -376,6 +365,10 @@ var deepEqualTests = []DeepEqualTest { ...@@ -376,6 +365,10 @@ var deepEqualTests = []DeepEqualTest {
DeepEqualTest{ &[3]int{ 1, 2, 3 }, &[3]int{ 1, 2, 4 }, false }, DeepEqualTest{ &[3]int{ 1, 2, 3 }, &[3]int{ 1, 2, 4 }, false },
DeepEqualTest{ Basic{ 1, 0.5 }, Basic{ 1, 0.6 }, false }, DeepEqualTest{ Basic{ 1, 0.5 }, Basic{ 1, 0.6 }, false },
DeepEqualTest{ Basic{ 1, 0 }, Basic{ 2, 0 }, false }, DeepEqualTest{ Basic{ 1, 0 }, Basic{ 2, 0 }, false },
DeepEqualTest{ map[int]string{ 1:"one", 3:"two" }, map[int]string{ 2:"two", 1:"one" }, false },
DeepEqualTest{ map[int]string{ 1:"one", 2:"txo" }, map[int]string{ 2:"two", 1:"one" }, false },
DeepEqualTest{ map[int]string{ 1:"one", }, map[int]string{ 2:"two", 1:"one" }, false },
DeepEqualTest{ map[int]string{ 2:"two", 1:"one" }, map[int]string{ 1:"one", }, false },
// Mismatched types // Mismatched types
DeepEqualTest{ 1, 1.0, false }, DeepEqualTest{ 1, 1.0, false },
...@@ -384,6 +377,7 @@ var deepEqualTests = []DeepEqualTest { ...@@ -384,6 +377,7 @@ var deepEqualTests = []DeepEqualTest {
DeepEqualTest{ []int{ 1, 2, 3 }, [3]int{ 1, 2, 3 }, false }, DeepEqualTest{ []int{ 1, 2, 3 }, [3]int{ 1, 2, 3 }, false },
DeepEqualTest{ &[3]interface{} { 1, 2, 4 }, &[3]interface{} { 1, 2, "s" }, false }, DeepEqualTest{ &[3]interface{} { 1, 2, 4 }, &[3]interface{} { 1, 2, "s" }, false },
DeepEqualTest{ Basic{ 1, 0.5 }, NotBasic{ 1, 0.5 }, false }, DeepEqualTest{ Basic{ 1, 0.5 }, NotBasic{ 1, 0.5 }, false },
DeepEqualTest{ map[uint]string{ 1:"one", 2:"two" }, map[int]string{ 2:"two", 1:"one" }, false },
} }
func TestDeepEqual(t *testing.T) { func TestDeepEqual(t *testing.T) {
...@@ -407,6 +401,11 @@ func TestTypeof(t *testing.T) { ...@@ -407,6 +401,11 @@ func TestTypeof(t *testing.T) {
} }
} }
type Recursive struct {
x int;
r *Recursive
}
func TestDeepEqualRecursiveStruct(t *testing.T) { func TestDeepEqualRecursiveStruct(t *testing.T) {
a, b := new(Recursive), new(Recursive); a, b := new(Recursive), new(Recursive);
*a = Recursive{ 12, a }; *a = Recursive{ 12, a };
...@@ -416,6 +415,13 @@ func TestDeepEqualRecursiveStruct(t *testing.T) { ...@@ -416,6 +415,13 @@ func TestDeepEqualRecursiveStruct(t *testing.T) {
} }
} }
type Complex struct {
a int;
b [3]*Complex;
c *string;
d map[float]float
}
func TestDeepEqualComplexStruct(t *testing.T) { func TestDeepEqualComplexStruct(t *testing.T) {
m := make(map[float]float); m := make(map[float]float);
stra, strb := "hello", "hello"; stra, strb := "hello", "hello";
......
...@@ -92,9 +92,6 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) bool { ...@@ -92,9 +92,6 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) bool {
return i1 == i2; return i1 == i2;
} }
return deepValueEqual(NewValue(i1), NewValue(i2), visited, depth+1); return deepValueEqual(NewValue(i1), NewValue(i2), visited, depth+1);
case *MapValue:
// TODO(dnadasi): Implement this fully once MapValue is implemented
return v1.Interface() == v2.Interface();
case *PtrValue: case *PtrValue:
return deepValueEqual(v.Elem(), v2.(*PtrValue).Elem(), visited, depth+1); return deepValueEqual(v.Elem(), v2.(*PtrValue).Elem(), visited, depth+1);
case *StructValue: case *StructValue:
...@@ -106,6 +103,18 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) bool { ...@@ -106,6 +103,18 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) bool {
} }
} }
return true; return true;
case *MapValue:
map1 := v;
map2 := v2.(*MapValue);
if map1.Len() != map2.Len() {
return false;
}
for i, k := range map1.Keys() {
if !deepValueEqual(map1.Get(k), map2.Get(k), visited, depth+1) {
return false;
}
}
return true;
default: default:
// Normal equality suffices // Normal equality suffices
return v1.Interface() == v2.Interface(); return v1.Interface() == v2.Interface();
...@@ -116,8 +125,7 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) bool { ...@@ -116,8 +125,7 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) bool {
// DeepEqual tests for deep equality. It uses normal == equality where possible // DeepEqual tests for deep equality. It uses normal == equality where possible
// but will scan members of arrays, slices, and fields of structs. It correctly // but will scan members of arrays, slices, and fields of structs. It correctly
// handles recursive types. Until reflection supports maps, maps are equal iff // handles recursive types.
// they are identical.
func DeepEqual(a1, a2 interface{}) bool { func DeepEqual(a1, a2 interface{}) bool {
v1 := NewValue(a1); v1 := NewValue(a1);
v2 := NewValue(a2); v2 := NewValue(a2);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment