Skip to content

Improved Crystal Coding Practices#3

Merged
dragosv merged 2 commits intomainfrom
style
Mar 8, 2026
Merged

Improved Crystal Coding Practices#3
dragosv merged 2 commits intomainfrom
style

Conversation

@dragosv
Copy link
Copy Markdown
Owner

@dragosv dragosv commented Mar 8, 2026

Adopt LavinMQ-Inspired Crystal Coding Practices

Summary

Applies idiomatic Crystal coding patterns inspired by CloudAMQP's LavinMQ to improve code safety, readability, and debuggability across the library.

Changes

1. Eliminate all not_nil! calls from source code

Replaced all 18 not_nil! calls in src/ with safe alternatives:

  • Introduced a require_container_id : String private helper on DockerContainer that returns the container ID or raises NotStartedError — replacing the repeated raise ... unless @container_id / @container_id.not_nil! pattern.
  • Used if id = @variable guard clauses in Network for safe nil unwrapping.
  • Updated .ameba.yml to remove source exclusions for Lint/NotNil (only spec/ is excluded now).

2. Nested error classes under parent domain

Restructured the flat error hierarchy to nest errors under their owning class, following the LavinMQ pattern of Error::Subtype:

Before (flat) After (nested)
Testcontainers::ContainerNotStartedError Testcontainers::DockerContainer::NotStartedError
Testcontainers::ContainerLaunchError Testcontainers::DockerContainer::LaunchError
Testcontainers::PortNotMappedError Testcontainers::DockerContainer::PortNotMappedError
Testcontainers::HealthcheckNotSupportedError Testcontainers::DockerContainer::HealthcheckNotSupportedError
Testcontainers::TimeoutError Testcontainers::DockerContainer::TimeoutError
Testcontainers::NetworkError Testcontainers::Network::Error
Testcontainers::NetworkNotFoundError Testcontainers::Network::NotFoundError
Testcontainers::NetworkAlreadyExistsError Testcontainers::Network::AlreadyExistsError

Backward-compatible aliases are provided at the old locations so existing user code continues to work.

3. Per-class Log.for scoped logging

Replaced the single global Testcontainers.logger with per-class log sources:

  • DockerContainer: Log = Testcontainers::Log.for("container") → source: testcontainers.container
  • Network: Log = Testcontainers::Log.for("network") → source: testcontainers.network

All 9 Testcontainers.logger.info calls replaced with Log.info. The Testcontainers.logger class property is kept for backward compatibility.

4. : Nil return type annotations

Added explicit : Nil return types to 10 methods that don't return meaningful values, following the LavinMQ convention:

  • configure_env on all 6 container modules (Elasticsearch, MariaDB, Mongo, MySQL, Postgres, RabbitMQ)
  • add_exposed_port, add_fixed_exposed_port, add_env, add_labels on DockerContainer
  • DockerClient.reset!

5. #inspect(io : IO) : Nil overrides

Added structured #inspect overrides to DockerContainer and Network for cleaner REPL/debug output instead of dumping all instance variables.

6. Ameba linting in CI

Added bin/ameba step to both ci.yml and release.yml pipelines.

Testing

  • All 68 unit tests pass
  • Ameba: 22 files inspected, 0 failures
  • crystal tool format: clean

Summary by Sourcery

Adopt more idiomatic, safe Crystal patterns across Docker container and network handling, error modeling, logging, and CI linting.

Enhancements:

  • Replace unsafe not_nil! usage in Docker container and network operations with explicit container/network ID checks and a shared helper on DockerContainer.
  • Nest Docker- and network-related error types under their respective classes while keeping backward-compatible aliases for existing error constants.
  • Introduce per-class scoped logging for DockerContainer and Network using Testcontainers::Log.for, replacing the previous global logger usage.
  • Add structured inspect implementations for DockerContainer and Network to provide concise, targeted debug representations.
  • Annotate void-like helper methods with explicit : Nil return types in container modules, DockerContainer helpers, and DockerClient.reset! for clearer intent.

CI:

  • Run the Ameba linter in both CI and release workflows to enforce style and safety rules, and update Ameba configuration now that source not_nil! usages are removed.

Documentation:

  • Document additional internal best practices in AGENTS.md around avoiding not_nil! and preferring explicit Nil return types.

Summary by CodeRabbit

  • New Features

    • Added inspection methods for containers and networks for better debugging.
    • Added network creation state detection.
  • Refactor

    • Reorganized error types into logical namespaces for clearer error handling.
    • Improved internal null-safety checks and logging patterns.
    • Added explicit return type annotations throughout the codebase.
  • Documentation

    • Updated coding guidelines with best practices for return type annotations.
  • Chores

    • Integrated Ameba linter into CI and release workflows.
    • Adjusted linting rules for improved code coverage.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Mar 8, 2026

Reviewer's Guide

Refactors DockerContainer and Network to use safer nil handling, nested error types, per-class logging, explicit Nil return annotations, and custom inspect output, while wiring Ameba linting into CI and documenting new style guidance.

Class diagram for the updated Testcontainers error hierarchy

classDiagram
    class TestcontainersError
    class ConnectionError
    class NotFoundError

    class DockerContainer
    class DockerContainer_NotStartedError
    class DockerContainer_LaunchError
    class DockerContainer_PortNotMappedError
    class DockerContainer_HealthcheckNotSupportedError
    class DockerContainer_TimeoutError

    class Network
    class Network_Error
    class Network_NotFoundError
    class Network_AlreadyExistsError

    class ContainerNotStartedError
    class ContainerLaunchError
    class PortNotMappedError
    class HealthcheckNotSupportedError
    class TimeoutError
    class NetworkError
    class NetworkNotFoundError
    class NetworkAlreadyExistsError

    TestcontainersError <|-- ConnectionError
    TestcontainersError <|-- NotFoundError

    TestcontainersError <|-- DockerContainer_NotStartedError
    TestcontainersError <|-- DockerContainer_LaunchError
    TestcontainersError <|-- DockerContainer_PortNotMappedError
    TestcontainersError <|-- DockerContainer_HealthcheckNotSupportedError
    TestcontainersError <|-- DockerContainer_TimeoutError

    TestcontainersError <|-- Network_Error
    Network_Error <|-- Network_NotFoundError
    Network_Error <|-- Network_AlreadyExistsError

    DockerContainer *-- DockerContainer_NotStartedError
    DockerContainer *-- DockerContainer_LaunchError
    DockerContainer *-- DockerContainer_PortNotMappedError
    DockerContainer *-- DockerContainer_HealthcheckNotSupportedError
    DockerContainer *-- DockerContainer_TimeoutError

    Network *-- Network_Error
    Network *-- Network_NotFoundError
    Network *-- Network_AlreadyExistsError

    class ContainerNotStartedError {
      <<alias>>
    }
    class ContainerLaunchError {
      <<alias>>
    }
    class PortNotMappedError {
      <<alias>>
    }
    class HealthcheckNotSupportedError {
      <<alias>>
    }
    class TimeoutError {
      <<alias>>
    }
    class NetworkError {
      <<alias>>
    }
    class NetworkNotFoundError {
      <<alias>>
    }
    class NetworkAlreadyExistsError {
      <<alias>>
    }

    ContainerNotStartedError ..> DockerContainer_NotStartedError
    ContainerLaunchError ..> DockerContainer_LaunchError
    PortNotMappedError ..> DockerContainer_PortNotMappedError
    HealthcheckNotSupportedError ..> DockerContainer_HealthcheckNotSupportedError
    TimeoutError ..> DockerContainer_TimeoutError
    NetworkError ..> Network_Error
    NetworkNotFoundError ..> Network_NotFoundError
    NetworkAlreadyExistsError ..> Network_AlreadyExistsError
Loading

Class diagram for DockerContainer and Network structural updates

