Skip to content

Commit 0337ee0

Browse files
orderdmap: add json tests
1 parent 8b833ca commit 0337ee0

File tree

2 files changed

+52
-34
lines changed

2 files changed

+52
-34
lines changed

Diff for: internal/orderedmap/orderedmap.go

+11-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package orderedmap
1818
import (
1919
"bytes"
2020
"encoding/json"
21+
"fmt"
2122
"slices"
2223
)
2324

@@ -38,10 +39,15 @@ type Map[K any, V any] interface {
3839
MarshalJSON() ([]byte, error)
3940
}
4041

42+
type scalars interface {
43+
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 |
44+
~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64 | ~string
45+
}
46+
4147
// NewWithConversionFunc creates a map using the given conversion function
4248
// to convert non-comparable key type to comparable items.
4349
// The conversion function must be bijective.
44-
func NewWithConversionFunc[K any, V any, C comparable](conv func(K) C) Map[K, V] {
50+
func NewWithConversionFunc[K any, V any, C scalars](conv func(K) C) Map[K, V] {
4551
return &mapImpl[K, V, C]{
4652
conv: conv,
4753
kv: map[C]V{},
@@ -50,15 +56,15 @@ func NewWithConversionFunc[K any, V any, C comparable](conv func(K) C) Map[K, V]
5056
}
5157

5258
// New creates a map
53-
func New[K comparable, V any]() Map[K, V] {
59+
func New[K scalars, V any]() Map[K, V] {
5460
return &mapImpl[K, V, K]{
5561
conv: func(in K) K { return in }, // identity
5662
kv: map[K]V{},
5763
o: []K{},
5864
}
5965
}
6066

61-
type mapImpl[K any, V any, C comparable] struct {
67+
type mapImpl[K any, V any, C scalars] struct {
6268
conv func(K) C
6369
kv map[C]V
6470
o []K
@@ -91,7 +97,8 @@ func (m *mapImpl[K, V, C]) MarshalJSON() ([]byte, error) {
9197
buf.WriteByte('{')
9298
encoder := json.NewEncoder(&buf)
9399
for _, k := range m.o {
94-
if err := encoder.Encode(k); err != nil {
100+
// Here we convert non string keys in string.
101+
if err := encoder.Encode(fmt.Sprintf("%v", m.conv(k))); err != nil {
95102
return nil, err
96103
}
97104
buf.WriteByte(':')

Diff for: internal/orderedmap/orderedmap_test.go

+41-30
Original file line numberDiff line numberDiff line change
@@ -67,36 +67,6 @@ func TestGet(t *testing.T) {
6767
require.True(t, ok)
6868
})
6969

70-
t.Run("the key is a pointer", func(t *testing.T) {
71-
m := orderedmap.New[*string, int]()
72-
73-
notExistingKey := toPtr("not-existing-key")
74-
require.Equal(t, 0, m.Get(notExistingKey))
75-
v, ok := m.GetOk(notExistingKey)
76-
require.Zero(t, v)
77-
require.False(t, ok)
78-
79-
existingKey := toPtr("existing-key")
80-
m.Set(existingKey, 1)
81-
require.Equal(t, 1, m.Get(existingKey))
82-
v, ok = m.GetOk(existingKey)
83-
require.Equal(t, 1, v)
84-
require.True(t, ok)
85-
86-
// Using a different pointer with the same value returns no result
87-
require.Equal(t, 0, m.Get(toPtr("existing-key")))
88-
v, ok = m.GetOk(toPtr("existing-key"))
89-
require.Zero(t, v)
90-
require.False(t, ok)
91-
92-
// test empty key
93-
m.Set(nil, 2)
94-
require.Equal(t, 2, m.Get(nil))
95-
v, ok = m.GetOk(nil)
96-
require.Equal(t, 2, v)
97-
require.True(t, ok)
98-
})
99-
10070
t.Run("custom comparable key", func(t *testing.T) {
10171
type A struct {
10272
b []byte
@@ -345,6 +315,47 @@ func TestClone(t *testing.T) {
345315
})
346316
}
347317

318+
func TestMarshallJSON(t *testing.T) {
319+
t.Run("empty map", func(t *testing.T) {
320+
m := orderedmap.New[string, int]()
321+
mapJSON, err := m.MarshalJSON()
322+
require.NoError(t, err)
323+
require.JSONEq(t, `{}`, string(mapJSON))
324+
})
325+
t.Run("respect the order of insertion", func(t *testing.T) {
326+
m := orderedmap.New[string, int]()
327+
m.Set("a", 1)
328+
m.Set("b", 2)
329+
m.Set("c", 3)
330+
mapJSON, err := m.MarshalJSON()
331+
require.NoError(t, err)
332+
require.JSONEq(t, `{"a":1,"b":2,"c":3}`, string(mapJSON))
333+
})
334+
t.Run("can serialize int keys", func(t *testing.T) {
335+
m := orderedmap.New[int, bool]()
336+
m.Set(1, true)
337+
m.Set(2, true)
338+
m.Set(3, true)
339+
mapJSON, err := m.MarshalJSON()
340+
require.NoError(t, err)
341+
require.JSONEq(t, `{"1":true,"2":true,"3":true}`, string(mapJSON))
342+
})
343+
t.Run("can serialize pointer keys", func(t *testing.T) {
344+
m := orderedmap.NewWithConversionFunc[*int, bool, int](func(i *int) int {
345+
if i == nil {
346+
return 0
347+
}
348+
return *i
349+
})
350+
m.Set(toPtr(1), true)
351+
m.Set(toPtr(2), true)
352+
m.Set(toPtr(3), true)
353+
mapJSON, err := m.MarshalJSON()
354+
require.NoError(t, err)
355+
require.JSONEq(t, `{"1":true,"2":true,"3":true}`, string(mapJSON))
356+
})
357+
}
358+
348359
func toPtr[V any](v V) *V {
349360
return &v
350361
}

0 commit comments

Comments
 (0)