Skip to content
CAI
Software that uses CAICheck a score

savonrb/savon

66.1

Adequate · 19 September 2026

2.4k

lines of production code

Ruby

primary language

1

measurement over time

CAI band scale
CAI lens gauges

What this system is

This system is the Savon library, a Ruby client for interacting with SOAP web services. It provides core functionality for building SOAP requests, parsing WSDL definitions, and managing HTTP transport layers, now supporting both the legacy HTTPI backend and an opt-in Faraday transport. The system includes a robust testing infrastructure with mock expectations, SSL/mTLS support, and integration tests for complex scenarios like authentication and concurrent requests.

How it got here

2009 — Modernization and test infrastructure

7 changes.

The project underwent significant modernization by updating dependencies to support Ruby 3.0, introducing an opt-in Faraday transport layer, and restructuring the library code. This period also involved replacing the legacy test suite with a comprehensive RSpec-based infrastructure to ensure coverage of core components.

2010–2013 — Test infrastructure and mock system overhaul

5 changes.

This period focused on significantly expanding the project's testing capabilities by introducing a local integration test server with SSL and authentication support, alongside comprehensive SSL fixtures. The mock system was refactored to use an observer-based architecture with fluent expectation matchers, enabling rigorous verification of SOAP interactions and transport behaviors.

2026 — Faraday transport integration

5 changes.

The project introduced an opt-in Faraday HTTP transport alongside the existing HTTPI backend, enabling advanced transport-level configuration. Comprehensive integration tests and fixtures were added to verify concurrent requests, WSDL parsing, and error handling for both transport implementations.

Features

Introduce opt-in Faraday HTTP transport alongside existing HTTPI backend

Savon now supports an opt-in HTTP transport backed by Faraday, allowing users to configure their own Faraday connection for advanced transport-level concerns like SSL, authentication, proxies, and middleware. This new transport layer, located in lib/savon/transport, includes a Faraday-specific implementation (lib/savon/transport/faraday.rb) that handles header assembly, request execution, and response normalization, while sharing common logging (lib/savon/transport/logging.rb) and response abstraction (lib/savon/transport/response.rb) with the existing HTTPI transport (lib/savon/transport/httpi.rb). The response object normalizes cookies differently per transport: HTTPI returns an array of HTTPI::Cookie objects, while Faraday returns a plain hash of name-value pairs, ensuring users of the Faraday path do not depend on HTTPI types.

lib/savon/transport · high confidence

Introduce opt-in Faraday transport with migration hints

Savon now supports an opt-in Faraday transport layer alongside the existing HTTPI transport. Users can switch by setting \transport: :faraday\ in their client configuration, which exposes a \client.faraday\ accessor for configuring middleware, SSL, and timeouts. When using Faraday, HTTPI-specific global options (such as \proxy\, \ssl\\\, \basic\_auth\, and \adapter\) are rejected at initialization; instead, Savon provides detailed migration hints in the error message to guide users toward the equivalent Faraday setup.

lib/savon · high confidence

Behavioural changes

Added binstubs for direct command execution

Executable binstubs have been added for bundle-audit, bundler-audit, rake, rspec, and rubocop in the bin directory. These scripts allow users to run these tools directly by name (e.g., \bundle-audit\) without needing to prefix commands with \bundle exec\, simplifying the workflow for development and testing tasks.

bin · high confidence

New mock interface with expectation matchers and observer-based verification

The Savon mock system has been refactored to use a new \MockExpectation\ class and an observer-based architecture. Users can now define expectations using a fluent interface (e.g., \expects(...).with(...).returns(...)\) and utilize the \:any\ symbol or RSpec-style matchers (via \===\) within expected message hashes for flexible validation. The mock system now actively verifies that all defined expectations are met and that responses are configured, raising specific errors if requests are unexpected, messages mismatch, or expected calls do not occur. A dedicated \SpecHelper\ is provided to integrate this verification into test suites, ensuring mocks are validated at the end of test runs.

lib/savon/mock · high confidence

Refactored library structure and error hierarchy

