Skip to content

Enforce complexity, shadowing, block statement, useless else and readonly rules with Biome - #1590

Merged
cristianrgreco merged 7 commits into
mainfrom
claude/vigorous-payne-1d8369
Oct 13, 2026
Merged

cristianrgreco merged 7 commits into
mainfrom
claude/vigorous-payne-1d8369

Conversation

@cristianrgreco

@cristianrgreco cristianrgreco commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Enables five more Biome rules at error. Every existing violation is fixed: there is no biome-ignore, no per-file exemption, and none of the five is turned off for **/*.test.ts.

Builds on #1585, which has merged. Hits are from biome lint --only=<rule> --max-diagnostics=none ., before on the #1585 branch and after on this one.

Rule Before: source Before: *.test.ts After
complexity/noExcessiveCognitiveComplexity (default max 15) 2 in 2 files 0 0
suspicious/noShadow 12 in 8 files 12 in 8 files 0
style/noUselessElse 25 in 16 files 1 0
style/useBlockStatements 28 in 9 files 6 in 2 files 0
style/useReadonlyClassProperties 8 in 5 files 0 0

Cognitive complexity

Function Score before Fix
CouchbaseContainer.configureExternalPorts 16 The five per-service blocks move, unchanged, into a private setServicePorts(body, container) placed below it.
ImageName constructor 20 The code that builds string moves into a private buildString() placed below it.
  • setServicePorts scores exactly 15, the limit.
  • buildString returns the value and the constructor assigns it. The branches could not be moved as they were, because string is readonly and can only be assigned in the constructor. Each this.string = x became return x, in the same order.

Shadowing

The inner binding is renamed in every case but one.

File Rename
gcloud/src/spanner-emulator-helper.ts the Spanner class from the dynamic import is aliased to SpannerClient; the Spanner type import is unchanged
toxiproxy/src/toxiproxy-container.ts reduce callback parameter port to candidatePort
container-runtime/auth/get-auth-config.ts parseDockerConfig parameter dockerConfig to json
container-runtime/clients/container/docker-container-client.ts processStream parameter stream to source
port-forwarder/port-forwarder.ts find callback parameter port to mapping
reaper/reaper.ts (5 hits) module-level let sessionId to reaperSessionId
utils/test-helper.ts predicate parameter status to running
wait-strategies/startup-check-strategy.ts predicate parameter startupStatus to status
hivemq and mosquitto tests (3 hits) message handler parameter message to payload
kurrentdb test getStreamFirstEvent parameter stream to subscription
common/retry.test.ts (3 hits) predicate parameter result to value
container-runtime/auth/credential-provider.test.ts test-local credentialProvider to unnamedCredentialProvider
docker-compose-environment.test.ts (2 hits), generic-container.test.ts nested await using _ to _pulled
generic-container-logs.test.ts data handler parameter line to chunk

reaper.ts is the exception: the outer, unexported variable is renamed. Two of the five inner bindings are the sessionId parameter properties of RyukReaper and DisabledReaper, which implement Reaper.sessionId, so they cannot be renamed.

Useless else and block statements

Both are Biome autofixes, applied with --write --unsafe and then read line by line.

  • noUselessElse: every site is an else after a branch that ends in return or throw. The else body moves out one level.
  • useBlockStatements: braces are added around single-statement if and else bodies.

Readonly class properties

By default the rule checks private properties only. All eight are assigned in the initialiser or constructor and nowhere else, so all eight are now readonly.

Class Fields
AzureCosmosDbEmulatorContainer key, explorerEnabled, portGenerator
MSSQLServerContainer username
NatsContainer args, values
DockerComposeEnvironment waitStrategy
SocatContainer targets
  • args, values, waitStrategy and targets are collections that are mutated but never reassigned.
  • key, explorerEnabled and username have no setter, so they were already constants.
  • No field is written through Object.assign, an index signature or a cast.

Verification

Local tests

The test files covering the changed files were run as two Vitest processes at the same time. The Docker host has 4 GB of memory and was shared with other sessions, which had five Couchbase containers running. No failure has been compared against the base branch yet.

Core, 25 files: 24 passed, 1 failed (272 tests passed, 1 failed, 1 skipped).

Test Error Rerun alone
generic-container.test.ts > should return first mapped port with regardless of protocol Test timed out in 180000ms passed

Modules, 15 files: 8 passed, 7 failed (66 tests passed, 12 failed). The 8 that passed: cloudstorage-emulator-container, emulator-flags-manager, spanner-emulator-helper, kurrentdb-container, mongodb-container, mosquitto-container, nats-container, toxiproxy-container.

File Failed tests Error Rerun alone
redis-container.test.ts 1 read ECONNRESET passed, 12 of 12
hivemq-container.test.ts 1 Get "https://registry-1.docker.io/v2/": net/http: TLS handshake timeout passed, 1 of 1
azurite-container.test.ts 1 RestError with an empty message passed, 9 of 9
postgresql-container.test.ts 1 connect ECONNREFUSED 127.0.0.1:61302 passed, 8 of 8
mongodb-atlas-local-container.test.ts 2 container … is not running (HTTP 409); cannot query search index … while in state UNKNOWN not rerun
azure-cosmosdb-emulator-container.test.ts 2 schema "cosmos_api" does not exist not rerun
mssqlserver-container.test.ts 4 Log stream ended and message "/.*Recovery is complete.*/" was not received (3); the same for /.*Attribute synchronization manager initialized*/ (1) not rerun

Not run locally: couchbase-container.test.ts, which covers configureExternalPorts. CI runs it.

Not breaking

  • No export is added, removed or renamed, and no public method or constructor signature changes.
  • The two new methods (setServicePorts, buildString) and the eight readonly fields are private.
  • The other changes are local renames, added braces and removed else keywords. Control flow is the same.
  • The HiveMQ, Mosquitto and KurrentDB docs pages include the renamed test lines, so those snippets show payload and subscription.

…tyle-with-biome-d40615

# Conflicts:
#	packages/testcontainers/src/container-runtime/clients/container/docker-container-client.ts
The rules live in biome.json. AGENTS.md keeps only the guidance that config can't express: fix a violation rather than suppressing it.
@cristianrgreco cristianrgreco added maintenance Improvements that do not change functionality patch Backward compatible bug fix labels Oct 12, 2026
…-1d8369

# Conflicts:
#	biome.json
#	packages/testcontainers/src/wait-strategies/http-wait-strategy.ts
@cristianrgreco
cristianrgreco marked this pull request as ready for review October 13, 2026 10:02
@cristianrgreco
cristianrgreco merged commit f6889cd into main Oct 13, 2026
191 checks passed
@cristianrgreco
cristianrgreco deleted the claude/vigorous-payne-1d8369 branch October 13, 2026 15:57
cristianrgreco added a commit that referenced this pull request Oct 13, 2026
Resolve conflicts with the Biome rule changes in #1585 and #1590: thread the signal through the extracted exec and HTTP helpers, and move the extracted Couchbase waits to poll.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintenance Improvements that do not change functionality patch Backward compatible bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant