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
package social.grain
import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlinx.serialization.json.Json
import okhttp3.OkHttpClient
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import social.grain.data.location.LocationServices
/**
* The H3 cell is the grouping key for a location feed, so it has to agree with
* every other Grain client exactly. These pin the resolution and the known
* reference values rather than trusting that the binding loaded.
*/
@RunWith(AndroidJUnit4::class)
class H3Test {
private val services = LocationServices(OkHttpClient(), Json { ignoreUnknownKeys = true })
@Test
fun theNativeBindingLoadsOnThisDevice() {
assertTrue(
"h3 ships arm and arm64 only — an x86 emulator has no binary",
services.isAvailable,
)
}
@Test
fun theDocumentedReferenceCoordinateProducesItsKnownCell() {
// The H3 project's own worked example: the Statue of Liberty at
// resolution 10. An independent expected value is the only thing that
// proves the binding agrees with other clients — asserting the
// library's output against itself would prove nothing.
assertEquals("8a2a1072b59ffff", services.cellFor(40.689247, -74.044502))
}
@Test
fun aCellCentresBackOnThePointItCameFrom() {
// The location feed's map has only the cell to work from, so the
// reverse conversion has to land inside the ~65m cell it names.
val center = services.coordinateFor("8a2a1072b59ffff")
assertNotNull(center)
assertEquals(40.689247, center!!.latitude, 0.001)
assertEquals(-74.044502, center.longitude, 0.001)
assertEquals("8a2a1072b59ffff", services.cellFor(center.latitude, center.longitude))
}
@Test
fun aCellAddressThatIsNotOneYieldsNoCoordinate() {
assertNull(services.coordinateFor("not-a-cell"))
}
@Test
fun aCellAddressIsFifteenHexCharacters() {
val cell = services.cellFor(51.5074, -0.1278)
assertNotNull(cell)
assertEquals(15, cell!!.length)
assertTrue("not hex: $cell", cell.all { it.isDigit() || it in 'a'..'f' })
}
@Test
fun nearbyPointsShareACellAndDistantOnesDoNot() {
// Resolution 10 cells are roughly 65m across, so a few metres apart is
// the same cell and a kilometre away is not.
val base = services.cellFor(37.775938, -122.41795)
assertEquals(base, services.cellFor(37.775940, -122.417952))
assertTrue(base != services.cellFor(37.785938, -122.41795))
}
}