-
Notifications
You must be signed in to change notification settings - Fork 926
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The implementation has been mostly copied from the Go reference implementation with some small changes to fit TinyGo. Source: https://github.com/golang/go/blob/77a11c05d6a6f766c75f804ea9b8796f9a9f85a3/src/reflect/deepequal.go In addition, this commit also contains the following: - A set of tests copied from the Go reflect package. - An increased stack size for the riscv-qemu and hifive1-qemu targets (because they otherwise fail to run the tests). Because these targets are only used for testing, this seems fine to me.
- Loading branch information
1 parent
5866a47
commit 335fb71
Showing
7 changed files
with
432 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
// Copyright 2009 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package reflect_test | ||
|
||
import ( | ||
"math" | ||
. "reflect" | ||
"testing" | ||
) | ||
|
||
type Basic struct { | ||
x int | ||
y float32 | ||
} | ||
|
||
type NotBasic Basic | ||
|
||
type DeepEqualTest struct { | ||
a, b interface{} | ||
eq bool | ||
} | ||
|
||
// Simple functions for DeepEqual tests. | ||
var ( | ||
fn1 func() // nil. | ||
fn2 func() // nil. | ||
fn3 = func() { fn1() } // Not nil. | ||
) | ||
|
||
type self struct{} | ||
|
||
type Loopy interface{} | ||
|
||
var loopy1, loopy2 Loopy | ||
var cycleMap1, cycleMap2, cycleMap3 map[string]interface{} | ||
|
||
type structWithSelfPtr struct { | ||
p *structWithSelfPtr | ||
s string | ||
} | ||
|
||
func init() { | ||
loopy1 = &loopy2 | ||
loopy2 = &loopy1 | ||
|
||
cycleMap1 = map[string]interface{}{} | ||
cycleMap1["cycle"] = cycleMap1 | ||
cycleMap2 = map[string]interface{}{} | ||
cycleMap2["cycle"] = cycleMap2 | ||
cycleMap3 = map[string]interface{}{} | ||
cycleMap3["different"] = cycleMap3 | ||
} | ||
|
||
// Note: all tests involving maps have been commented out because they aren't | ||
// supported yet. | ||
var deepEqualTests = []DeepEqualTest{ | ||
// Equalities | ||
{nil, nil, true}, | ||
{1, 1, true}, | ||
{int32(1), int32(1), true}, | ||
{0.5, 0.5, true}, | ||
{float32(0.5), float32(0.5), true}, | ||
{"hello", "hello", true}, | ||
{make([]int, 10), make([]int, 10), true}, | ||
{&[3]int{1, 2, 3}, &[3]int{1, 2, 3}, true}, | ||
{Basic{1, 0.5}, Basic{1, 0.5}, true}, | ||
{error(nil), error(nil), true}, | ||
//{map[int]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, true}, | ||
{fn1, fn2, true}, | ||
{[]byte{1, 2, 3}, []byte{1, 2, 3}, true}, | ||
{[]MyByte{1, 2, 3}, []MyByte{1, 2, 3}, true}, | ||
{MyBytes{1, 2, 3}, MyBytes{1, 2, 3}, true}, | ||
|
||
// Inequalities | ||
{1, 2, false}, | ||
{int32(1), int32(2), false}, | ||
{0.5, 0.6, false}, | ||
{float32(0.5), float32(0.6), false}, | ||
{"hello", "hey", false}, | ||
{make([]int, 10), make([]int, 11), false}, | ||
{&[3]int{1, 2, 3}, &[3]int{1, 2, 4}, false}, | ||
{Basic{1, 0.5}, Basic{1, 0.6}, false}, | ||
{Basic{1, 0}, Basic{2, 0}, false}, | ||
//{map[int]string{1: "one", 3: "two"}, map[int]string{2: "two", 1: "one"}, false}, | ||
//{map[int]string{1: "one", 2: "txo"}, map[int]string{2: "two", 1: "one"}, false}, | ||
//{map[int]string{1: "one"}, map[int]string{2: "two", 1: "one"}, false}, | ||
//{map[int]string{2: "two", 1: "one"}, map[int]string{1: "one"}, false}, | ||
{nil, 1, false}, | ||
{1, nil, false}, | ||
{fn1, fn3, false}, | ||
{fn3, fn3, false}, | ||
{[][]int{{1}}, [][]int{{2}}, false}, | ||
{&structWithSelfPtr{p: &structWithSelfPtr{s: "a"}}, &structWithSelfPtr{p: &structWithSelfPtr{s: "b"}}, false}, | ||
|
||
// Fun with floating point. | ||
{math.NaN(), math.NaN(), false}, | ||
{&[1]float64{math.NaN()}, &[1]float64{math.NaN()}, false}, | ||
{&[1]float64{math.NaN()}, self{}, true}, | ||
{[]float64{math.NaN()}, []float64{math.NaN()}, false}, | ||
{[]float64{math.NaN()}, self{}, true}, | ||
//{map[float64]float64{math.NaN(): 1}, map[float64]float64{1: 2}, false}, | ||
//{map[float64]float64{math.NaN(): 1}, self{}, true}, | ||
|
||
// Nil vs empty: not the same. | ||
{[]int{}, []int(nil), false}, | ||
{[]int{}, []int{}, true}, | ||
{[]int(nil), []int(nil), true}, | ||
//{map[int]int{}, map[int]int(nil), false}, | ||
//{map[int]int{}, map[int]int{}, true}, | ||
//{map[int]int(nil), map[int]int(nil), true}, | ||
|
||
// Mismatched types | ||
{1, 1.0, false}, | ||
{int32(1), int64(1), false}, | ||
{0.5, "hello", false}, | ||
{[]int{1, 2, 3}, [3]int{1, 2, 3}, false}, | ||
{&[3]interface{}{1, 2, 4}, &[3]interface{}{1, 2, "s"}, false}, | ||
{Basic{1, 0.5}, NotBasic{1, 0.5}, false}, | ||
{map[uint]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, false}, | ||
{[]byte{1, 2, 3}, []MyByte{1, 2, 3}, false}, | ||
{[]MyByte{1, 2, 3}, MyBytes{1, 2, 3}, false}, | ||
{[]byte{1, 2, 3}, MyBytes{1, 2, 3}, false}, | ||
|
||
// Possible loops. | ||
{&loopy1, &loopy1, true}, | ||
{&loopy1, &loopy2, true}, | ||
//{&cycleMap1, &cycleMap2, true}, | ||
{&cycleMap1, &cycleMap3, false}, | ||
} | ||
|
||
func TestDeepEqual(t *testing.T) { | ||
for _, test := range deepEqualTests { | ||
if test.b == (self{}) { | ||
test.b = test.a | ||
} | ||
if r := DeepEqual(test.a, test.b); r != test.eq { | ||
t.Errorf("DeepEqual(%#v, %#v) = %v, want %v", test.a, test.b, r, test.eq) | ||
} | ||
} | ||
} | ||
|
||
type Recursive struct { | ||
x int | ||
r *Recursive | ||
} | ||
|
||
func TestDeepEqualRecursiveStruct(t *testing.T) { | ||
a, b := new(Recursive), new(Recursive) | ||
*a = Recursive{12, a} | ||
*b = Recursive{12, b} | ||
if !DeepEqual(a, b) { | ||
t.Error("DeepEqual(recursive same) = false, want true") | ||
} | ||
} | ||
|
||
type _Complex struct { | ||
a int | ||
b [3]*_Complex | ||
c *string | ||
d map[float64]float64 | ||
} | ||
|
||
func TestDeepEqualComplexStruct(t *testing.T) { | ||
m := make(map[float64]float64) | ||
stra, strb := "hello", "hello" | ||
a, b := new(_Complex), new(_Complex) | ||
*a = _Complex{5, [3]*_Complex{a, b, a}, &stra, m} | ||
*b = _Complex{5, [3]*_Complex{b, a, a}, &strb, m} | ||
if !DeepEqual(a, b) { | ||
t.Error("DeepEqual(complex same) = false, want true") | ||
} | ||
} | ||
|
||
func TestDeepEqualComplexStructInequality(t *testing.T) { | ||
m := make(map[float64]float64) | ||
stra, strb := "hello", "helloo" // Difference is here | ||
a, b := new(_Complex), new(_Complex) | ||
*a = _Complex{5, [3]*_Complex{a, b, a}, &stra, m} | ||
*b = _Complex{5, [3]*_Complex{b, a, a}, &strb, m} | ||
if DeepEqual(a, b) { | ||
t.Error("DeepEqual(complex different) = true, want false") | ||
} | ||
} | ||
|
||
type MyBytes []byte | ||
type MyByte byte |
Oops, something went wrong.