Skip to content

Releases: kensa-dev/kensa

0.8.13

Choose a tag to compare

@github-actions github-actions released this 14 Jul 08:46

Changelog:

Fixes:

  • @RenderedValue identifier as a fixtures[...] / outputs[...] subscript key. A rendered parameter or field used inside a fixtures or outputs subscript, such as fixtures[productFor(provideType)] or outputs[trackingId], crashed the source parser and rendered the whole statement as "Could not parse this statement". The parser now keeps its expression stack balanced for these nested rendered identifiers (#163).
  • Named parameterized-test arguments show their label. JUnit unwraps Named.of("label", value) to the raw payload before Kensa sees the invocation, so the parameter table showed the payload instead of the label. Kensa now recovers the label positionally from the test display name and applies it to opaque payloads, falling back to the raw value when the argument count does not match the parsed parameters (#162).
  • Opaque lambda and builder arguments render by type name. Lambda and builder parameter values that fell through to Object.toString() produced non-deterministic noise like MyTest$$Lambda/0x...@6f77685 in parameter tables. They now render as their functional interface simple name (for example Function1, or a custom SAM name), with lambda as a fallback. Registered value renderers still take precedence.

Performance:

  • Fewer test-explorer re-renders in large reports. Explorer rows no longer re-render on every selection or URL change, because only System-View rows subscribe to the router now. This cuts per-click main-thread work in reports with many test rows.

0.8.12

Choose a tag to compare

@github-actions github-actions released this 08 Jul 22:08

Changelog:

Fixes:

  • @ExpandableSentence with value class parameters. The Kotlin compiler mangles the JVM name of a function that takes a value class parameter (someAction becomes someAction-abc123), so Kensa could not find the method and reported the test as unparseable. Thanks to Michael Orr (#160).
  • @RenderedValue with value class parameters or return types. The same name mangling meant the captured invocation was recorded under the mangled JVM name and never matched the parsed sentence, so the rendered value was silently dropped.
  • Array parameter types in parameterized tests. Tests declaring array parameters — Array<Pair<String, String>> and other Array<T> (including nested, variance and nullable components), primitive arrays (IntArray, ...), Java arrays (String[]), vararg params — previously failed with Did not find method declaration for test method; plain Float/Short/Byte/Char params now match too. Array values also render like lists ([(a, b)]) everywhere instead of Object.toString() identity hashes (#161).

Performance:

  • No reflective method lookup on instrumented calls. The compiler-plugin hooks now record invocations by source name directly instead of deriving a java.lang.reflect.Method on every @ExpandableSentence / @RenderedValue call.

0.8.11

Choose a tag to compare

@github-actions github-actions released this 05 Jul 11:30

Changelog:

New features:

  • Multi-assertion thenEventually / thenContinually blocks. Both polling forms now accept a block of then / and assertions evaluated in parallel within a single polling window — thenEventually locks in each assertion independently as it starts passing, thenContinually requires all assertions to hold on every tick. Single failures are rethrown as-is; multiple failures are aggregated with the rest suppressed. Available in the Kotest and Hamkrest bridges.

Fixes:

  • ReplaceSentence and Ignore hints in Java test sources. The Java lexer now recognises the documented /*+ ... */ hint form (it previously only matched javadoc-style comments, which then failed the prefix check), and the Java body parser now emits Ignore hints, matching the Kotlin parser (#151).

0.8.10

Choose a tag to compare

@github-actions github-actions released this 01 Jul 10:27

Changelog:

New features:

  • @Fixture factory functions. Annotate a function in a FixtureContainer with @Fixture("Key") and call it inline via fixtures[myFixture(arg)]; the compiler plugin rewrites its no-name fixture { } to inject the key and arguments, giving each (key, args) a distinct memoized identity that renders as a fixture token.

Fixes:

  • Chained reference to a parameterised @RenderedValue method. productFor(p).stringValue now renders the captured value instead of the call words / null (#149).
  • Top-level @RenderedValue function. Resolves the file-facade FQN (honouring @file:JvmName), fixing a ClassNotFoundException (#150).

0.8.9

Choose a tag to compare

@github-actions github-actions released this 28 Jun 10:56

Changelog:

New features:

  • Null-safe paths in rendered values. Rendered chained paths now accept the ?. safe-call operator — order?.customer?.name, fixtures[X]?.foo, outputs("k")?.bar — which were previously dropped from value substitution (#144).
  • Test parameters rendered through registered renderers. Parameter values, the parameterised test description shown in the test header, and the suite search index now all honour registered value renderers, and each parameter is rendered exactly once (no more double-rendering when a String renderer is registered) (#145).
  • Parameter-derived fixtures. A parameterFixture("key", from = "paramName") { … } (Kotlin) / createParameterFixture(...) (Java) is registered by name — so it resolves in fixtures[…] interpolation — and derives its value per invocation from a named parameterised-test argument, seeded before the test body so it's usable both in the test and in the rendered sentence. Secondary fixtures can derive from one (#148).

Changed:

  • Consistent lowercase null rendering. Captured null values now render as lowercase null everywhere, matching the source-literal null keyword and the UI's null styling (previously an inconsistent NULL, which made an actual null display as a quoted string) (#146).

Fixes:

  • No ConcurrentModificationException in sequence diagrams under parallel execution. SequenceDiagramFactory is now safe when tests run in parallel (#142).
  • dataOnly is authoritative over outputDir in site mode.

0.8.8

Choose a tag to compare

@github-actions github-actions released this 14 Jun 14:10

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

Choose a tag to compare

@github-actions github-actions released this 04 Jun 10:55

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

Choose a tag to compare

@github-actions github-actions released this 02 Jun 22:59

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

Choose a tag to compare

@github-actions github-actions released this 31 May 10:14

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

Choose a tag to compare

@github-actions github-actions released this 23 May 14:22

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.