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 }