Skip to content

Releases: kensa-dev/kensa

0.8.8

14 Jun 14:10

Choose a tag to compare

Changelog:

New features:

  • Suite-wide fixture search. Modifier-click (find by fixture name) or right-click (find by value or name) any fixture token in a report to search the whole suite. Matches dock in a resizable, non-modal panel grouped project → class → method → invocation, auto-revealing the active result in the left explorer and highlighting it in violet across sentences and interaction payloads, landing on the exact invocation. Backed by a new per-source search-index.json — a value-anywhere index over rendered sentences, givens/outputs and interaction payloads, with short, boolean and small-numeric values filtered out as noise — emitted in both data-only and full output modes.

0.8.7

04 Jun 10:55

Choose a tag to compare

Changelog:

Changed:

  • Built against Kotlin 2.4.0.. Kensa now compiles against Kotlin 2.4.0 and requires consumers to be on Kotlin 2.4.0; projects still on Kotlin 2.3.x should stay on the previous Kensa release. Context parameters are stable in 2.4.0, so the deprecated -Xcontext-parameters flag has been dropped from the build.

0.8.6

02 Jun 22:59

Choose a tag to compare

Changelog:

New features:

  • Expression-bodied @ExpandableSentence and test functions now render. A function written with an expression body — fun theDetails() = arrayOf(aField of "John", ...) — previously produced an empty expandable popup, because an expression body emits no statement for the source parser to turn into a sentence. Expression bodies now render through the same path as block bodies. When the whole body is a single wrapping call (arrayOf(...), listOf(...), or any builder(args)) the call itself is stripped so only its contents render — a matcher/element list reads as a clean list without the surrounding builder. Lambda-delegating bodies (= with(context) { ... }, = test { ... }) are untouched and keep rendering their lambda statements; block bodies are unchanged.
  • /*+ Ignore */ source hint. A /*+ Ignore */ comment on its own line drops the rendered tokens on the next source line from the report sentence; /*+ Ignore:n */ drops the next n lines. It works anywhere in a test or @ExpandableSentence body — a manual way to hide distracting plumbing (a wrapping return arrayOf( line, a gnarly builder chain) from the sentence without changing the test. Complements the existing /*+ ReplaceSentence: ... */ hint.

0.8.5

31 May 10:14

Choose a tag to compare

Changelog:

Changed:

  • primary participant now renders as the leftmost participant. Previously primary.participant(...) was only emitted as an empty-diagram fallback for marker-only tests — configuring primary.actor("SUT") alongside other participants required re-declaring "SUT" via participant("SUT") to actually see it. SequenceDiagramFactory now prepends the primary's line to the participants list whenever it is set, so primary means what it reads as: the leftmost participant. When the same name is already declared (top-level or inside a box { }) the primary is suppressed so the explicit declaration wins and keeps its position. Docs.
  • Test headers cap inline issue badges. A test card header now renders at most three @Issue badges inline; any beyond that fold into a +N more popover listing the full set in a scrollable grid, so long issue lists no longer push the header layout around. Badges still link to the issue tracker, and the popover trigger does not toggle the test card.
  • Tidier parameterised invocation headers. Long backend display names now truncate to a single line (full text on hover) instead of wrapping and growing the header box, and a leading JUnit-style [N] index prefix is stripped from the name since the card already carries a #N badge (a bare [123] with no trailing space — e.g. a Kotest list toString — is left intact).
  • Sidebar test leaves read as leaves. Test rows are inset past the absent-chevron gutter and the leaf diamond's stroke is thickened, so individual tests no longer blend in with the container folders above them.

Performance:

  • Parsing no longer serialises on hash-bin collisions. The per-method and per-class parser caches moved off ConcurrentHashMap.computeIfAbsent, which holds the bin lock for the entire duration of a (potentially slow) parse and blocks unrelated threads whose keys land in the same bin. They now use a CompletableFuture-based memoize that reserves the slot and runs the parse outside the lock, so concurrent first-time parses of different classes/methods proceed in parallel.
  • Lower retained heap from cached parse trees. MethodDeclarationContext now severs the parsed method body from its parent chain, so a cached ParsedMethod no longer pins the entire enclosing AST in memory.

Fixes:

  • No report written when no tests ran. writeAllResults forced the lazy ResultWriter even with an empty test set, which recreated (wiped) the output directory and wrote an empty report — destroying any report from a previous run. It now returns early when no test containers were recorded, leaving the output directory untouched on a zero-test run. Covers every framework adapter (JUnit 5/6, TestNG, Kotest), which all funnel through the same call.
  • Breadcrumb no longer nests <li> inside <li>. The package breadcrumb in the detail header rendered its separator as an <li> inside the item <li>, tripping React's validateDOMNesting warning. The separator is now a sibling of the item under the list.

0.8.4

23 May 14:22

Choose a tag to compare

Changelog:

New features:

  • Sidebar tree auto-expands while filtering. Typing in the test filter now reveals matches inside user-collapsed folders without touching the persisted shape — clear the filter and your collapse/expand state is restored exactly as it was. Builds on the v0.8.3 expand/collapse toolbar.

Fixes:

  • Collapse-all now collapses every folder, not just project roots. The ⌥+[ toolbar button only added per-source project roots to the collapsed set; package nodes were built dynamically per-render and never reached the expansion state, so opening a collapsed root revealed every nested package already expanded. The package tree is now materialised before expansion state sees it, matching IntelliJ behaviour: collapse-all → opening the root shows only its top-level entries; expand-all opens every folder.
  • Persisted tree state is bounded. kensa-tree-collapsed in localStorage now caps at 5000 entries, dropping the oldest on load. Prevents unbounded growth in long-lived workspaces where folder ids churn (heavy package refactors, frequent packageDisplay mode switches).
  • All Kensa modules now appear in the BOM. Modules added after the BOM's last refresh were missing from kensa-bom, so importing the BOM didn't constrain their versions.

0.8.3

21 May 10:31

Choose a tag to compare

Changelog:

New features:

  • Sidebar tree expand/collapse toolbar. Two icon buttons live inline with the Test Explorer group label: expand-all (⌥+]) and collapse-all (⌥+[). Expansion state persists to localStorage so the tree's open/closed shape survives reload. Newly-seen folder ids that aren't yet in storage stay expanded by default — no surprises after a build adds packages.
  • Parameterised test display. Invocation card headers no longer truncate parameter lists. A hybrid summary picks one of three shapes per invocation: the backend-supplied displayName when present (e.g. JUnit's [1] arg1, arg2); an inline comma-join when there are ≤3 parameters and the joined string fits in 80 characters; or a N params count chip otherwise. When the header had to drop information the expanded card body grows a structured parameters table; when the header already listed everything the table is suppressed to avoid redundancy. Above the per-invocation cards a cross-invocation matrix renders whenever a test has ≥2 invocations and every invocation carries ≥2 parameters — clicking a row scrolls to and expands the matching card. Values flow through a small client-side classifier that colours numbers / booleans / null / strings / JSON code-style.

Fixes:

  • Console banner now prints an absolute output path. The "Kensa Output:" line emitted at the end of a run is what IntelliJ turns into a clickable hyperlink — but only when the path is fully qualified. Relative outputDir values (common under @KensaTest YAML config or any konfigure { outputDir = Path(...) } with a relative argument) silently failed to link. Resolved to absolute at print time so the hyperlink works regardless of how outputDir was supplied.

0.8.2

18 May 08:50

Choose a tag to compare

Changelog:

New features:

  • Framework-native tags surfaced in reports. JUnit @Tag, Kotest @Tags, and TestNG @Test(groups = ...) now flow through to the HTML report as badges on each test (alongside @Issue badges) and as a multi-select cloud in the sidebar with OR-logic filtering. Click a badge to filter by that tag; Cmd/Ctrl/Shift-click to add to the current selection.
  • sequenceDiagram { } Kotlin DSL on Configuration for declaring participants, boxes, title, hide-unlinked, and a fallback identity. Declaration order is left-to-right on the rendered diagram. Each participant call (participant, actor, boundary, control, entity, database, collections, queue) returns a handle so .withColour(...) and .withAlias(...) chain inline. box(title) { ... } wraps nested participants. Docs.
  • primary.<type>(name) fallback identity. A test that captures only dividers (SD-MARKER / ==Something==) or has no participants previously produced markup PlantUML couldn't recognise as a sequence diagram — falling into the error path that pulls in QR-code (zxing) classes stripped from the shadow JAR. Configure sequenceDiagram { primary.actor("User") } to inject a single participant for these cases. Only emitted when no participants are declared and no real arrow interactions are captured.

Fixes:

  • UI no longer caches loadJson / loadText fetches. Browser-side requests for indices.json, results/*.json, and source-file text now go out with cache: 'no-store' so a regenerated report is picked up on reload without a hard refresh.
  • Late-applied sequence-diagram config is now observed by the factory. When Kensa.konfigure { ... } runs from a companion-object init block (a common pattern — e.g., your own JUnit extension) it may execute after KensaLifecycleManager.initialise(...) has already constructed SequenceDiagramFactory. Previously the factory captured a reference to the old var umlDirectives list, so a subsequent umlDirectives = listOf(...) reassignment was invisible to it — the rendered diagram had no participant declarations and PlantUML laid out participants from interaction order alone. The factory now reads from the shared list at render time, so post-init reassignment via the deprecated setter (or the new sequenceDiagram { } block) is honoured.

Deprecated:

  • Configuration.umlDirectives — replaced by the sequenceDiagram { } block. The legacy setter still works but clears the directives list and invalidates any retained participant handle from a prior sequenceDiagram { } block. Java consumers can keep using it until a richer Java-side API lands.

0.8.1

13 May 08:28

Choose a tag to compare

Changelog:

New features:

  • Spring Boot starter — two new modules (kensa-spring-boot-starter, kensa-spring-boot-starter-web) wire Kensa into Spring Boot tests with zero manual configuration: @KensaTest boots the application context with Kensa registered as a JUnit Jupiter extension and configures the runtime from kensa.* properties in application.yml. The -web module auto-configures HandlerInterceptor / ClientHttpRequestInterceptor / ExchangeFilterFunction beans that capture HTTP interactions for the sequence diagram. Override any capture point by registering a bean with the canonical name (kensaHandlerInterceptor, kensaClientHttpRequestInterceptor, kensaExchangeFilterFunction) to plug in a party-aware variant. Spring deps are compileOnly — non-Spring projects on kensa-core see no transitive Spring dependency. Docs.

Changed:

  • @ExpandableSentence bodies are now parsed lazily — the parser runs only on first access, so unused expandable methods incur no parse cost.
  • JUnit framework adapters — softer version pin. kensa-framework-junit5 and -junit6 previously consumed the junit-bom at implementation scope, which propagated as a hard runtime dep and made Kensa's JUnit version a floor for consumers. The BOM is now compileOnly; the published POM still carries it as <scope>import</scope> in <dependencyManagement> (so suggested versions are visible to Maven consumers) but is no longer a runtime dep, letting Spring Boot's dependency-management plugin and similar version-managers win cleanly. junit-jupiter-api, junit-jupiter-params, and junit-platform-launcher still ship transitively at implementation scope, so consumer classpaths are unchanged. The dead junit-jupiter-engine declaration was removed (the adapter's listener uses junit-platform-engine types brought in via the launcher).
  • TestNG framework adapter — testng is now compileOnly. kensa-framework-testng no longer ships TestNG transitively. TestNG users already declare testng explicitly in their build, so the practical impact is nil; the win is that the adapter no longer imposes a TestNG version on consumers.

Fixes:

  • Remove -Xexplicit-backing-fields again (re-introduced unintentionally in 0.8.0). Downstream Kotlin projects no longer need -Xskip-prerelease-check to consume kensa-core.
  • Per-source component diagrams in site mode. The HTML UI was loading every per-source aggregateComponentDiagram from each sources/<id>/indices.json but then only using the first source's diagram as a global System View — every other source's architecture was silently dropped. Site mode now renders one System View per source, surfaced as a "System View" entry inside each source's tree root in the sidebar. Single-sourceset projects are unaffected (one source → one entry).
  • kensa-framework-junit5: per-class results/*.json files now write correctly on JUnit Jupiter < 5.13. The CloseableTestContainer that hooks end-of-class teardown used java.io.Closeable, which the Jupiter ExtensionContext.Store only honours on 5.13+; on 5.12 (forced by Spring Boot 3.5.x) the close callback never fired and test detail files were silently dropped. Switched to ExtensionContext.Store.CloseableResource, which is honoured by every 5.x version.

0.8.0

10 May 15:56

Choose a tag to compare

Changelog:
New features:

  • Kotest Field Assertion DSL — three new modules (kensa-kotest-test-support, -xml, -json) providing a MatcherField<T, R> interface and composable, named-field matchers for JSON and XML payloads. Extension functions of / matching / withListOf / withSetOf / toMatcher produce standard Matcher<T?> values that compose with then(collector, matcher). Failure messages are auto-prefixed with the field's description. Docs.
  • Hamkrest Field Assertion DSL — three new modules (kensa-hamkrest-test-support, -xml, -json) providing a MatcherField<T, R> interface and composable, named-field matchers for JSON and XML payloads. Extension functions of / matching / withListOf / withSetOf / toMatcher produce standard Matcher<T?> values that compose with then(collector, matcher). Failure messages are auto-prefixed with the field's description. Docs.
  • Phrasing sugar in both flavours — with, thatHas (single + vararg), thatIs, shouldHaveAll — for assertions that read like English at the call-site. Docs.
  • @RenderedValueWithHint integration for field DSL — JSONPointer / XPath surfaced as on-hover hints in the report. Docs.
  • Site mode for HTML reports — runtime, UI, and CLI integration. Docs.
  • Experimental UI test framework with Playwright and Selenium adapters (framework-playwright, framework-selenium, plus -junit5 / -junit6 variants). Docs.
  • Component diagram view. Shows all interactions between components in a test suite. Docs.
  • UI Click-to-filter passed / failed / disabled badges on the sidebar footer.
  • UI Scrollable expandable popups.
  • Missing andEventually overloads on the kotest assertion entry points.

Changed:

  • CLI updated for site mode; warns on Kensa-version drift between the CLI and the report it serves. Docs.
  • Local builds now default the version to snapshot-version.txt.

Fixes:

  • getFailingLine choosing the wrong line number.
  • Default-mode @ExpandableRenderedValue rendering.
  • Kotest matcher double-execute inside andEventually.

Breaking:

  • Legacy UI removed (deprecated in 0.7.0; Configuration.uiMode and KensaConfigurator.withUiMode(...) are gone, along with the UiMode enum).

0.7.1

29 Apr 08:38

Choose a tag to compare

Changelog:

  • Fix #132: don't clear sidebar search on Escape while a dialog is open
  • Fix #131: match issue ids exactly, not as substrings
  • Build uses Gradle 9.5.0
  • Kotlin 2.3.21