| Dimension | Shared | Only in A | Only in B | Overlap |
|---|---|---|---|---|
| Sections | 0 | 10 | 14 | 0% |
| Commands | 0 | 0 | 6 | 0% |
| Section tags | 3 | 1 | 2 | 50% |
What each file covers
Sections
0 shared · 10 only in A · 14 only in B- − Test Data Manager - Agent Guidelines
- − Module Overview
- − Testing Guidelines (for tests within this module)
- − Core Principles
- − Testing Patterns
- − Usage from Other Modules
- − Implementing ManagedTest
- − Using Assertions
- − Behavior Matrix
- − Key Classes Reference
- + Analysis API Guidelines
- + Architecture
- + Relationship with PSI
- + Key Conventions
- + Working with Test Data
- + `updateTestData` — the only recommended way to update test data
- + Update test data by directory (preferred for iteration)
- + Update test data by test class pattern
- + Run only golden tests (useful for quick baseline updates)
- + Incremental update — only re-run variant tests for changed paths
- + Limit to a subset of modules using task paths (Gradle task-name matching)
- + `checkTestData` — verification only
- + Key Components
- + Detailed Documentation
Commands
0 shared · 0 only in A · 6 only in B- + ./gradlew updateTestData -Porg.jetbrains.kotlin.testDataManager.options.testDataPath=analysis/analysis-api/testData/components/resolver/
- + ./gradlew updateTestData -Porg.jetbrains.kotlin.testDataManager.options.testClassPattern=.*ResolveTest.*
- + ./gradlew updateTestData -Porg.jetbrains.kotlin.testDataManager.options.goldenOnly=true
- + ./gradlew updateTestData -Porg.jetbrains.kotlin.testDataManager.options.incremental=true
- + ./gradlew :analysis:analysis-api-fir:updateTestData :analysis:stubs:updateTestData
- + ./gradlew checkTestData -Porg.jetbrains.kotlin.testDataManager.options.testDataPath=analysis/analysis-api/testData/components/resolver/singleByPsi/
Section tags
3 shared · 1 only in A · 2 only in B- − agent-behaviour
- + api
- + docs
- test
- code-style
- architecture
Line diff
JetBrains/kotlin · analysis/test-data-manager/AGENTS.md
@@ −1 @@
1# Test Data Manager - Agent Guidelines
2
3Automated system for managing test data files across multiple test configurations.
4
5## Module Overview
6
7This module provides infrastructure for:
8- Comparing test outputs with expected files using variant chains
9- Automatic file management (creation, update, redundancy removal)
10- Test discovery, grouping, and conflict detection
11
12**Structure:**
13- `testFixtures/` — Runtime API for use by other modules
14- `tests/` — Module's own test suite
15
16For conceptual details (variant chains, conflicts, convergence), see [README.md](README.md).
17For running test data management tasks (checking/updating test data via Gradle), see [test-data-manager-convention](../../repo/gradle-build-conventions/test-data-manager-convention/README.md).
18
19## Testing Guidelines (for tests within this module)
20
21### Core Principles
22
231. **Readable multi-line string expectations** — Format results as human-readable strings, compare with `assertEquals`
242. **Custom formatters** — Create formatters that produce deterministic, readable output
253. **Domain-specific assertion helpers** — Encapsulate complex assertions in named functions
264. **Descriptive test names** — Use backticks with clear descriptions
27
28### Testing Patterns
29
30#### Pattern 1: Readable Output Formatting
31
32Create formatters that produce deterministic, human-readable output for complex results.
33
34From `TestDiscoveryAndGroupingIntegrationTest.kt`:
35
36```kotlin
37private fun formatResult(result: GroupingResult): String = buildString {
38 for (group in result.groups) {
39 val header = if (group.variantDepth == 0) "Group 0 (golden)" else "Group ${group.variantDepth}"
40 appendLine("=== $header ===")
41 for (test in group.tests.sortedBy { it.displayName }) {
42 appendLine("${test.displayName} -> ${test.variantChain}")
43 }
44 appendLine()
45 }
46}.trimEnd()
47
48@Test
49fun `discovery finds all tests`() {
50 val result = runDiscovery()
51 assertEquals(expected.trimIndent(), formatResult(result))
52}
53```
54
55#### Pattern 2: Domain-Specific Assertions
56
57Encapsulate complex assertions in helper functions with clear names.
58
59From `TestDataManagerGroupingTest.kt`:
60
61```kotlin
62private fun assertGrouping(tests: List<DiscoveredTest>, expected: String) {
63 val result = groupByVariantDepth(tests)
64 val actual = result.groups.joinToString("\n") { group ->
65 "depth=${group.variantDepth}: ${group.uniqueVariantChains.joinToString(", ")}"
66 }
67 assertEquals(expected.trimIndent(), actual)
68}
69
70private fun assertConflicts(tests: List<DiscoveredTest>, expected: String) {
71 val conflicts = validateConflicts(tests)
72 val actual = conflicts.joinToString("\n") {
73 "${it.chainA} vs ${it.chainB}: '${it.conflictingVariant}'"
74 }
75 assertEquals(expected.trimIndent(), actual)
76}
77
78@Test
79fun `tests grouped by variant depth`() {
80 assertGrouping(
81 tests = listOf(
82 DiscoveredTest("1", "golden", emptyList()),
83 DiscoveredTest("2", "js", listOf("js")),
84 ),
85 expected = """
86 depth=0: []
87 depth=1: [js]
88 """
89 )
90}
91```
92
93#### Pattern 3: State-Based Testing with Setup/Assert Helpers
94
95For file-based operations, use setup and assertion helpers.
96
97From `ManagedTestAssertionsTest.kt`:
98
99```kotlin
100private fun assertFileState(expected: String) {
101 val actual = listOf("test.txt", "test.js.txt").mapNotNull { name ->
102 val file = tempDir.resolve(name)
103 if (file.exists()) "$name: ${file.readText().trim()}" else null
104 }.joinToString("\n")
105 assertEquals(expected.trimIndent(), actual)
106}
107
108private fun setupFiles(vararg files: Pair<String, String>) {
109 for ((name, content) in files) {
110 tempDir.resolve(name).writeText("$content\n")
111 }
112}
113
114@Test
115fun `UPDATE mode - mismatch updates file`() {
116 setupFiles("test.txt" to "old")
117 runAssertion(variantChain = emptyList(), actual = "new")
118 assertFileState("test.txt: new")
119}
120```
121
122#### Pattern 4: Filter Testing with Base Class
123
124For JUnit filter tests, extend `AbstractPostDiscoveryFilterTest`.
125
126From `ManagedTestFilterTest.kt`:
127
128```kotlin
129internal class ManagedTestFilterTest : AbstractPostDiscoveryFilterTest() {
130 @Test
131 fun `ClassSource with ManagedTest is included`() {
132 assertIncluded(
133 filter = ManagedTestFilter,
134 descriptor = descriptorFromClass<FakeGoldenAnalysisApiTestGenerated>(),
135 )
136 }
137
138 @Test
139 fun `ClassSource without ManagedTest is excluded`() {
140 assertExcluded(
141 filter = ManagedTestFilter,
142 descriptor = descriptorFromClass<NoMetadataClass>(),
143 )
144 }
145}
146```
147
148Available utilities from `AbstractPostDiscoveryFilterTest`:
149- `assertIncluded(filter, descriptor)` / `assertExcluded(filter, descriptor)`
150- `descriptorFromClass<T>()` — Create descriptor from class
151- `descriptorFromMethod(method)` — Create descriptor from method reference
152- `descriptorWithSource(source)` — Create descriptor with custom source
153
154#### Pattern 5: Fake Test Classes for Integration Testing
155
156Create fake test classes in `tests/.../fakes/` to simulate real test configurations.
157
158```kotlin
159// Base class for all fakes
160abstract class FakeManagedTest : ManagedTest
161
162// Golden test (no variant)
163@TestMetadata("testData/analysis/api")
164class FakeGoldenAnalysisApiTestGenerated : FakeManagedTest() {
165 override val variantChain = emptyList<String>()
166
167 @Test
168 @TestMetadata("symbols.kt")
169 fun testSymbols() {}
170}
171
172// Multi-level variant test
173@TestMetadata("testData/lightClasses")
174class FakeWasmLightClassesTestGenerated : FakeManagedTest() {
175 override val variantChain = listOf("knm", "wasm")
176
177 @Test
178 @TestMetadata("simple.kt")
179 fun testSimple() {}
180}
181```
182
183## Usage from Other Modules
184
185### Implementing ManagedTest
186
187Implement `ManagedTest` interface and provide variant chain:
188
189```kotlin
190abstract class MyTestBase : ManagedTest {
191 override val variantChain: List<String>
192 get() = emptyList()
193}
194```
195
196Variant chain rules:
197- `[]` (empty) — Golden/default configuration, writes to `.txt`
198- `["js"]` — Single variant, writes to `.js.txt`
199- `["knm", "wasm"]` — Multi-level variant, writes to `.wasm.txt` (last element only)
200
201### Using Assertions
202
203Use the extension function `ManagedTest.assertEqualsToTestDataFile()` for comparing test output:
204
205```kotlin
206class MyTest : ManagedTest {
207 override val variantChain = listOf("js")
208
209 fun runTest(testDataFile: File) {
210 val actual = computeResult()
211 assertEqualsToTestDataFile(
212 testDataPath = testDataFile.toPath(),
213 actual = actual,
214 extension = ".txt",
215 )
216 }
217}
218```
219
220Or use `ManagedTestAssertions.assertEqualsToTestDataFile()` directly:
221
222```kotlin
223ManagedTestAssertions.assertEqualsToTestDataFile(
224 testDataPath = testDataFile.toPath(),
225 actual = actualContent,
226 variantChain = variantChain,
227 extension = ".txt",
228)
229```
230
231
232### Behavior Matrix
233
234| Scenario | UPDATE mode | CHECK mode (local) | CHECK mode (CI) |
235|---------------------------|-------------|--------------------|-----------------|
236| actual=null, file missing | Pass | Pass | Pass |
237| actual=null, file exists | Delete | Delete + throw | Throw |
238| File missing (golden) | Create | Create + throw | Throw |
239| File missing (secondary) | Create | Throw | Throw |
240| Content matches | Pass | Pass | Pass |
241| Write-target redundant | Delete | Delete + throw | Throw |
242| Content mismatch | Update | Throw | Throw |
243
244## Key Classes Reference
245
246| Class | Location | Purpose |
247|--------------------------|----------------------|--------------------------------------------------|
248| `ManagedTest` | testFixtures | Interface for tests managed by the system |
249| `ManagedTestAssertions` | testFixtures | Assertion functions for test data comparison |
250| `TestDataManagerRunner` | testFixtures | Main runner (discovery, grouping, execution) |
251| `TestDataContext` | testFixtures | File path resolution and mode for variant chains |
252| `ManagedTestFilter` | testFixtures/filters | JUnit filter for ManagedTest implementations |
253| `TestMetadataFilter` | testFixtures/filters | JUnit filter by @TestMetadata paths |
254| `VariantChainComparator` | testFixtures | Orders variant chains by depth |
255
JetBrains/kotlin · analysis/AGENTS.md
@@ +1 @@
1# Analysis API Guidelines
2
3A library for analyzing Kotlin code at the semantic level, providing structured access to symbols, types, and semantic relationships.
4
5**Entry point:** Use [`analyze()`](analysis-api/src/org/jetbrains/kotlin/analysis/api/analyze.kt) to start an analysis session. See [Analysis API documentation](https://kotl.in/analysis-api) for a usage guide.
6
7## Architecture
8
9- **Platform** — Provides declarations, project structure, and modification events (IntelliJ, Standalone)
10- **Engine** — Performs code analysis using platform-provided information (K1, K2)
11- **User** — Code that calls `analyze()` to work with symbols and types
12
13→ READ [`analysis-api-platform-interface/README.md`](analysis-api-platform-interface/README.md) for detailed architecture overview
14
15## Relationship with PSI
16
17Analysis API builds on top of Kotlin PSI (`compiler/psi/`):
18- **PSI** provides syntax (structure of code): `KtElement`, `KtExpression`, `KtDeclaration`
19- **Analysis API** provides semantics (meaning of code): `KaSymbol`, `KaType`
20
21```
22PSI (syntax) → Analysis API (semantics) → Symbols, Types, Resolution
23```
24
25**Both PSI and Analysis API follow shared development principles** documented in [`docs/contribution-guide/api-development.md`](docs/contribution-guide/api-development.md).
26
27WHEN working with PSI elements:
28→ READ [`compiler/psi/AGENTS.md`](../compiler/psi/AGENTS.md) for PSI-specific rules and conventions
29
30## Key Conventions
31
32- `Ka` prefix for Analysis API types, `Kt` for PSI types
33- Prefer interfaces to classes for better binary compatibility
34- Properties for attributes, functions for actions with parameters
35- Return nullable types for operations that can fail (avoid exceptions for non-exceptional cases)
36- All implementations must validate lifetime ownership with `withValidityAssertion`
37- Mark experimental APIs with `@KaExperimentalApi`, implementation details with `@KaImplementationDetail`
38
39## Working with Test Data
40
41When modifying test data files or running generated tests (`*Generated`) that compare output against `.txt` files, use `updateTestData` (to rewrite files) or `checkTestData` (to verify only) instead of standard test commands. Both take their options as `-P` properties, so changing filters between runs stays fast.
42
43### `updateTestData` — the only recommended way to update test data
44
45```bash
46# Update test data by directory (preferred for iteration)
47./gradlew updateTestData -Porg.jetbrains.kotlin.testDataManager.options.testDataPath=analysis/analysis-api/testData/components/resolver/
48
49# Update test data by test class pattern
50./gradlew updateTestData -Porg.jetbrains.kotlin.testDataManager.options.testClassPattern=.*ResolveTest.*
51
52# Run only golden tests (useful for quick baseline updates)
53./gradlew updateTestData -Porg.jetbrains.kotlin.testDataManager.options.goldenOnly=true
54
55# Incremental update — only re-run variant tests for changed paths
56./gradlew updateTestData -Porg.jetbrains.kotlin.testDataManager.options.incremental=true
57
58# Limit to a subset of modules using task paths (Gradle task-name matching)
59./gradlew :analysis:analysis-api-fir:updateTestData :analysis:stubs:updateTestData
60```
61
62`updateTestData` is fixed to update mode. There is no `updateTestDataGlobally` — Gradle's task-name matching runs the task in every applicable subproject when invoked from the repo root.
63
64### `checkTestData` — verification only
65
66If you specifically need to verify that existing test data is consistent without modifying anything (e.g., sanity-checking generated files after an `updateTestData` run), use `checkTestData`. It is the exact `-P`-driven counterpart of `updateTestData` but fixed to check mode: it fails on any mismatch and writes nothing.
67
68```bash
69./gradlew checkTestData -Porg.jetbrains.kotlin.testDataManager.options.testDataPath=analysis/analysis-api/testData/components/resolver/singleByPsi/
70```
71
72Use this only for verification. For any workflow that writes test data, use `updateTestData`.
73
74**Why use these tasks instead of plain `:test`?**
75- Run only relevant tests (filtered by path or class pattern)
76- Handle variant chains correctly (golden `.txt` files run before variant-specific `.js.txt`, `.wasm.txt`, etc.)
77- Automatically discover all modules that use managed test data
78- Detect and remove redundant variant files
79
80For full options, see [test-data-manager-convention](../repo/gradle-build-conventions/test-data-manager-convention/README.md).
81
82## Key Components
83
84- [`analysis-api/`](analysis-api) - User-facing API surface (`KaSession`, `KaSymbol`, `KaType`)
85- [`analysis-api-platform-interface/`](analysis-api-platform-interface) - Platform abstraction (declaration providers, project structure, lifetime)
86- [`analysis-api-standalone/`](analysis-api-standalone) - CLI-based implementation of the Analysis API
87- [`analysis-api-fir/`](analysis-api-fir) - K2 implementation based on FIR
88- [`analysis-api-impl-base/`](analysis-api-impl-base) - Shared implementation utilities
89- [`low-level-api-fir/`](low-level-api-fir) - K2-specific infrastructure for lazy/incremental analysis
90- [`symbol-light-classes/`](symbol-light-classes) - Java PSI view of Kotlin declarations for interop
91- [`decompiled/light-classes-for-decompiled`](decompiled/light-classes-for-decompiled) - Light classes for decompiled/library code
92- [`test-data-manager/`](test-data-manager) - Infrastructure for managing test data files with variant chains
93
94## Detailed Documentation
95
96WHEN adding or modifying API endpoints:
97→ READ [`docs/contribution-guide/api-development.md`](docs/contribution-guide/api-development.md)
98
99WHEN deprecating API or understanding stability categories:
100→ READ [`docs/contribution-guide/api-evolution.md`](docs/contribution-guide/api-evolution.md)
101
102WHEN implementing platform components:
103→ READ [`analysis-api-platform-interface/README.md`](analysis-api-platform-interface/README.md)
104
105WHEN working with light classes:
106→ READ [`symbol-light-classes/README.md`](symbol-light-classes/README.md)
107
108WHEN working with lazy resolution (LL API):
109→ READ [`low-level-api-fir/README.md`](low-level-api-fir/README.md)
110
111WHEN writing or managing test data files:
112→ READ [`test-data-manager/AGENTS.md`](test-data-manager/AGENTS.md)
113
114WHEN seeking historical context on design decisions:
115→ READ [`docs/design-documents/README.md`](docs/design-documents/README.md) (these are historical snapshots, not necessarily up to date)
116
117WHEN working with stubs:
118→ READ [`stubs/README.md`](stubs/README.md)
119
@@ −1 +1 @@
1−# Test Data Manager - Agent Guidelines
1+# Analysis API Guidelines
22
3−Automated system for managing test data files across multiple test configurations.
3+A library for analyzing Kotlin code at the semantic level, providing structured access to symbols, types, and semantic relationships.
44
5−## Module Overview
5+**Entry point:** Use [`analyze()`](analysis-api/src/org/jetbrains/kotlin/analysis/api/analyze.kt) to start an analysis session. See [Analysis API documentation](https://kotl.in/analysis-api) for a usage guide.
66
7−This module provides infrastructure for:
8−- Comparing test outputs with expected files using variant chains
9−- Automatic file management (creation, update, redundancy removal)
10−- Test discovery, grouping, and conflict detection
7+## Architecture
118
12−**Structure:**
13−- `testFixtures/` — Runtime API for use by other modules
14−- `tests/` — Module's own test suite
9+- **Platform** — Provides declarations, project structure, and modification events (IntelliJ, Standalone)
10+- **Engine** — Performs code analysis using platform-provided information (K1, K2)
11+- **User** — Code that calls `analyze()` to work with symbols and types
1512
16−For conceptual details (variant chains, conflicts, convergence), see [README.md](README.md).
17−For running test data management tasks (checking/updating test data via Gradle), see [test-data-manager-convention](../../repo/gradle-build-conventions/test-data-manager-convention/README.md).
13+→ READ [`analysis-api-platform-interface/README.md`](analysis-api-platform-interface/README.md) for detailed architecture overview
1814
19−## Testing Guidelines (for tests within this module)
15+## Relationship with PSI
2016
21−### Core Principles
17+Analysis API builds on top of Kotlin PSI (`compiler/psi/`):
18+- **PSI** provides syntax (structure of code): `KtElement`, `KtExpression`, `KtDeclaration`
19+- **Analysis API** provides semantics (meaning of code): `KaSymbol`, `KaType`
2220
23−1. **Readable multi-line string expectations** — Format results as human-readable strings, compare with `assertEquals`
24−2. **Custom formatters** — Create formatters that produce deterministic, readable output
25−3. **Domain-specific assertion helpers** — Encapsulate complex assertions in named functions
26−4. **Descriptive test names** — Use backticks with clear descriptions
27−
28−### Testing Patterns
29−
30−#### Pattern 1: Readable Output Formatting
31−
32−Create formatters that produce deterministic, human-readable output for complex results.
33−
34−From `TestDiscoveryAndGroupingIntegrationTest.kt`:
35−
36−```kotlin
37−private fun formatResult(result: GroupingResult): String = buildString {
38− for (group in result.groups) {
39− val header = if (group.variantDepth == 0) "Group 0 (golden)" else "Group ${group.variantDepth}"
40− appendLine("=== $header ===")
41− for (test in group.tests.sortedBy { it.displayName }) {
42− appendLine("${test.displayName} -> ${test.variantChain}")
43− }
44− appendLine()
45− }
46−}.trimEnd()
47−
48−@Test
49−fun `discovery finds all tests`() {
50− val result = runDiscovery()
51− assertEquals(expected.trimIndent(), formatResult(result))
52−}
5321 ```
22+PSI (syntax) → Analysis API (semantics) → Symbols, Types, Resolution
23+```
5424
55−#### Pattern 2: Domain-Specific Assertions
25+**Both PSI and Analysis API follow shared development principles** documented in [`docs/contribution-guide/api-development.md`](docs/contribution-guide/api-development.md).
5626
57−Encapsulate complex assertions in helper functions with clear names.
27+WHEN working with PSI elements:
28+→ READ [`compiler/psi/AGENTS.md`](../compiler/psi/AGENTS.md) for PSI-specific rules and conventions
5829
59−From `TestDataManagerGroupingTest.kt`:
30+## Key Conventions
6031
61−```kotlin
62−private fun assertGrouping(tests: List<DiscoveredTest>, expected: String) {
63− val result = groupByVariantDepth(tests)
64− val actual = result.groups.joinToString("\n") { group ->
65− "depth=${group.variantDepth}: ${group.uniqueVariantChains.joinToString(", ")}"
66− }
67− assertEquals(expected.trimIndent(), actual)
68−}
32+- `Ka` prefix for Analysis API types, `Kt` for PSI types
33+- Prefer interfaces to classes for better binary compatibility
34+- Properties for attributes, functions for actions with parameters
35+- Return nullable types for operations that can fail (avoid exceptions for non-exceptional cases)
36+- All implementations must validate lifetime ownership with `withValidityAssertion`
37+- Mark experimental APIs with `@KaExperimentalApi`, implementation details with `@KaImplementationDetail`
6938
70−private fun assertConflicts(tests: List<DiscoveredTest>, expected: String) {
71− val conflicts = validateConflicts(tests)
72− val actual = conflicts.joinToString("\n") {
73− "${it.chainA} vs ${it.chainB}: '${it.conflictingVariant}'"
74− }
75− assertEquals(expected.trimIndent(), actual)
76−}
39+## Working with Test Data
7740
78−@Test
79−fun `tests grouped by variant depth`() {
80− assertGrouping(
81− tests = listOf(
82− DiscoveredTest("1", "golden", emptyList()),
83− DiscoveredTest("2", "js", listOf("js")),
84− ),
85− expected = """
86− depth=0: []
87− depth=1: [js]
88− """
89− )
90−}
91−```
41+When modifying test data files or running generated tests (`*Generated`) that compare output against `.txt` files, use `updateTestData` (to rewrite files) or `checkTestData` (to verify only) instead of standard test commands. Both take their options as `-P` properties, so changing filters between runs stays fast.
9242
93−#### Pattern 3: State-Based Testing with Setup/Assert Helpers
43+### `updateTestData` — the only recommended way to update test data
9444
95−For file-based operations, use setup and assertion helpers.
45+```bash
46+# Update test data by directory (preferred for iteration)
47+./gradlew updateTestData -Porg.jetbrains.kotlin.testDataManager.options.testDataPath=analysis/analysis-api/testData/components/resolver/
9648
97−From `ManagedTestAssertionsTest.kt`:
49+# Update test data by test class pattern
50+./gradlew updateTestData -Porg.jetbrains.kotlin.testDataManager.options.testClassPattern=.*ResolveTest.*
9851
99−```kotlin
100−private fun assertFileState(expected: String) {
101− val actual = listOf("test.txt", "test.js.txt").mapNotNull { name ->
102− val file = tempDir.resolve(name)
103− if (file.exists()) "$name: ${file.readText().trim()}" else null
104− }.joinToString("\n")
105− assertEquals(expected.trimIndent(), actual)
106−}
52+# Run only golden tests (useful for quick baseline updates)
53+./gradlew updateTestData -Porg.jetbrains.kotlin.testDataManager.options.goldenOnly=true
10754
108−private fun setupFiles(vararg files: Pair<String, String>) {
109− for ((name, content) in files) {
110− tempDir.resolve(name).writeText("$content\n")
111− }
112−}
55+# Incremental update — only re-run variant tests for changed paths
56+./gradlew updateTestData -Porg.jetbrains.kotlin.testDataManager.options.incremental=true
11357
114−@Test
115−fun `UPDATE mode - mismatch updates file`() {
116− setupFiles("test.txt" to "old")
117− runAssertion(variantChain = emptyList(), actual = "new")
118− assertFileState("test.txt: new")
119−}
58+# Limit to a subset of modules using task paths (Gradle task-name matching)
59+./gradlew :analysis:analysis-api-fir:updateTestData :analysis:stubs:updateTestData
12060 ```
12161
122−#### Pattern 4: Filter Testing with Base Class
62+`updateTestData` is fixed to update mode. There is no `updateTestDataGlobally` — Gradle's task-name matching runs the task in every applicable subproject when invoked from the repo root.
12363
124−For JUnit filter tests, extend `AbstractPostDiscoveryFilterTest`.
64+### `checkTestData` — verification only
12565
126−From `ManagedTestFilterTest.kt`:
66+If you specifically need to verify that existing test data is consistent without modifying anything (e.g., sanity-checking generated files after an `updateTestData` run), use `checkTestData`. It is the exact `-P`-driven counterpart of `updateTestData` but fixed to check mode: it fails on any mismatch and writes nothing.
12767
128−```kotlin
129−internal class ManagedTestFilterTest : AbstractPostDiscoveryFilterTest() {
130− @Test
131− fun `ClassSource with ManagedTest is included`() {
132− assertIncluded(
133− filter = ManagedTestFilter,
134− descriptor = descriptorFromClass<FakeGoldenAnalysisApiTestGenerated>(),
135− )
136− }
137−
138− @Test
139− fun `ClassSource without ManagedTest is excluded`() {
140− assertExcluded(
141− filter = ManagedTestFilter,
142− descriptor = descriptorFromClass<NoMetadataClass>(),
143− )
144− }
145−}
68+```bash
69+./gradlew checkTestData -Porg.jetbrains.kotlin.testDataManager.options.testDataPath=analysis/analysis-api/testData/components/resolver/singleByPsi/
14670 ```
14771
148−Available utilities from `AbstractPostDiscoveryFilterTest`:
149−- `assertIncluded(filter, descriptor)` / `assertExcluded(filter, descriptor)`
150−- `descriptorFromClass<T>()` — Create descriptor from class
151−- `descriptorFromMethod(method)` — Create descriptor from method reference
152−- `descriptorWithSource(source)` — Create descriptor with custom source
72+Use this only for verification. For any workflow that writes test data, use `updateTestData`.
15373
154−#### Pattern 5: Fake Test Classes for Integration Testing
74+**Why use these tasks instead of plain `:test`?**
75+- Run only relevant tests (filtered by path or class pattern)
76+- Handle variant chains correctly (golden `.txt` files run before variant-specific `.js.txt`, `.wasm.txt`, etc.)
77+- Automatically discover all modules that use managed test data
78+- Detect and remove redundant variant files
15579
156−Create fake test classes in `tests/.../fakes/` to simulate real test configurations.
80+For full options, see [test-data-manager-convention](../repo/gradle-build-conventions/test-data-manager-convention/README.md).
15781
158−```kotlin
159−// Base class for all fakes
160−abstract class FakeManagedTest : ManagedTest
82+## Key Components
16183
162−// Golden test (no variant)
163−@TestMetadata("testData/analysis/api")
164−class FakeGoldenAnalysisApiTestGenerated : FakeManagedTest() {
165− override val variantChain = emptyList<String>()
84+- [`analysis-api/`](analysis-api) - User-facing API surface (`KaSession`, `KaSymbol`, `KaType`)
85+- [`analysis-api-platform-interface/`](analysis-api-platform-interface) - Platform abstraction (declaration providers, project structure, lifetime)
86+- [`analysis-api-standalone/`](analysis-api-standalone) - CLI-based implementation of the Analysis API
87+- [`analysis-api-fir/`](analysis-api-fir) - K2 implementation based on FIR
88+- [`analysis-api-impl-base/`](analysis-api-impl-base) - Shared implementation utilities
89+- [`low-level-api-fir/`](low-level-api-fir) - K2-specific infrastructure for lazy/incremental analysis
90+- [`symbol-light-classes/`](symbol-light-classes) - Java PSI view of Kotlin declarations for interop
91+- [`decompiled/light-classes-for-decompiled`](decompiled/light-classes-for-decompiled) - Light classes for decompiled/library code
92+- [`test-data-manager/`](test-data-manager) - Infrastructure for managing test data files with variant chains
16693
167− @Test
168− @TestMetadata("symbols.kt")
169− fun testSymbols() {}
170−}
94+## Detailed Documentation
17195
172−// Multi-level variant test
173−@TestMetadata("testData/lightClasses")
174−class FakeWasmLightClassesTestGenerated : FakeManagedTest() {
175− override val variantChain = listOf("knm", "wasm")
96+WHEN adding or modifying API endpoints:
97+→ READ [`docs/contribution-guide/api-development.md`](docs/contribution-guide/api-development.md)
17698
177− @Test
178− @TestMetadata("simple.kt")
179− fun testSimple() {}
180−}
181−```
99+WHEN deprecating API or understanding stability categories:
100+→ READ [`docs/contribution-guide/api-evolution.md`](docs/contribution-guide/api-evolution.md)
182101
183−## Usage from Other Modules
102+WHEN implementing platform components:
103+→ READ [`analysis-api-platform-interface/README.md`](analysis-api-platform-interface/README.md)
184104
185−### Implementing ManagedTest
105+WHEN working with light classes:
106+→ READ [`symbol-light-classes/README.md`](symbol-light-classes/README.md)
186107
187−Implement `ManagedTest` interface and provide variant chain:
108+WHEN working with lazy resolution (LL API):
109+→ READ [`low-level-api-fir/README.md`](low-level-api-fir/README.md)
188110
189−```kotlin
190−abstract class MyTestBase : ManagedTest {
191− override val variantChain: List<String>
192− get() = emptyList()
193−}
194−```
111+WHEN writing or managing test data files:
112+→ READ [`test-data-manager/AGENTS.md`](test-data-manager/AGENTS.md)
195113
196−Variant chain rules:
197−- `[]` (empty) — Golden/default configuration, writes to `.txt`
198−- `["js"]` — Single variant, writes to `.js.txt`
199−- `["knm", "wasm"]` — Multi-level variant, writes to `.wasm.txt` (last element only)
114+WHEN seeking historical context on design decisions:
115+→ READ [`docs/design-documents/README.md`](docs/design-documents/README.md) (these are historical snapshots, not necessarily up to date)
200116
201−### Using Assertions
202−
203−Use the extension function `ManagedTest.assertEqualsToTestDataFile()` for comparing test output:
204−
205−```kotlin
206−class MyTest : ManagedTest {
207− override val variantChain = listOf("js")
208−
209− fun runTest(testDataFile: File) {
210− val actual = computeResult()
211− assertEqualsToTestDataFile(
212− testDataPath = testDataFile.toPath(),
213− actual = actual,
214− extension = ".txt",
215− )
216− }
217−}
218−```
219−
220−Or use `ManagedTestAssertions.assertEqualsToTestDataFile()` directly:
221−
222−```kotlin
223−ManagedTestAssertions.assertEqualsToTestDataFile(
224− testDataPath = testDataFile.toPath(),
225− actual = actualContent,
226− variantChain = variantChain,
227− extension = ".txt",
228−)
229−```
230−
231−
232−### Behavior Matrix
233−
234−| Scenario | UPDATE mode | CHECK mode (local) | CHECK mode (CI) |
235−|---------------------------|-------------|--------------------|-----------------|
236−| actual=null, file missing | Pass | Pass | Pass |
237−| actual=null, file exists | Delete | Delete + throw | Throw |
238−| File missing (golden) | Create | Create + throw | Throw |
239−| File missing (secondary) | Create | Throw | Throw |
240−| Content matches | Pass | Pass | Pass |
241−| Write-target redundant | Delete | Delete + throw | Throw |
242−| Content mismatch | Update | Throw | Throw |
243−
244−## Key Classes Reference
245−
246−| Class | Location | Purpose |
247−|--------------------------|----------------------|--------------------------------------------------|
248−| `ManagedTest` | testFixtures | Interface for tests managed by the system |
249−| `ManagedTestAssertions` | testFixtures | Assertion functions for test data comparison |
250−| `TestDataManagerRunner` | testFixtures | Main runner (discovery, grouping, execution) |
251−| `TestDataContext` | testFixtures | File path resolution and mode for variant chains |
252−| `ManagedTestFilter` | testFixtures/filters | JUnit filter for ManagedTest implementations |
253−| `TestMetadataFilter` | testFixtures/filters | JUnit filter by @TestMetadata paths |
254−| `VariantChainComparator` | testFixtures | Orders variant chains by depth |
117+WHEN working with stubs:
118+→ READ [`stubs/README.md`](stubs/README.md)
255119
