scratch_test.go (5287B)
1 // Copyright 2018 The Hugo Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 package maps
15
16 import (
17 "reflect"
18 "sync"
19 "testing"
20
21 qt "github.com/frankban/quicktest"
22 )
23
24 func TestScratchAdd(t *testing.T) {
25 t.Parallel()
26 c := qt.New(t)
27
28 scratch := NewScratch()
29 scratch.Add("int1", 10)
30 scratch.Add("int1", 20)
31 scratch.Add("int2", 20)
32
33 c.Assert(scratch.Get("int1"), qt.Equals, int64(30))
34 c.Assert(scratch.Get("int2"), qt.Equals, 20)
35
36 scratch.Add("float1", float64(10.5))
37 scratch.Add("float1", float64(20.1))
38
39 c.Assert(scratch.Get("float1"), qt.Equals, float64(30.6))
40
41 scratch.Add("string1", "Hello ")
42 scratch.Add("string1", "big ")
43 scratch.Add("string1", "World!")
44
45 c.Assert(scratch.Get("string1"), qt.Equals, "Hello big World!")
46
47 scratch.Add("scratch", scratch)
48 _, err := scratch.Add("scratch", scratch)
49
50 m := scratch.Values()
51 c.Assert(m, qt.HasLen, 5)
52
53 if err == nil {
54 t.Errorf("Expected error from invalid arithmetic")
55 }
56 }
57
58 func TestScratchAddSlice(t *testing.T) {
59 t.Parallel()
60 c := qt.New(t)
61
62 scratch := NewScratch()
63
64 _, err := scratch.Add("intSlice", []int{1, 2})
65 c.Assert(err, qt.IsNil)
66 _, err = scratch.Add("intSlice", 3)
67 c.Assert(err, qt.IsNil)
68
69 sl := scratch.Get("intSlice")
70 expected := []int{1, 2, 3}
71
72 if !reflect.DeepEqual(expected, sl) {
73 t.Errorf("Slice difference, go %q expected %q", sl, expected)
74 }
75 _, err = scratch.Add("intSlice", []int{4, 5})
76
77 c.Assert(err, qt.IsNil)
78
79 sl = scratch.Get("intSlice")
80 expected = []int{1, 2, 3, 4, 5}
81
82 if !reflect.DeepEqual(expected, sl) {
83 t.Errorf("Slice difference, go %q expected %q", sl, expected)
84 }
85 }
86
87 // https://github.com/gohugoio/hugo/issues/5275
88 func TestScratchAddTypedSliceToInterfaceSlice(t *testing.T) {
89 t.Parallel()
90 c := qt.New(t)
91
92 scratch := NewScratch()
93 scratch.Set("slice", []any{})
94
95 _, err := scratch.Add("slice", []int{1, 2})
96 c.Assert(err, qt.IsNil)
97 c.Assert(scratch.Get("slice"), qt.DeepEquals, []int{1, 2})
98 }
99
100 // https://github.com/gohugoio/hugo/issues/5361
101 func TestScratchAddDifferentTypedSliceToInterfaceSlice(t *testing.T) {
102 t.Parallel()
103 c := qt.New(t)
104
105 scratch := NewScratch()
106 scratch.Set("slice", []string{"foo"})
107
108 _, err := scratch.Add("slice", []int{1, 2})
109 c.Assert(err, qt.IsNil)
110 c.Assert(scratch.Get("slice"), qt.DeepEquals, []any{"foo", 1, 2})
111 }
112
113 func TestScratchSet(t *testing.T) {
114 t.Parallel()
115 c := qt.New(t)
116
117 scratch := NewScratch()
118 scratch.Set("key", "val")
119 c.Assert(scratch.Get("key"), qt.Equals, "val")
120 }
121
122 func TestScratchDelete(t *testing.T) {
123 t.Parallel()
124 c := qt.New(t)
125
126 scratch := NewScratch()
127 scratch.Set("key", "val")
128 scratch.Delete("key")
129 scratch.Add("key", "Lucy Parsons")
130 c.Assert(scratch.Get("key"), qt.Equals, "Lucy Parsons")
131 }
132
133 // Issue #2005
134 func TestScratchInParallel(t *testing.T) {
135 var wg sync.WaitGroup
136 scratch := NewScratch()
137
138 key := "counter"
139 scratch.Set(key, int64(1))
140 for i := 1; i <= 10; i++ {
141 wg.Add(1)
142 go func(j int) {
143 for k := 0; k < 10; k++ {
144 newVal := int64(k + j)
145
146 _, err := scratch.Add(key, newVal)
147 if err != nil {
148 t.Errorf("Got err %s", err)
149 }
150
151 scratch.Set(key, newVal)
152
153 val := scratch.Get(key)
154
155 if counter, ok := val.(int64); ok {
156 if counter < 1 {
157 t.Errorf("Got %d", counter)
158 }
159 } else {
160 t.Errorf("Got %T", val)
161 }
162 }
163 wg.Done()
164 }(i)
165 }
166 wg.Wait()
167 }
168
169 func TestScratchGet(t *testing.T) {
170 t.Parallel()
171 scratch := NewScratch()
172 nothing := scratch.Get("nothing")
173 if nothing != nil {
174 t.Errorf("Should not return anything, but got %v", nothing)
175 }
176 }
177
178 func TestScratchSetInMap(t *testing.T) {
179 t.Parallel()
180 c := qt.New(t)
181
182 scratch := NewScratch()
183 scratch.SetInMap("key", "lux", "Lux")
184 scratch.SetInMap("key", "abc", "Abc")
185 scratch.SetInMap("key", "zyx", "Zyx")
186 scratch.SetInMap("key", "abc", "Abc (updated)")
187 scratch.SetInMap("key", "def", "Def")
188 c.Assert(scratch.GetSortedMapValues("key"), qt.DeepEquals, []any{0: "Abc (updated)", 1: "Def", 2: "Lux", 3: "Zyx"})
189 }
190
191 func TestScratchDeleteInMap(t *testing.T) {
192 t.Parallel()
193 c := qt.New(t)
194
195 scratch := NewScratch()
196 scratch.SetInMap("key", "lux", "Lux")
197 scratch.SetInMap("key", "abc", "Abc")
198 scratch.SetInMap("key", "zyx", "Zyx")
199 scratch.DeleteInMap("key", "abc")
200 scratch.SetInMap("key", "def", "Def")
201 scratch.DeleteInMap("key", "lmn") // Do nothing
202 c.Assert(scratch.GetSortedMapValues("key"), qt.DeepEquals, []any{0: "Def", 1: "Lux", 2: "Zyx"})
203 }
204
205 func TestScratchGetSortedMapValues(t *testing.T) {
206 t.Parallel()
207 scratch := NewScratch()
208 nothing := scratch.GetSortedMapValues("nothing")
209 if nothing != nil {
210 t.Errorf("Should not return anything, but got %v", nothing)
211 }
212 }
213
214 func BenchmarkScratchGet(b *testing.B) {
215 scratch := NewScratch()
216 scratch.Add("A", 1)
217 b.ResetTimer()
218 for i := 0; i < b.N; i++ {
219 scratch.Get("A")
220 }
221 }