From b02966ee6d0176c9fdc704795e712cc5e8e70353 Mon Sep 17 00:00:00 2001 From: Zamicol Date: Thu, 30 Mar 2023 12:02:50 -0600 Subject: [PATCH] fix #11; remove redundant MapSlice.KeysString() method --- coze_test.go | 45 ++++----------------- mapslice.go | 42 +++++++++---------- mapslice_test.go | 102 ++++++++++++++--------------------------------- normal/normal.go | 8 ++-- 4 files changed, 62 insertions(+), 135 deletions(-) diff --git a/coze_test.go b/coze_test.go index c33b7fa..b53ca41 100644 --- a/coze_test.go +++ b/coze_test.go @@ -161,30 +161,7 @@ func ExamplePay_UnmarshalJSON_duplicate() { msg := []byte(`{"alg":"ES256","alg":"ES384"}`) err := json.Unmarshal(msg, h) - if err != nil { - fmt.Println(err) - } - - // Output: - // Coze: JSON duplicate field name -} - -// Example demonstrating that unmarshalling a `pay` that has duplicate field -// names results in an error. -func ExamplePay_UnmarshalJSON_duplicate_array() { - h := &Pay{} - - // Error will be nil - err := json.Unmarshal([]byte(`{"bob":"bob","joe":["alg","alg"]}`), h) - if err != nil { - fmt.Println(err) - } - - // Error will not be nil - err = json.Unmarshal([]byte(`{"bob":"bob","joe":["alg","alg"],"bob":"bob2"}`), h) - if err != nil { - fmt.Println(err) - } + fmt.Println(err) // Output: // Coze: JSON duplicate field name @@ -195,11 +172,8 @@ func ExamplePay_UnmarshalJSON_duplicate_array() { func ExampleCoze_UnmarshalJSON_duplicate() { h := &Pay{} msg := []byte(`{"coze":{"pay":"ES256","pay":"ES384"}}`) - err := json.Unmarshal(msg, h) - if err != nil { - fmt.Println(err) - } + fmt.Println(err) // Output: // Coze: JSON duplicate field name @@ -287,7 +261,6 @@ func ExampleCoze_MetaWithAlg() { } func ExampleCoze_MetaWithAlg_contextual() { - // func TestCoze_MetaWithAlg_contextual(t *testing.T) { // Test MetaWithAlg using no sig, which should calc what it can. cz := new(Coze) err := json.Unmarshal([]byte(GoldenCoze), cz) @@ -299,9 +272,9 @@ func ExampleCoze_MetaWithAlg_contextual() { if err != nil { panic(err) } - fmt.Printf("%s\n", cz) - // Test empty coze with coze.parsed.alg + + // Empty coze with coze.parsed.alg cz = new(Coze) err = json.Unmarshal(GoldenCozeEmpty, cz) if err != nil { @@ -394,12 +367,9 @@ func ExampleMarshal_jsonRawMessage() { // Incorrect usage with pointer to a zero value string. // Pointer to empty string will fail Marshal since an empty string is not - // valid JSON. (If it were the value `""` it would pass. ) - b, err := Marshal(anon) // fails - if err != nil { - fmt.Println(err) - } - fmt.Printf("%+v\n", b) // Empty because of error. + // valid JSON., while the value `""` will pass. + b, err := Marshal(anon) // fails + fmt.Printf("%s\n%+v\n", err, b) // Error is populated and b is empty because of error. // Correct usage with quotes characters. quotes := []byte("\"\"") // string with two quote characters @@ -440,6 +410,7 @@ func Test_checkDuplicate(t *testing.T) { if err != ErrJSONDuplicate { t.Fatal("Should have found duplciate.") } + // No duplicate. Should not error. data = `{"a": "b", "c":"d", "d": {"e": 1, "f": 2}}` err = checkDuplicate(json.NewDecoder(strings.NewReader(data))) diff --git a/mapslice.go b/mapslice.go index 65cbd9a..64a7dc4 100644 --- a/mapslice.go +++ b/mapslice.go @@ -7,16 +7,17 @@ import ( "sort" ) -// MapSlice of map items. Go maps have an arbitrary order that cannot be -// (easily) set. MapSlice is for easy setting of a given order for maps. +// MapSlice is for setting of a given order for maps map items. Go maps have an +// arbitrary order that cannot be (easily) set. // -// This implementation of MapSlice supports only things that JSON or Coze -// needs, chiefly, Key is now type string instead of type any, and has extra -// methods, "Keys()", "KeyStrings()", "Values()". +// This implementation of MapSlice is designed for JSON/Coze. Key is now type +// string (instead of type any), and has extra methods, "Keys()", +// "KeyStrings()", "Values()". // // We may publish this as a standalone package. // -// go-yaml, a dead project, had the same problem and was solved 8 years ago: +// go-yaml, a "dead"/done project, had the same problem and was solved 8 years +// ago: // https://github.com/go-yaml/yaml/blob/7649d4548cb53a614db133b2a8ac1f31859dda8c/yaml.go#L20 // // MapSlice and MapItem was originally inspired from (3 years ago): @@ -38,17 +39,8 @@ func nextIndex() uint64 { return indexCounter } -// Keys returns a MapSlice's Keys in a slice. -func (ms MapSlice) Keys() []any { - s := make([]any, len(ms)) - for i, k := range ms { - s[i] = k.Key - } - return s -} - -// KeysString returns MapSlice's Keys as []string. -func (ms MapSlice) KeysString() []string { +// Keys returns MapSlice's Keys as []string. +func (ms MapSlice) Keys() []string { s := make([]string, len(ms)) for i, k := range ms { s[i] = k.Key @@ -68,14 +60,22 @@ func (ms MapSlice) Values() []any { // MarshalJSON for map slice. func (ms MapSlice) MarshalJSON() ([]byte, error) { buf := &bytes.Buffer{} - buf.Write([]byte{'{'}) + buf.Write([]byte{'{'}) // Write err is always nil. for i, mi := range ms { - b, err := json.Marshal(&mi.Value) + k, err := Marshal(&mi.Key) if err != nil { return nil, err } - buf.WriteString(fmt.Sprintf("%q:", fmt.Sprintf("%v", mi.Key))) - buf.Write(b) + buf.Write(k) + buf.Write([]byte{':'}) + + v, err := Marshal(&mi.Value) + if err != nil { + return nil, err + } + + buf.Write(v) + if i < len(ms)-1 { buf.Write([]byte{','}) } diff --git a/mapslice_test.go b/mapslice_test.go index 60b002c..1ac38ba 100644 --- a/mapslice_test.go +++ b/mapslice_test.go @@ -6,102 +6,58 @@ import ( "testing" ) -func TestMarshal(t *testing.T) { - ms := MapSlice{ - MapItem{Key: "abc", Value: 123}, - MapItem{Key: "def", Value: 456}, - MapItem{Key: "ghi", Value: 789}, - } - - b, err := json.Marshal(ms) - if err != nil { - t.Fatal(err) - } - - e := "{\"abc\":123,\"def\":456,\"ghi\":789}" - r := string(b) - - if r != e { - t.Fatalf("expected: %s\ngot: %s", e, r) - } +var GoldenMapSLice = MapSlice{ + MapItem{Key: "abc", Value: 123}, + MapItem{Key: "def", Value: "456"}, } -func TestMarshalError(t *testing.T) { - ms := MapSlice{ - MapItem{Key: "abc", Value: make(chan int)}, - } - - e := "json: error calling MarshalJSON for type coze.MapSlice: json: unsupported type: chan int" - if _, err := json.Marshal(ms); err != nil && e != err.Error() { - t.Fatalf("expected: %s\ngot: %v", e, err) - } -} - -func TestUnmarshal(t *testing.T) { - ms := MapSlice{} - if err := json.Unmarshal([]byte("{\"abc\":123,\"def\":456,\"ghi\":789}"), &ms); err != nil { - t.Fatal(err) - } - - e := "[{abc 123} {def 456} {ghi 789}]" - r := fmt.Sprintf("%v", ms) - - if r != e { - t.Fatalf("expected: %s\ngot: %s", e, r) - } -} - -func ExampleMapSlice_MarshalJSON() { - ms := MapSlice{ - MapItem{Key: "abc", Value: 123}, - MapItem{Key: "def", Value: 456}, - MapItem{Key: "ghi", Value: 789}, - } - - b, err := json.Marshal(ms) +func ExampleMapSlice_marshal() { + b, err := Marshal(GoldenMapSLice) if err != nil { panic(err) } - fmt.Printf("%s", b) + fmt.Printf("%s\n", b) // Output: - // {"abc":123,"def":456,"ghi":789} + // {"abc":123,"def":"456"} } -func ExampleMapSlice_UnmarshalJSON() { +func ExampleMapSlice_unmarshal() { ms := MapSlice{} - - if err := json.Unmarshal([]byte(`{"abc":123,"def":456,"ghi":789}`), &ms); err != nil { + err := json.Unmarshal([]byte(`{"abc":123,"def":"456"}`), &ms) + if err != nil { panic(err) } - fmt.Printf("%s", ms) + + fmt.Printf("%s\n", ms) // Output: - // [{abc 123} {def 456} {ghi 789}] + // [{abc 123} {def 456}] } func ExampleMapSlice_Keys() { - ms := MapSlice{ - MapItem{Key: "abc", Value: 123}, - MapItem{Key: "def", Value: 456}, - MapItem{Key: "ghi", Value: 789}, - } - fmt.Println(ms.Keys()) - fmt.Println(ms.KeysString()) + fmt.Println(GoldenMapSLice.Keys()) // Output: - // [abc def ghi] - // [abc def ghi] + // [abc def] } func ExampleMapSlice_Values() { + fmt.Println(GoldenMapSLice.Values()) + + // Output: + // [123 456] +} + +// Demonstrates that marshaling a channel is invalid. +func TestMapSlice_Marshal_chan(t *testing.T) { ms := MapSlice{ - MapItem{Key: "abc", Value: 123}, - MapItem{Key: "def", Value: 456}, - MapItem{Key: "ghi", Value: 789}, + MapItem{Key: "abc", Value: make(chan int)}, } - fmt.Println(ms.Values()) - // Output: - // [123 456 789] + e := "json: error calling MarshalJSON for type coze.MapSlice: json: unsupported type: chan int" + _, err := json.Marshal(ms) + if err != nil && e != err.Error() { + t.Fatalf("expected: %s\ngot: %v", e, err) + } } diff --git a/normal/normal.go b/normal/normal.go index 2596c72..33b68fb 100644 --- a/normal/normal.go +++ b/normal/normal.go @@ -195,7 +195,7 @@ func isNormal(r coze.MapSlice, rSkip int, nSkip int, extraFlag bool, norms ...No norm := norms[nSkip] if extraFlag { // Progress record pointer to first match. - keys := r[rSkip:].KeysString() + keys := r[rSkip:].Keys() var i int for i = 0; i < len(keys); i++ { if slices.Contains(norm.Normal(), Normal(keys[i])) { @@ -244,7 +244,7 @@ func isNormal(r coze.MapSlice, rSkip int, nSkip int, extraFlag bool, norms ...No if norm.Len() > len(r)-rSkip { return false } - keys := r[rSkip : v.Len()+rSkip].KeysString() + keys := r[rSkip : v.Len()+rSkip].Keys() slices.Sort(keys) slices.Sort(v) for i := range v { @@ -254,7 +254,7 @@ func isNormal(r coze.MapSlice, rSkip int, nSkip int, extraFlag bool, norms ...No passedRecs++ } case Option: - keys := r[rSkip:].KeysString() + keys := r[rSkip:].Keys() for i, n := range keys { if !slices.Contains(v, Normal(n)) { if nSkip+1 == len(norms) { // last norm @@ -271,7 +271,7 @@ func isNormal(r coze.MapSlice, rSkip int, nSkip int, extraFlag bool, norms ...No case Need: i := 0 key := "" - keys := r[rSkip:].KeysString() + keys := r[rSkip:].Keys() for i, key = range keys { if passedRecs == v.Len() { break