Skip to content

Commit 6b7b5e5

Browse files
oschwaldclaude
andcommitted
test: Add instrumented tests for GPU, Camera, and Font collectors
Add instrumented tests that run on real Android devices/emulators to verify: - GpuCollector: EGL context creation, renderer/vendor info, resource cleanup - CameraCollector: Camera2 API access, facing values, repeated calls - FontCollector: Typeface detection, standard fonts, consistency These tests require actual Android APIs and cannot be mocked in unit tests. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 6f9ffd6 commit 6b7b5e5

File tree

3 files changed

+190
-0
lines changed

3 files changed

+190
-0
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.maxmind.device.collector
2+
3+
import android.hardware.camera2.CameraCharacteristics
4+
import androidx.test.ext.junit.runners.AndroidJUnit4
5+
import androidx.test.platform.app.InstrumentationRegistry
6+
import org.junit.Assert.assertNotNull
7+
import org.junit.Assert.assertTrue
8+
import org.junit.Test
9+
import org.junit.runner.RunWith
10+
11+
/**
12+
* Instrumented tests for [CameraCollector].
13+
*
14+
* These tests run on an Android device/emulator to verify camera info collection
15+
* using real Camera2 API.
16+
*/
17+
@RunWith(AndroidJUnit4::class)
18+
public class CameraCollectorInstrumentedTest {
19+
@Test
20+
public fun collect_returnsCameraListOrEmpty() {
21+
val context = InstrumentationRegistry.getInstrumentation().targetContext
22+
val collector = CameraCollector(context)
23+
24+
val result = collector.collect()
25+
26+
assertNotNull("Camera list should not be null", result)
27+
// Most devices have at least one camera, but emulators may not
28+
}
29+
30+
@Test
31+
public fun collect_cameraInfoHasValidFacing() {
32+
val context = InstrumentationRegistry.getInstrumentation().targetContext
33+
val collector = CameraCollector(context)
34+
35+
val result = collector.collect()
36+
37+
result.forEach { cameraInfo ->
38+
assertNotNull("Camera ID should not be null", cameraInfo.cameraID)
39+
assertTrue(
40+
"Facing should be FRONT (0), BACK (1), or EXTERNAL (2)",
41+
cameraInfo.facing in
42+
listOf(
43+
CameraCharacteristics.LENS_FACING_FRONT,
44+
CameraCharacteristics.LENS_FACING_BACK,
45+
CameraCharacteristics.LENS_FACING_EXTERNAL,
46+
),
47+
)
48+
}
49+
}
50+
51+
@Test
52+
public fun collect_doesNotCrashOnRepeatedCalls() {
53+
val context = InstrumentationRegistry.getInstrumentation().targetContext
54+
val collector = CameraCollector(context)
55+
56+
// Multiple calls should not crash
57+
repeat(3) {
58+
val result = collector.collect()
59+
assertNotNull(result)
60+
}
61+
}
62+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.maxmind.device.collector
2+
3+
import androidx.test.ext.junit.runners.AndroidJUnit4
4+
import org.junit.Assert.assertNotNull
5+
import org.junit.Assert.assertTrue
6+
import org.junit.Test
7+
import org.junit.runner.RunWith
8+
9+
/**
10+
* Instrumented tests for [FontCollector].
11+
*
12+
* These tests run on an Android device/emulator to verify font detection
13+
* using real Android Typeface API.
14+
*/
15+
@RunWith(AndroidJUnit4::class)
16+
public class FontCollectorInstrumentedTest {
17+
@Test
18+
public fun collect_returnsFontInfo() {
19+
val collector = FontCollector()
20+
21+
val result = collector.collect()
22+
23+
assertNotNull("Font info should not be null", result)
24+
assertNotNull("Available fonts list should not be null", result.availableFonts)
25+
}
26+
27+
@Test
28+
public fun collect_detectsRobotoFont() {
29+
val collector = FontCollector()
30+
31+
val result = collector.collect()
32+
33+
// Roboto is always available as the default Android font
34+
// FontCollector only tests fonts from its TEST_FONTS list
35+
assertTrue(
36+
"Roboto font should be available (Android default)",
37+
result.availableFonts.contains("Roboto"),
38+
)
39+
}
40+
41+
@Test
42+
public fun collect_returnsNonEmptyFontList() {
43+
val collector = FontCollector()
44+
45+
val result = collector.collect()
46+
47+
assertTrue(
48+
"Available fonts should not be empty",
49+
result.availableFonts.isNotEmpty(),
50+
)
51+
}
52+
53+
@Test
54+
public fun collect_isConsistentAcrossMultipleCalls() {
55+
val collector = FontCollector()
56+
57+
val result1 = collector.collect()
58+
val result2 = collector.collect()
59+
60+
assertTrue(
61+
"Font list should be consistent across calls",
62+
result1.availableFonts == result2.availableFonts,
63+
)
64+
}
65+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.maxmind.device.collector
2+
3+
import androidx.test.ext.junit.runners.AndroidJUnit4
4+
import org.junit.Assert.assertTrue
5+
import org.junit.Test
6+
import org.junit.runner.RunWith
7+
8+
/**
9+
* Instrumented tests for [GpuCollector].
10+
*
11+
* These tests run on an Android device/emulator to verify GPU info collection
12+
* using real EGL contexts.
13+
*/
14+
@RunWith(AndroidJUnit4::class)
15+
public class GpuCollectorInstrumentedTest {
16+
@Test
17+
public fun collect_returnsGpuInfoOrNullGracefully() {
18+
val collector = GpuCollector()
19+
20+
val result = collector.collect()
21+
22+
// On most devices, GPU info should be available
23+
// On emulators without GPU support, null is acceptable
24+
if (result != null) {
25+
// If we got a result, it should have meaningful data
26+
assertTrue(
27+
"Renderer or vendor should be non-null",
28+
result.renderer != null || result.vendor != null,
29+
)
30+
}
31+
// Test passes whether result is null or non-null
32+
// The key is that it doesn't crash
33+
}
34+
35+
@Test
36+
public fun collect_doesNotCrashOnRepeatedCalls() {
37+
val collector = GpuCollector()
38+
39+
// Multiple calls should not leak EGL resources or crash
40+
repeat(5) {
41+
val result = collector.collect()
42+
// Just verify no crash - result can be null or non-null
43+
}
44+
}
45+
46+
@Test
47+
public fun collect_handlesMultipleCollectorInstances() {
48+
// Verify that multiple collector instances don't interfere
49+
val collector1 = GpuCollector()
50+
val collector2 = GpuCollector()
51+
52+
val result1 = collector1.collect()
53+
val result2 = collector2.collect()
54+
55+
// Results should be consistent (both null or both non-null with same values)
56+
if (result1 != null && result2 != null) {
57+
assertTrue(
58+
"Renderer should be consistent across instances",
59+
result1.renderer == result2.renderer,
60+
)
61+
}
62+
}
63+
}

0 commit comments

Comments
 (0)