classDiagram
    class DockerContainer {
      +String? name
      +String image
      +String? container_id
      +Time? created_at
      +Hash(String,String) labels
      +Hash(String,Hash(String,String)) exposed_ports
      +Hash(String,Array~Docr_Types_PortBinding~) port_bindings
      +String host()
      +Int32 mapped_port(port : Int32|String)
      +Int32 first_mapped_port()
      +Bool running?()
      +Bool healthy?()
      +Bool supports_healthcheck?()
      +Bool exists?()
      +Docr_Types_ContainerInspectResponse info()
      +String logs(stdout : Bool, stderr : Bool)
      +String exec(cmd : Array~String~)
      +Bool wait_for_logs(matcher : Regex, timeout : Int32, interval : Float64)
      +Bool wait_for_tcp_port(port : Int32, timeout : Int32, interval : Float64)
      +Bool wait_for_healthcheck(timeout : Int32, interval : Float64)
      +Bool wait_for_http(container_port : Int32, path : String, status : Int32, https : Bool)
      +self stop(force : Bool)
      +self kill(signal : String)
      +self remove(force : Bool, volumes : Bool)
      +self restart()
      +self pause()
      +self unpause()
      +void inspect(io : IO) : Nil
      -String require_container_id() : String
      -void add_exposed_port(port : Int32|String) : Nil
      -void add_fixed_exposed_port(container_port : Int32|String, host_port : Int32) : Nil
      -void add_env(env_str : String) : Nil
      -void add_labels(labels : Hash~String,String~) : Nil
      <<has constant>> Log
    }

    class Network {
      +String name
      +String? network_id
      +Hash(String,String) labels
      +self create!()
      +Bool created?()
      +Docr_Types_Network info()
      +self remove()
      +void inspect(io : IO) : Nil
      <<has constant>> Log
    }

    class DockerClient {
      +Docr_Types_API api
      +String host()
      +void reset!() : Nil
    }

    class DockerContainer_NotStartedError
    class DockerContainer_HealthcheckNotSupportedError
    class DockerContainer_PortNotMappedError

    class Network_Error

    DockerContainer ..> DockerClient : uses
    Network ..> DockerClient : uses

    DockerContainer ..> DockerContainer_NotStartedError : raises
    DockerContainer ..> DockerContainer_HealthcheckNotSupportedError : raises
    DockerContainer ..> DockerContainer_PortNotMappedError : raises

    Network ..> Network_Error : raises
Loading

File-Level Changes

Change Details Files
Refactor DockerContainer to eliminate not_nil!, centralize container ID validation, adopt scoped logging, add inspect output, and annotate Nil-returning helpers.
  • Introduce Log = Testcontainers::Log.for("container") and replace all Testcontainers.logger.info calls with Log.info within DockerContainer lifecycle methods.
  • Replace direct @container_id.not_nil! usage by introducing private require_container_id : String helper and using local id variables where appropriate.
  • Update container lifecycle and query methods (stop, kill, restart, pause, unpause, status, healthy?, supports_healthcheck?, exists?, info, host, mapped_port, first_mapped_port, logs, exec, wait_for_logs, wait_for_tcp_port, wait_for_healthcheck, wait_for_http) to rely on require_container_id and nested NotStartedError.
  • Add a structured inspect(io : IO) : Nil implementation for DockerContainer that prints class, image, id, and name instead of full instance variable dump.
  • Add explicit : Nil return types to private helper methods add_exposed_port, add_fixed_exposed_port, add_env, and add_labels.
src/testcontainers/docker_container.cr
Reorganize error hierarchy into nested domain-specific error classes with backwards-compatible aliases.
  • Define Testcontainers::DockerContainer nested error classes NotStartedError, LaunchError, PortNotMappedError, HealthcheckNotSupportedError, and TimeoutError inheriting from TestcontainersError.
  • Define Testcontainers::Network nested error classes Error, NotFoundError, and AlreadyExistsError inheriting from TestcontainersError.
  • Replace usages of flat error names in DockerContainer and Network with the new nested constants (e.g., NotStartedError, HealthcheckNotSupportedError, Error, AlreadyExistsError).
  • Provide constant aliases in Testcontainers module mapping legacy flat error names (e.g., ContainerNotStartedError, NetworkError) to the new nested classes to maintain backward compatibility.
src/testcontainers/errors.cr
src/testcontainers/docker_container.cr
src/testcontainers/network.cr
Refactor Network to use scoped logging, safer network_id handling, and custom inspect output.
  • Introduce Log = Testcontainers::Log.for("network") and replace Testcontainers.logger.info with Log.info in create! and remove.
  • Add inspect(io : IO) : Nil on Network to emit class, name, and id.
  • Replace @network_id.not_nil! and generic NetworkError usages by local id variable or raising nested Error when network is not created, and use AlreadyExistsError for duplicate network creation.
  • Keep remove idempotent while improving error messages via nested Error.
