route/vendor/github.com/aclements/go-moremath/scale/log_test.go

189 lines
5.5 KiB
Go

// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package scale
import (
"fmt"
"math"
"testing"
"github.com/aclements/go-moremath/internal/mathtest"
"github.com/aclements/go-moremath/vec"
)
func TestLog(t *testing.T) {
l, err := NewLog(0, 10, 10)
if _, ok := err.(RangeErr); !ok {
t.Errorf("want RangeErr; got %v", err)
}
l, err = NewLog(-10, 0, 10)
if _, ok := err.(RangeErr); !ok {
t.Errorf("want RangeErr; got %v", err)
}
l, err = NewLog(-10, 10, 10)
if _, ok := err.(RangeErr); !ok {
t.Errorf("want RangeErr; got %v", err)
}
l, err = NewLog(10, 20, 0)
if _, ok := err.(RangeErr); !ok {
t.Errorf("want RangeErr; got %v", err)
}
l, _ = NewLog(1, 10, 10)
mathtest.WantFunc(t, fmt.Sprintf("%v.Map", l), l.Map,
map[float64]float64{
-1: math.NaN(),
0: math.NaN(),
0.1: -1,
1: 0,
math.Pow(10, 0.5): 0.5,
10: 1,
100: 2,
})
mathtest.WantFunc(t, fmt.Sprintf("%v.Unmap", l), l.Unmap,
map[float64]float64{
-1: 0.1,
0: 1,
0.5: math.Pow(10, 0.5),
1: 10,
2: 100,
})
l.SetClamp(true)
mathtest.WantFunc(t, fmt.Sprintf("%v.Map", l), l.Map,
map[float64]float64{
-1: math.NaN(),
0: math.NaN(),
0.1: 0,
1: 0,
math.Pow(10, 0.5): 0.5,
10: 1,
100: 1,
})
mathtest.WantFunc(t, fmt.Sprintf("%v.Unmap", l), l.Unmap,
map[float64]float64{
0: 1,
0.5: math.Pow(10, 0.5),
1: 10,
})
l, _ = NewLog(-1, -10, 10)
mathtest.WantFunc(t, fmt.Sprintf("%v.Map", l), l.Map,
map[float64]float64{
1: math.NaN(),
0: math.NaN(),
-0.1: 2,
-1: 1,
-math.Pow(10, 0.5): 0.5,
-10: 0,
-100: -1,
})
mathtest.WantFunc(t, fmt.Sprintf("%v.Unmap", l), l.Unmap,
map[float64]float64{
2: -0.1,
1: -1,
0.5: -math.Pow(10, 0.5),
0: -10,
-1: -100,
})
l, _ = NewLog(5, 5, 10)
mathtest.WantFunc(t, fmt.Sprintf("%v.Map", l), l.Map,
map[float64]float64{
-1: math.NaN(),
0: math.NaN(),
1: 0.5,
10: 0.5,
})
mathtest.WantFunc(t, fmt.Sprintf("%v.Unmap", l), l.Unmap,
map[float64]float64{
0: 5,
0.5: 5,
1: 5,
})
}
func TestLogTicks(t *testing.T) {
m := func(m int) TickOptions {
return TickOptions{Max: m}
}
// Test the obvious.
l, _ := NewLog(1, 10, 10)
major, minor := l.Ticks(m(5))
wmajor, wminor := vec.Logspace(0, 1, 2, 10), vec.Linspace(1, 10, 10)
if !ticksEq(major, wmajor, minor, wminor) {
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
}
// Test two orders of magnitude.
l, _ = NewLog(1, 100, 10)
major, minor = l.Ticks(m(5))
wmajor, wminor = vec.Logspace(0, 2, 3, 10), vec.Concat(vec.Linspace(1, 9, 9), vec.Linspace(10, 100, 10))
if !ticksEq(major, wmajor, minor, wminor) {
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
}
// Test many orders of magnitude (higher tick levels).
l, _ = NewLog(1, 1e8, 10)
major, minor = l.Ticks(m(5))
wmajor, wminor = vec.Logspace(0, 4, 5, 100), vec.Logspace(0, 8, 9, 10)
if !ticksEq(major, wmajor, minor, wminor) {
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
}
major, minor = l.Ticks(m(4))
wmajor, wminor = vec.Logspace(0, 2, 3, 10000), vec.Logspace(0, 4, 5, 100)
if !ticksEq(major, wmajor, minor, wminor) {
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
}
// Test minor ticks outside major ticks.
l, _ = NewLog(0.91, 200, 10)
major, minor = l.Ticks(m(5))
wmajor, wminor = vec.Logspace(0, 2, 3, 10), vec.Concat(vec.Linspace(1, 9, 9), vec.Linspace(10, 100, 10), []float64{200})
if !ticksEq(major, wmajor, minor, wminor) {
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
}
// Test nicing.
l.Nice(m(5))
major, minor = l.Ticks(m(5))
wmajor, wminor = vec.Logspace(-1, 3, 5, 10), vec.Concat(vec.Linspace(0.1, 0.9, 9), vec.Linspace(1, 9, 9), vec.Linspace(10, 90, 9), vec.Linspace(100, 1000, 10))
if !ticksEq(major, wmajor, minor, wminor) {
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
}
// Test negative ticks.
neg := vec.Vectorize(func(x float64) float64 { return -x })
l, _ = NewLog(-1, -100, 10)
major, minor = l.Ticks(m(5))
wmajor, wminor = neg(vec.Logspace(2, 0, 3, 10)), neg(vec.Concat(vec.Linspace(100, 10, 10), vec.Linspace(9, 1, 9)))
if !ticksEq(major, wmajor, minor, wminor) {
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
}
major, minor = l.Ticks(m(2))
wmajor, wminor = neg(vec.Logspace(1, 0, 2, 100)), neg(vec.Logspace(2, 0, 3, 10))
if !ticksEq(major, wmajor, minor, wminor) {
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
}
l.Nice(m(5))
major, minor = l.Ticks(m(5))
wmajor, wminor = neg(vec.Logspace(2, 0, 3, 10)), neg(vec.Concat(vec.Linspace(100, 10, 10), vec.Linspace(9, 1, 9)))
if !ticksEq(major, wmajor, minor, wminor) {
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
}
// Test Min==Max.
l, _ = NewLog(5, 5, 10)
major, minor = l.Ticks(m(5))
wmajor, wminor = []float64{5}, []float64{5}
if !ticksEq(major, wmajor, minor, wminor) {
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
}
}