You've already forked json-iterator
							
							
				mirror of
				https://github.com/json-iterator/go.git
				synced 2025-10-31 00:07:40 +02:00 
			
		
		
		
	Methods on aliased types are not valid map keys
This commit is contained in:
		| @@ -1,152 +0,0 @@ | |||||||
| package test |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"encoding/json" |  | ||||||
| 	"fmt" |  | ||||||
| 	"strings" |  | ||||||
| 	"testing" |  | ||||||
|  |  | ||||||
| 	"github.com/davecgh/go-spew/spew" |  | ||||||
| 	fuzz "github.com/google/gofuzz" |  | ||||||
| 	jsoniter "github.com/json-iterator/go" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func Test_Roundtrip(t *testing.T) { |  | ||||||
| 	fz := fuzz.New().MaxDepth(10).NilChance(0.3) |  | ||||||
| 	for i := 0; i < 1000; i++ { |  | ||||||
| 		var before T |  | ||||||
| 		fz.Fuzz(&before) |  | ||||||
|  |  | ||||||
| 		jbStd, err := json.Marshal(before) |  | ||||||
| 		if err != nil { |  | ||||||
| 			t.Fatalf("failed to marshal with stdlib: %v", err) |  | ||||||
| 		} |  | ||||||
| 		if len(strings.TrimSpace(string(jbStd))) == 0 { |  | ||||||
| 			t.Fatal("stdlib marshal produced empty result and no error") |  | ||||||
| 		} |  | ||||||
| 		jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) |  | ||||||
| 		if err != nil { |  | ||||||
| 			t.Fatalf("failed to marshal with jsoniter: %v", err) |  | ||||||
| 		} |  | ||||||
| 		if len(strings.TrimSpace(string(jbIter))) == 0 { |  | ||||||
| 			t.Fatal("jsoniter marshal produced empty result and no error") |  | ||||||
| 		} |  | ||||||
| 		if string(jbStd) != string(jbIter) { |  | ||||||
| 			t.Fatalf("marshal expected:\n    %s\ngot:\n    %s\nobj:\n    %s", |  | ||||||
| 				indent(jbStd, "    "), indent(jbIter, "    "), dump(before)) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		var afterStd T |  | ||||||
| 		err = json.Unmarshal(jbIter, &afterStd) |  | ||||||
| 		if err != nil { |  | ||||||
| 			t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n    %s", |  | ||||||
| 				err, indent(jbIter, "    ")) |  | ||||||
| 		} |  | ||||||
| 		var afterIter T |  | ||||||
| 		err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) |  | ||||||
| 		if err != nil { |  | ||||||
| 			t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n    %s", |  | ||||||
| 				err, indent(jbIter, "    ")) |  | ||||||
| 		} |  | ||||||
| 		if fingerprint(afterStd) != fingerprint(afterIter) { |  | ||||||
| 			t.Fatalf("unmarshal expected:\n    %s\ngot:\n    %s\nvia:\n    %s", |  | ||||||
| 				dump(afterStd), dump(afterIter), indent(jbIter, "    ")) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const indentStr = ">  " |  | ||||||
|  |  | ||||||
| func fingerprint(obj interface{}) string { |  | ||||||
| 	c := spew.ConfigState{ |  | ||||||
| 		SortKeys: true, |  | ||||||
| 		SpewKeys: true, |  | ||||||
| 	} |  | ||||||
| 	return c.Sprintf("%v", obj) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func dump(obj interface{}) string { |  | ||||||
| 	cfg := spew.ConfigState{ |  | ||||||
| 		Indent: indentStr, |  | ||||||
| 	} |  | ||||||
| 	return cfg.Sdump(obj) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func indent(src []byte, prefix string) string { |  | ||||||
| 	var buf bytes.Buffer |  | ||||||
| 	err := json.Indent(&buf, src, prefix, indentStr) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Sprintf("!!! %v", err) |  | ||||||
| 	} |  | ||||||
| 	return buf.String() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { |  | ||||||
| 	t.ReportAllocs() |  | ||||||
| 	t.ResetTimer() |  | ||||||
|  |  | ||||||
| 	var obj T |  | ||||||
| 	fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) |  | ||||||
| 	fz.Fuzz(&obj) |  | ||||||
| 	for i := 0; i < t.N; i++ { |  | ||||||
| 		jb, err := fn(obj) |  | ||||||
| 		if err != nil { |  | ||||||
| 			t.Fatalf("%s failed to marshal:\n input: %s\n  error: %v", name, dump(obj), err) |  | ||||||
| 		} |  | ||||||
| 		_ = jb |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { |  | ||||||
| 	t.ReportAllocs() |  | ||||||
| 	t.ResetTimer() |  | ||||||
|  |  | ||||||
| 	var before T |  | ||||||
| 	fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) |  | ||||||
| 	fz.Fuzz(&before) |  | ||||||
| 	jb, err := json.Marshal(before) |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatalf("failed to marshal: %v", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for i := 0; i < t.N; i++ { |  | ||||||
| 		var after T |  | ||||||
| 		err = fn(jb, &after) |  | ||||||
| 		if err != nil { |  | ||||||
| 			t.Fatalf("%s failed to unmarshal:\n  input: %q\n  error: %v", name, string(jb), err) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func BenchmarkStandardMarshal(t *testing.B) { |  | ||||||
| 	benchmarkMarshal(t, "stdlib", json.Marshal) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func BenchmarkStandardUnmarshal(t *testing.B) { |  | ||||||
| 	benchmarkUnmarshal(t, "stdlib", json.Unmarshal) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func BenchmarkJSONIterMarshalFastest(t *testing.B) { |  | ||||||
| 	benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { |  | ||||||
| 	benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func BenchmarkJSONIterMarshalDefault(t *testing.B) { |  | ||||||
| 	benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { |  | ||||||
| 	benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func BenchmarkJSONIterMarshalCompatible(t *testing.B) { |  | ||||||
| 	benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { |  | ||||||
| 	benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) |  | ||||||
| } |  | ||||||
| @@ -1,26 +0,0 @@ | |||||||
| package test |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"encoding" |  | ||||||
| 	"strings" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type KeyType struct { |  | ||||||
| 	X string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (k KeyType) MarshalText() ([]byte, error) { |  | ||||||
| 	return []byte("MANUAL__" + k.X), nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (k *KeyType) UnmarshalText(text []byte) error { |  | ||||||
| 	k.X = strings.TrimPrefix(string(text), "MANUAL__") |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var _ encoding.TextMarshaler = KeyType{} |  | ||||||
| var _ encoding.TextUnmarshaler = &KeyType{} |  | ||||||
|  |  | ||||||
| type A KeyType |  | ||||||
|  |  | ||||||
| type T map[A]string |  | ||||||
		Reference in New Issue
	
	Block a user