Skip to content

Testing

Run the full core test suite:

Terminal window
./gradlew :isometric-core:test

Run a specific test class:

Terminal window
./gradlew :isometric-core:test --tests "io.fabianterhorst.isometric.IsoColorTest"

Run a single test method:

Terminal window
./gradlew :isometric-core:test --tests "io.fabianterhorst.isometric.IsoColorTest.testFromHexString"

The core module has unit tests covering all fundamental types:

Test ClassCovers
IsoColorTestColor construction, HSL conversion, fromHex, lighten, toRGBA, named constants
PointTestPoint arithmetic, translation, rotation, scaling, depth calculation
Point2DTest2D point operations
VectorTestVector operations, dot product, cross product, normalization
PathTestPath construction, transforms, closerThan depth comparison, reversal
ShapeTestShape construction, transforms, extrusion, orderedPaths
CircleTestCircle path generation with configurable vertex count
IsometricEngineTestEngine construction, add/clear, projectScene, hit testing
IsometricEngineProjectionTestworldToScreen, screenToWorld round-trip accuracy
TileCoordinateTestConstruction, equals/hashCode/toString, plus/minus operators, isWithin, toPoint, ORIGIN
TileGridConfigTestDefault values, tileSize validation, elevation lambda storage, equals/hashCode (elevation excluded), toString
TileCoordinateExtensionsTestPoint.toTileCoordinate with positive/negative/boundary coords, floor-not-truncation, screenToTile round-trip
StackAxisTestAll three enum values, unitPoint() unit vectors, one-non-zero-component invariant

Pre-WS9 test files are located under:

isometric-core/src/test/kotlin/io/fabianterhorst/isometric/

WS9 and later test files use the updated package:

isometric-core/src/test/kotlin/io/github/jayteealao/isometric/

The compose module also has instrumented tests that run on a device or emulator:

Test ClassCovers
TileGridTestPer-tile content invocation, bounds enforcement, onTileClick wiring, elevation function inputs
StackTestItem count, axis directions, gap validation, negative gap, nested stacks
Terminal window
./gradlew :isometric-compose:connectedAndroidTest

DocScreenshotGenerator is a test-based tool that renders scenes to PNG files using a headless AWT BufferedImage. This is how the documentation screenshots are produced.

Terminal window
./gradlew :isometric-core:test --tests "io.fabianterhorst.isometric.DocScreenshotGenerator"

Generated images are written to docs/assets/screenshots/. After generating, copy them to the docs site:

Terminal window
cp docs/assets/screenshots/*.png site/public/screenshots/

DocScreenshotGenerator uses AwtRenderer (a test utility in the same source set) to draw RenderCommand output from IsometricEngine onto a BufferedImage. The renderer converts each command’s Point2D polygon into an AWT Polygon and fills it with the computed color.

This approach avoids any Android or Compose dependency, keeping screenshot generation runnable on any JVM.

Place test files in the same package structure as the source:

isometric-core/src/test/kotlin/io/fabianterhorst/isometric/

For shape-specific tests:

isometric-core/src/test/kotlin/io/fabianterhorst/isometric/shapes/
  • Test classes: {ClassName}Test.kt (e.g., PrismTest.kt)
  • Test methods: descriptive names using backticks or camelCase (e.g., `translate returns new instance with offset position` or testTranslateReturnsNewInstance)
package io.fabianterhorst.isometric.shapes
import io.fabianterhorst.isometric.Point
import org.junit.Assert.assertEquals
import org.junit.Test
class PrismTest {
@Test
fun `default prism has unit dimensions`() {
val prism = Prism()
assertEquals(1.0, prism.width, 0.0)
assertEquals(1.0, prism.depth, 0.0)
assertEquals(1.0, prism.height, 0.0)
}
@Test
fun `translate returns new prism with offset position`() {
val prism = Prism(Point.ORIGIN)
val moved = prism.translate(1.0, 2.0, 3.0)
assertEquals(1.0, moved.position.x, 1e-10)
assertEquals(2.0, moved.position.y, 1e-10)
assertEquals(3.0, moved.position.z, 1e-10)
}
@Test(expected = IllegalArgumentException::class)
fun `negative width throws`() {
Prism(width = -1.0)
}
}
  1. Test behavior, not implementation. Verify that translate returns correct coordinates, not that it calls a specific internal method.
  2. Test edge cases. Zero dimensions, negative values, very large scales, NaN inputs.
  3. Test immutability. Verify that transform methods return new instances and do not mutate the original.
  4. Use tolerance for floating-point comparisons. Always use assertEquals(expected, actual, tolerance) with a tolerance like 1e-10.
  5. Validate error messages. When testing require / IllegalArgumentException, verify the message string contains the expected description.