# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

Kotest is a Kotlin Multiplatform testing framework providing test specs, assertions, and property testing. It targets JVM, JS, Wasm, and Native platforms.

## Build Commands

```bash
# Full check (all platforms)
./gradlew check

# JVM-only (fastest for local dev)
./gradlew check -PjvmOnly=true

# Specific platform combinations
./gradlew check -Pkotest_enableKotlinJs=false -Pkotest_enableKotlinNative=false

# Run tests for a specific module
./gradlew :kotest-assertions:kotest-assertions-core:jvmTest
./gradlew :kotest-framework:kotest-framework-engine:jvmTest

# API compatibility validation (required before PRs that change public API)
./gradlew apiCheck

# Regenerate API dumps after public API changes
./gradlew apiDump
```

## Code Style

- **3-space indentation** (not 4) — configured in `.editorconfig`
- Max line length: 120 characters
- No star imports in Kotlin
- Follow [Kotlin Coding Conventions](https://kotlinlang.org/docs/coding-conventions.html)

## Architecture

### Module Organization

- **kotest-common** — Shared multiplatform utilities
- **kotest-framework/kotest-framework-engine** — Core test execution engine (multiplatform). Contains `Spec`, `TestCase`, `TestEngine`
- **kotest-assertions/kotest-assertions-shared** — Base `Matcher` interface and assertion counters
- **kotest-assertions/kotest-assertions-core** — Standard matchers for String, Int, collections, etc.
- **kotest-property** — Property-based testing with `Arb<T>` generators and shrinking
- **kotest-property/kotest-property-permutations** — 6.0+ combinatorial permutation DSL
- **kotest-runner/kotest-runner-junit5** — JUnit 5 Platform integration (primary JVM runner)
- **kotest-extensions/** — Integration modules (Spring, Testcontainers, Koin, etc.)
- **kotest-tests/** — ~40 JVM-only test modules covering specific scenarios

### Key Abstractions

- **Spec** — Base class for test classes. Styles: `FunSpec`, `StringSpec`, `ShouldSpec`, `WordSpec`, `BehaviorSpec`, `DescribeSpec`, `FeatureSpec`, `FreeSpec`, `ExpectSpec`
- **TestCase** — Represents a single test with config, name, and parent reference
- **Matcher<T>** — Core assertion interface; used via `should`/`shouldNot` infix DSL
- **Arb<T>** — Arbitrary generator for property testing with shrinking support
- **Extension** — Lifecycle hooks registered globally via `ProjectConfig` or per-Spec

### Kotlin Multiplatform Source Sets

Multiplatform modules use this hierarchy:
```
commonMain / commonTest
├── jvmMain / jvmTest
├── jsMain / jsTest
├── wasmJsMain / wasmJsTest
├── nativeMain / nativeTest (further split: linux, macOS, mingw, iOS, tvOS, watchOS)
└── nonjvmMain (shared non-JVM code)
```

### Build Logic (buildSrc)

Convention plugins in `buildSrc/src/main/kotlin/`:
- `kotest-base` — Shared base config
- `kotlin-conventions` — Kotlin multiplatform setup, compiler options
- `kotest-jvm-conventions` — JVM target + JUnit Platform
- `kotest-js-wasm-conventions` — JS + Wasm targets
- `kotest-native-conventions` — Native targets with platform hierarchy
- `kotest-multiplatform-library-conventions` — Combines JVM + JS + Native + publishing
- `kotest-publishing-conventions` — Maven Central publishing and signing

Platform targets are controlled by Gradle properties:
- `jvmOnly=true` — Skip all non-JVM targets
- `kotest_enableKotlinJs=true/false`
- `kotest_enableKotlinNative=true/false`

### Binary Compatibility

Uses Kotlin Binary Compatibility Validator. API dumps live in `.api/` directories per module. Run `./gradlew apiDump` after any public API change and commit the updated `.api` files. Classes annotated `@KotestInternal` are excluded from validation.

### Versioning

Version is defined in `buildSrc/src/main/kotlin/Ci.kt`. Local builds produce `X.Y.Z-LOCAL`, CI builds produce `X.Y.Z.{BUILD_NUMBER}-SNAPSHOT`, and releases are set via `RELEASE_VERSION` env var.