src/testcontainers/network.cr
Tighten type signatures and style guidance for Nil-returning methods, and enable Ameba linting in CI and release workflows.
  • Add : Nil return type annotations to configure_env methods in all database and service container modules (Elasticsearch, MariaDB, Mongo, MySQL, Postgres, RabbitMQ).
  • Add : Nil return type annotation to Testcontainers::DockerClient.reset! class method.
  • Update AGENTS.md with an explicit best-practice note about using : Nil return type annotations for methods without meaningful return values.
  • Update .ameba.yml to remove src/ exclusions for Lint/NotNil, indicating 0 outstanding problems, while still excluding spec/docker_container_spec.cr.
  • Add a Run Ameba linter step (bin/ameba) to .github/workflows/ci.yml and .github/workflows/release.yml before formatting/build steps.
src/testcontainers/containers/elasticsearch.cr
src/testcontainers/containers/mariadb.cr
src/testcontainers/containers/mongo.cr
src/testcontainers/containers/mysql.cr
src/testcontainers/containers/postgres.cr
src/testcontainers/containers/rabbitmq.cr
src/testcontainers/docker_client.cr
.ameba.yml
.github/workflows/ci.yml
.github/workflows/release.yml
AGENTS.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 8, 2026

Warning

Rate limit exceeded

@dragosv has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 15 minutes and 26 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dd700855-ff24-472c-9c8e-ab02e9722c23

📥 Commits

Reviewing files that changed from the base of the PR and between 54cc68d and 33792dd.

⛔ Files ignored due to path filters (2)
  • .DS_Store is excluded by !**/.DS_Store
  • .github/.DS_Store is excluded by !**/.DS_Store
📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • .github/workflows/release.yml
  • PR_SUMMARY.md
  • shard.yml
📝 Walkthrough

Walkthrough

The PR enhances code quality and safety by introducing Ameba linting to CI/CD pipelines, standardizing explicit Nil return type annotations across container implementations, refactoring docker_container.cr with improved nil-safety patterns and structured logging, reorganizing the error hierarchy under descriptive namespaces with backward compatibility, and updating network.cr with better error handling and inspection capabilities.

Changes

Cohort / File(s) Summary
CI/CD Workflow Enhancement
.ameba.yml, .github/workflows/ci.yml, .github/workflows/release.yml
Integrated Ameba linter into build, test, and release workflows; removed prior exclusions for docker_container.cr and network.cr to enable comprehensive linting coverage.
Type Annotation Standardization
src/testcontainers/containers/elasticsearch.cr, src/testcontainers/containers/mariadb.cr, src/testcontainers/containers/mongo.cr, src/testcontainers/containers/mysql.cr, src/testcontainers/containers/postgres.cr, src/testcontainers/containers/rabbitmq.cr, src/testcontainers/docker_client.cr
Added explicit : Nil return type annotations to configure_env private methods across container classes and reset! in DockerClient module, improving type safety without altering behavior.
Error Hierarchy Reorganization
src/testcontainers/errors.cr
Restructured error classes under DockerContainer and Network namespaces; added backward-compatible top-level aliases to maintain API compatibility while improving error organization and discoverability.
Docker Container Refactoring
src/testcontainers/docker_container.cr
Introduced structured logging via Log constant, added require_container_id guard method to replace .not_nil! calls, added public inspect(io : IO) : Nil method, and updated multiple methods with explicit return type annotations and improved nil-safety patterns.
Network Infrastructure Updates
src/testcontainers/network.cr
Added Log constant for structured logging, introduced created? method, added public inspect(io : IO) : Nil method, and updated error handling to use new namespaced error types.
Documentation Update
AGENTS.md
Added best practice guideline recommending explicit Nil return type annotations on methods that don't return meaningful values.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • dragosv/testcontainers-crystal#2: Introduces DockerClient.default_labels and network label support; this PR's new add_labels helper and namespaced error reorganization provide supporting infrastructure for label handling patterns.

Poem

🐰 Type safety hops and logs now glow,
Errors nested, safe below,
Guard methods shield the nil abyss,
Containers inspect with whiskered bliss!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is vague and overly generic, describing broad 'Improved Crystal Coding Practices' without clearly conveying the main focus of the changeset. Consider a more specific title that highlights the primary change, such as 'Remove not_nil! and adopt LavinMQ-inspired patterns' or 'Nest error classes and add explicit Nil return types'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The PR description is comprehensive and well-structured, covering all major changes, testing details, and motivations clearly aligned with the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch style

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/ci.yml (1)

