-
Notifications
You must be signed in to change notification settings - Fork 46
/
extensive_test.go
158 lines (143 loc) · 3.9 KB
/
extensive_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package geohash
import (
"math"
"testing"
)
// TestCase objects are generated from independent code to verify we get the
// same results. See testcases_test.go.
type TestCase struct {
hashInt uint64
hash string
lat, lng float64
}
// Test we get the same string geohashes.
func TestEncode(t *testing.T) {
for _, c := range testcases {
hash := Encode(c.lat, c.lng)
if c.hash != hash {
t.Errorf("incorrect encode string result for (%v,%v): %s != %s",
c.lat, c.lng, c.hash, hash)
}
}
}
// Test we get the same integer geohashes.
func TestEncodeInt(t *testing.T) {
for _, c := range testcases {
hashInt := EncodeInt(c.lat, c.lng)
if c.hashInt != hashInt {
t.Errorf("incorrect encode integer result for (%v,%v): %016x != %016x xor %016x",
c.lat, c.lng, c.hashInt, hashInt, c.hashInt^hashInt)
}
}
}
// Verify the prefix property.
func TestPrefixProperty(t *testing.T) {
for _, c := range testcases {
for chars := uint(1); chars <= 12; chars++ {
hash := EncodeWithPrecision(c.lat, c.lng, chars)
pre := c.hash[:chars]
if pre != hash {
t.Errorf("incorrect encode string result for (%v,%v) at precision %d: %s != %s",
c.lat, c.lng, chars, pre, hash)
}
}
}
}
// Verify all string hashes pass validation.
func TestValidate(t *testing.T) {
for _, c := range testcases {
if err := Validate(c.hash); err != nil {
t.Fatalf("unexpected error for %q: %s", c.hash, err)
}
}
}
// Test bounding boxes for string geohashes.
func TestBoundingBox(t *testing.T) {
for _, c := range testcases {
box := BoundingBox(c.hash)
if !box.Contains(c.lat, c.lng) {
t.Errorf("incorrect bounding box for %s", c.hash)
}
}
}
// Test bounding boxes for integer geohashes.
func TestBoundingBoxInt(t *testing.T) {
for _, c := range testcases {
box := BoundingBoxInt(c.hashInt)
if !box.Contains(c.lat, c.lng) {
t.Errorf("incorrect bounding box for 0x%x", c.hashInt)
}
}
}
// Crude test of integer decoding.
func TestDecodeInt(t *testing.T) {
for _, c := range testcases {
lat, lng := DecodeInt(c.hashInt)
if math.Abs(lat-c.lat) > 0.0000001 {
t.Errorf("large error in decoded latitude for 0x%x", c.hashInt)
}
if math.Abs(lng-c.lng) > 0.0000001 {
t.Errorf("large error in decoded longitude for 0x%x", c.hashInt)
}
}
}
func TestConvertStringToInt(t *testing.T) {
for _, c := range testcases {
for chars := uint(1); chars <= 12; chars++ {
hash := c.hash[:chars]
inthash, bits := ConvertStringToInt(hash)
expect := c.hashInt >> (64 - bits)
if inthash != expect {
t.Fatalf("incorrect conversion to integer for %q: got %#x expect %#x", hash, inthash, expect)
}
}
}
}
func TestConvertIntToString(t *testing.T) {
for _, c := range testcases {
for chars := uint(1); chars <= 12; chars++ {
bits := 5 * chars
inthash := c.hashInt >> (64 - bits)
hash := ConvertIntToString(inthash, chars)
expect := c.hash[:chars]
if hash != expect {
t.Fatalf("incorrect conversion to string for %#x: got %q expect %q", inthash, hash, expect)
}
}
}
}
type DecodeTestCase struct {
hash string
box Box
}
// Test decoding at various precisions.
func TestDecode(t *testing.T) {
for _, c := range decodecases {
lat, lng := Decode(c.hash)
if !c.box.Contains(lat, lng) {
t.Errorf("hash %s decoded to %f,%f should lie in %+v",
c.hash, lat, lng, c.box)
}
}
}
// Test decoding at various precisions.
func TestDecodeCenter(t *testing.T) {
for _, c := range decodecases {
lat, lng := DecodeCenter(c.hash)
if !c.box.Contains(lat, lng) {
t.Errorf("hash %s decoded to %f,%f should lie in %+v",
c.hash, lat, lng, c.box)
}
}
}
// Test roundtrip decoding then encoding again.
func TestDecodeThenEncode(t *testing.T) {
for _, c := range decodecases {
precision := uint(len(c.hash))
lat, lng := Decode(c.hash)
rehashed := EncodeWithPrecision(lat, lng, precision)
if c.hash != rehashed {
t.Errorf("hash %s decoded and re-encoded to %s", c.hash, rehashed)
}
}
}