The library has been reorganized to use a modular directory structure, replacing the previous flat file layout with separate require paths for version, client, model, and string utilities. The error handling system was updated to introduce a custom \Savon::Error\ base class, with specific exceptions like \UnknownOptionError\ and \UnknownOperationError\ inheriting from it. Additionally, the codebase now enforces frozen string literals and exposes an observer pattern for notifying external listeners about operations.

lib · high confidence

Test coverage

Added SSL and WSDL test fixtures for integration specs; Added SSL test fixtures for client certificates and keys; Added comprehensive test coverage for Savon core components; Added integration tests for Faraday transport and cookie handling; Added integration tests for concurrent requests, real-world WSDL parsing, and error handling; Added spec support infrastructure for testing; Added test coverage for the new transport abstraction layer; Initial test infrastructure setup with RSpec and SimpleCov; New local integration test server with authentication and SSL support; Removal of legacy test suite and fixtures.

Dependencies

Savon gemspec and Gemfile updated for modern Ruby and HTTP stack

The Savon gemspec and Gemfile have been updated to require Ruby 3.0.0 or higher and modernize the dependency stack. Runtime dependencies now include httpi 4.x, wasabi 5.x, and nokogiri 1.8.1+, replacing older libraries like hpricot and smacks-apricoteatsgorilla. Development dependencies have also been refreshed, adding bundler-audit, rubocop, and puma 8.x to support current CI and testing workflows.

(dependencies) · high confidence

Housekeeping

Project initialization and repository configuration

The repository has been initialized with standard project configuration files, including a \.gitignore\ for Ruby artifacts, a \RuboCop\ configuration (\.rubocop.yml\) targeting Ruby 3.0 with RSpec and Rake plugins, and a corresponding \.rubocop\_todo.yml\ generated from the existing codebase. Documentation and process files have been added, including a \CHANGELOG.md\ following Keep a Changelog format, a \README.md\ with usage examples and installation instructions, a \CODE\_OF\_CONDUCT.md\, a \CONTRIBUTING.md\ guide, a \SECURITY.md\ policy, and a \RELEASING.md\ workflow. The legacy \README.rdoc\ has been removed.

(repo-wide) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Baseline

  • First survey — no prior run to compare against. CAI 66.

Lenses

  • Code Health 98
  • Architecture 100
  • Maturity 55
  • Readiness 64
  • Security 79

Changes since last survey

  • 300 commits — 263 feature/other, 37 fixes

By area

  • (root) — 145 commits
  • lib/savon — 52 commits
  • .github/workflows — 38 commits
  • spec/savon — 26 commits
  • (repo) — 19 commits
  • spec/integration — 10 commits
  • .github/ISSUE_TEMPLATE — 3 commits
  • .github/stale.yml — 3 commits
  • .github/PULL_REQUEST_TEMPLATE.md — 1 commit
  • .github/dependabot.yml — 1 commit
  • spec/fixtures — 1 commit
  • spec/spec_helper.rb — 1 commit

Notable commits

  • fix: Add regression-guard specs for previously uncovered branches (#1075)
  • fix: CI: Travis maintenance: add JRuby 9.2; fix JRuby 9.1 build; configure Rubinius (#921)
  • fix: Expose a bug with old :attributes! syntax (#718)
  • fix: Fix #986 do not include xmlns namespace from WSDL (#989)
  • fix: Fix 2.17.3 link in changelog
  • fix: Fix Operation endpoint error spec
  • fix: Fix RuboCop todos (#1043)
  • fix: Fix SOAPFault.present? ignoring its xml argument
  • fix: Fix Savon::Model [CVE redacted]
  • fix: Fix a problem when http.body is empty (#800)
  • fix: Fix building for test (#799)
  • fix: Fix changelog URI
  • fix: Fix circular loading (#835)
  • fix: Fix cookies regression and add Faraday-native cookie shapes
  • fix: Fix detecting Soap 1.1 Fault when faultcode and faultstring are empty (#875)
  • fix: Fix elementFormDefault="qualified" regression (#917)
  • fix: Fix exception when soap:Fault contains invalid encoding (#923)
  • fix: Fix integration spec
  • fix: Fix linting
  • fix: Fix multipart Content-Type dropped on attachment requests
  • …and 280 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

savonrb/savon was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 19 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 5a70d2f89876efa58f6f5a4d9298cca64350cb67 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-13a154b7f5d1.