47-49: Minor ordering inconsistency with release workflow.

In ci.yml, the Ameba linter runs after the formatting check (lines 44-45), while in release.yml, Ameba runs before the formatting check. Consider aligning the step order for consistency, though both orderings work correctly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci.yml around lines 47 - 49, Reorder the steps in ci.yml
so the "Run Ameba linter" step runs before the formatting check to match
release.yml; locate the step labeled "Run Ameba linter" (currently running
bin/ameba) and move it above the formatting check step so the step order is
consistent across workflows.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@AGENTS.md`:
- Line 92: Fix the typographical error in the text snippet "pattern  : Nil" by
removing the extra space so it reads "pattern : Nil" (i.e., single space before
the colon); locate the occurrence of the exact string "pattern  : Nil" in
AGENTS.md and replace it with "pattern : Nil".

---

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 47-49: Reorder the steps in ci.yml so the "Run Ameba linter" step
runs before the formatting check to match release.yml; locate the step labeled
"Run Ameba linter" (currently running bin/ameba) and move it above the
formatting check step so the step order is consistent across workflows.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1b99cd70-8f5c-40b7-8d4d-436696cc13bc

📥 Commits

Reviewing files that changed from the base of the PR and between 528f4b8 and 54cc68d.

⛔ Files ignored due to path filters (3)
  • .DS_Store is excluded by !**/.DS_Store
  • .github/.DS_Store is excluded by !**/.DS_Store
  • src/.DS_Store is excluded by !**/.DS_Store
📒 Files selected for processing (14)
  • .ameba.yml
  • .github/workflows/ci.yml
  • .github/workflows/release.yml
  • AGENTS.md
  • src/testcontainers/containers/elasticsearch.cr
  • src/testcontainers/containers/mariadb.cr
  • src/testcontainers/containers/mongo.cr
  • src/testcontainers/containers/mysql.cr
  • src/testcontainers/containers/postgres.cr
  • src/testcontainers/containers/rabbitmq.cr
  • src/testcontainers/docker_client.cr
  • src/testcontainers/docker_container.cr
  • src/testcontainers/errors.cr
  • src/testcontainers/network.cr

- Use `begin/ensure` blocks for resource cleanup.
- Keep Docker endpoint configuration centralized via `Testcontainers::DockerClient`.
- When adding monkey-patches to `docr` types, isolate them in `patches.cr` with clear comments.
- Use Nil return type annotations pattern : Nil return types on methods that don't return meaningful values (e.g., def max_connections=(value : Int32) : Nil)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Typographical error: extra spaces before the colon.

There are two spaces before the colon in "pattern : Nil".

✏️ Proposed fix
-- Use Nil return type annotations pattern  : Nil return types on methods that don't return meaningful values (e.g., def max_connections=(value : Int32) : Nil)
+- Use Nil return type annotations pattern: Nil return types on methods that don't return meaningful values (e.g., `def max_connections=(value : Int32) : Nil`)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- Use Nil return type annotations pattern : Nil return types on methods that don't return meaningful values (e.g., def max_connections=(value : Int32) : Nil)
- Use Nil return type annotations pattern: Nil return types on methods that don't return meaningful values (e.g., `def max_connections=(value : Int32) : Nil`)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@AGENTS.md` at line 92, Fix the typographical error in the text snippet
"pattern  : Nil" by removing the extra space so it reads "pattern : Nil" (i.e.,
single space before the colon); locate the occurrence of the exact string
"pattern  : Nil" in AGENTS.md and replace it with "pattern : Nil".

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 8, 2026

Codecov Report

❌ Patch coverage is 43.90244% with 23 lines in your changes missing coverage. Please review.
✅ Project coverage is 61.14%. Comparing base (528f4b8) to head (af97cd0).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
src/testcontainers/docker_container.cr 44.11% 19 Missing ⚠️
src/testcontainers/errors.cr 42.85% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main       #3      +/-   ##
==========================================
+ Coverage   59.35%   61.14%   +1.78%     
==========================================
  Files          14       14              
  Lines         342      350       +8     
==========================================
+ Hits          203      214      +11     
+ Misses        139      136       -3     
Flag Coverage Δ
unittests 61.14% <43.90%> (+1.78%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@dragosv dragosv merged commit 520b661 into main Mar 8, 2026
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant