github.com/shohhei1126/hugo@v0.42.2-0.20180623210752-3d5928889ad7/tpl/math/math_test.go (about) 1 // Copyright 2017 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 math 15 16 import ( 17 "fmt" 18 "math" 19 "testing" 20 21 "github.com/stretchr/testify/assert" 22 "github.com/stretchr/testify/require" 23 ) 24 25 func TestBasicNSArithmetic(t *testing.T) { 26 t.Parallel() 27 28 ns := New() 29 30 for i, test := range []struct { 31 fn func(a, b interface{}) (interface{}, error) 32 a interface{} 33 b interface{} 34 expect interface{} 35 }{ 36 {ns.Add, 4, 2, int64(6)}, 37 {ns.Add, 1.0, "foo", false}, 38 {ns.Sub, 4, 2, int64(2)}, 39 {ns.Sub, 1.0, "foo", false}, 40 {ns.Mul, 4, 2, int64(8)}, 41 {ns.Mul, 1.0, "foo", false}, 42 {ns.Div, 4, 2, int64(2)}, 43 {ns.Div, 1.0, "foo", false}, 44 } { 45 errMsg := fmt.Sprintf("[%d] %v", i, test) 46 47 result, err := test.fn(test.a, test.b) 48 49 if b, ok := test.expect.(bool); ok && !b { 50 require.Error(t, err, errMsg) 51 continue 52 } 53 54 require.NoError(t, err, errMsg) 55 assert.Equal(t, test.expect, result, errMsg) 56 } 57 } 58 59 func TestDoArithmetic(t *testing.T) { 60 t.Parallel() 61 62 for i, test := range []struct { 63 a interface{} 64 b interface{} 65 op rune 66 expect interface{} 67 }{ 68 {3, 2, '+', int64(5)}, 69 {3, 2, '-', int64(1)}, 70 {3, 2, '*', int64(6)}, 71 {3, 2, '/', int64(1)}, 72 {3.0, 2, '+', float64(5)}, 73 {3.0, 2, '-', float64(1)}, 74 {3.0, 2, '*', float64(6)}, 75 {3.0, 2, '/', float64(1.5)}, 76 {3, 2.0, '+', float64(5)}, 77 {3, 2.0, '-', float64(1)}, 78 {3, 2.0, '*', float64(6)}, 79 {3, 2.0, '/', float64(1.5)}, 80 {3.0, 2.0, '+', float64(5)}, 81 {3.0, 2.0, '-', float64(1)}, 82 {3.0, 2.0, '*', float64(6)}, 83 {3.0, 2.0, '/', float64(1.5)}, 84 {uint(3), uint(2), '+', uint64(5)}, 85 {uint(3), uint(2), '-', uint64(1)}, 86 {uint(3), uint(2), '*', uint64(6)}, 87 {uint(3), uint(2), '/', uint64(1)}, 88 {uint(3), 2, '+', uint64(5)}, 89 {uint(3), 2, '-', uint64(1)}, 90 {uint(3), 2, '*', uint64(6)}, 91 {uint(3), 2, '/', uint64(1)}, 92 {3, uint(2), '+', uint64(5)}, 93 {3, uint(2), '-', uint64(1)}, 94 {3, uint(2), '*', uint64(6)}, 95 {3, uint(2), '/', uint64(1)}, 96 {uint(3), -2, '+', int64(1)}, 97 {uint(3), -2, '-', int64(5)}, 98 {uint(3), -2, '*', int64(-6)}, 99 {uint(3), -2, '/', int64(-1)}, 100 {-3, uint(2), '+', int64(-1)}, 101 {-3, uint(2), '-', int64(-5)}, 102 {-3, uint(2), '*', int64(-6)}, 103 {-3, uint(2), '/', int64(-1)}, 104 {uint(3), 2.0, '+', float64(5)}, 105 {uint(3), 2.0, '-', float64(1)}, 106 {uint(3), 2.0, '*', float64(6)}, 107 {uint(3), 2.0, '/', float64(1.5)}, 108 {3.0, uint(2), '+', float64(5)}, 109 {3.0, uint(2), '-', float64(1)}, 110 {3.0, uint(2), '*', float64(6)}, 111 {3.0, uint(2), '/', float64(1.5)}, 112 {0, 0, '+', 0}, 113 {0, 0, '-', 0}, 114 {0, 0, '*', 0}, 115 {"foo", "bar", '+', "foobar"}, 116 {3, 0, '/', false}, 117 {3.0, 0, '/', false}, 118 {3, 0.0, '/', false}, 119 {uint(3), uint(0), '/', false}, 120 {3, uint(0), '/', false}, 121 {-3, uint(0), '/', false}, 122 {uint(3), 0, '/', false}, 123 {3.0, uint(0), '/', false}, 124 {uint(3), 0.0, '/', false}, 125 {3, "foo", '+', false}, 126 {3.0, "foo", '+', false}, 127 {uint(3), "foo", '+', false}, 128 {"foo", 3, '+', false}, 129 {"foo", "bar", '-', false}, 130 {3, 2, '%', false}, 131 } { 132 errMsg := fmt.Sprintf("[%d] %v", i, test) 133 134 result, err := DoArithmetic(test.a, test.b, test.op) 135 136 if b, ok := test.expect.(bool); ok && !b { 137 require.Error(t, err, errMsg) 138 continue 139 } 140 141 require.NoError(t, err, errMsg) 142 assert.Equal(t, test.expect, result, errMsg) 143 } 144 } 145 146 func TestCeil(t *testing.T) { 147 t.Parallel() 148 149 ns := New() 150 151 for i, test := range []struct { 152 x interface{} 153 expect interface{} 154 }{ 155 {0.1, 1.0}, 156 {0.5, 1.0}, 157 {1.1, 2.0}, 158 {1.5, 2.0}, 159 {-0.1, 0.0}, 160 {-0.5, 0.0}, 161 {-1.1, -1.0}, 162 {-1.5, -1.0}, 163 {"abc", false}, 164 } { 165 errMsg := fmt.Sprintf("[%d] %v", i, test) 166 167 result, err := ns.Ceil(test.x) 168 169 if b, ok := test.expect.(bool); ok && !b { 170 require.Error(t, err, errMsg) 171 continue 172 } 173 174 require.NoError(t, err, errMsg) 175 assert.Equal(t, test.expect, result, errMsg) 176 } 177 } 178 179 func TestFloor(t *testing.T) { 180 t.Parallel() 181 182 ns := New() 183 184 for i, test := range []struct { 185 x interface{} 186 expect interface{} 187 }{ 188 {0.1, 0.0}, 189 {0.5, 0.0}, 190 {1.1, 1.0}, 191 {1.5, 1.0}, 192 {-0.1, -1.0}, 193 {-0.5, -1.0}, 194 {-1.1, -2.0}, 195 {-1.5, -2.0}, 196 {"abc", false}, 197 } { 198 errMsg := fmt.Sprintf("[%d] %v", i, test) 199 200 result, err := ns.Floor(test.x) 201 202 if b, ok := test.expect.(bool); ok && !b { 203 require.Error(t, err, errMsg) 204 continue 205 } 206 207 require.NoError(t, err, errMsg) 208 assert.Equal(t, test.expect, result, errMsg) 209 } 210 } 211 212 func TestLog(t *testing.T) { 213 t.Parallel() 214 215 ns := New() 216 217 for i, test := range []struct { 218 a interface{} 219 expect interface{} 220 }{ 221 {1, float64(0)}, 222 {3, float64(1.0986)}, 223 {0, float64(math.Inf(-1))}, 224 {1.0, float64(0)}, 225 {3.1, float64(1.1314)}, 226 {"abc", false}, 227 } { 228 errMsg := fmt.Sprintf("[%d] %v", i, test) 229 230 result, err := ns.Log(test.a) 231 232 if b, ok := test.expect.(bool); ok && !b { 233 require.Error(t, err, errMsg) 234 continue 235 } 236 237 // we compare only 4 digits behind point if its a real float 238 // otherwise we usually get different float values on the last positions 239 if result != math.Inf(-1) { 240 result = float64(int(result*10000)) / 10000 241 } 242 243 require.NoError(t, err, errMsg) 244 assert.Equal(t, test.expect, result, errMsg) 245 } 246 } 247 248 func TestMod(t *testing.T) { 249 t.Parallel() 250 251 ns := New() 252 253 for i, test := range []struct { 254 a interface{} 255 b interface{} 256 expect interface{} 257 }{ 258 {3, 2, int64(1)}, 259 {3, 1, int64(0)}, 260 {3, 0, false}, 261 {0, 3, int64(0)}, 262 {3.1, 2, int64(1)}, 263 {3, 2.1, int64(1)}, 264 {3.1, 2.1, int64(1)}, 265 {int8(3), int8(2), int64(1)}, 266 {int16(3), int16(2), int64(1)}, 267 {int32(3), int32(2), int64(1)}, 268 {int64(3), int64(2), int64(1)}, 269 {"3", "2", int64(1)}, 270 {"3.1", "2", false}, 271 {"aaa", "0", false}, 272 {"3", "aaa", false}, 273 } { 274 errMsg := fmt.Sprintf("[%d] %v", i, test) 275 276 result, err := ns.Mod(test.a, test.b) 277 278 if b, ok := test.expect.(bool); ok && !b { 279 require.Error(t, err, errMsg) 280 continue 281 } 282 283 require.NoError(t, err, errMsg) 284 assert.Equal(t, test.expect, result, errMsg) 285 } 286 } 287 288 func TestModBool(t *testing.T) { 289 t.Parallel() 290 291 ns := New() 292 293 for i, test := range []struct { 294 a interface{} 295 b interface{} 296 expect interface{} 297 }{ 298 {3, 3, true}, 299 {3, 2, false}, 300 {3, 1, true}, 301 {3, 0, nil}, 302 {0, 3, true}, 303 {3.1, 2, false}, 304 {3, 2.1, false}, 305 {3.1, 2.1, false}, 306 {int8(3), int8(3), true}, 307 {int8(3), int8(2), false}, 308 {int16(3), int16(3), true}, 309 {int16(3), int16(2), false}, 310 {int32(3), int32(3), true}, 311 {int32(3), int32(2), false}, 312 {int64(3), int64(3), true}, 313 {int64(3), int64(2), false}, 314 {"3", "3", true}, 315 {"3", "2", false}, 316 {"3.1", "2", nil}, 317 {"aaa", "0", nil}, 318 {"3", "aaa", nil}, 319 } { 320 errMsg := fmt.Sprintf("[%d] %v", i, test) 321 322 result, err := ns.ModBool(test.a, test.b) 323 324 if test.expect == nil { 325 require.Error(t, err, errMsg) 326 continue 327 } 328 329 require.NoError(t, err, errMsg) 330 assert.Equal(t, test.expect, result, errMsg) 331 } 332 } 333 334 func TestRound(t *testing.T) { 335 t.Parallel() 336 337 ns := New() 338 339 for i, test := range []struct { 340 x interface{} 341 expect interface{} 342 }{ 343 {0.1, 0.0}, 344 {0.5, 1.0}, 345 {1.1, 1.0}, 346 {1.5, 2.0}, 347 {-0.1, -0.0}, 348 {-0.5, -1.0}, 349 {-1.1, -1.0}, 350 {-1.5, -2.0}, 351 {"abc", false}, 352 } { 353 errMsg := fmt.Sprintf("[%d] %v", i, test) 354 355 result, err := ns.Round(test.x) 356 357 if b, ok := test.expect.(bool); ok && !b { 358 require.Error(t, err, errMsg) 359 continue 360 } 361 362 require.NoError(t, err, errMsg) 363 assert.Equal(t, test.expect, result, errMsg) 364 } 365 }