Review, fix 10 confirmed defects, and take the suite from 24 to 115 tests (0.4.0) - #3
Open
peterclark wants to merge 2 commits into
Open
Review, fix 10 confirmed defects, and take the suite from 24 to 115 tests (0.4.0)#3peterclark wants to merge 2 commits into
peterclark wants to merge 2 commits into
Conversation
Document the repo for future Claude Code sessions and record a review of the gem at 4c1e46f. CLAUDE.md covers the commands (including the Bundler pin that blocks `bundle install` on modern Bundler), the single-endpoint POST design and its indexed-key wire format, the process-global configuration and shared class-variable client, and the load-time caching wiring. PLAN.md records 12 defects, each reproduced against the current code on Ruby 3.3.6 rather than inferred, and lays out four phases (toolchain, test harness, defect fixes, coverage) plus five refactoring proposals. Notable findings: `Redcap.new` silently discards block configuration, query values are interpolated into filterLogic unescaped, the API token is written to logs when logging is enabled, and multi-record `update` reports failure on success. Documentation only; no library code changes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011fTWYMojvbXxVp445oYaJ4
…erage Executes Phases 1-4 of PLAN.md. Refactoring proposals R1-R5 remain open. Phase 1 - toolchain. Removed the `bundler ~> 1.13` development pin that made `bundle install` fail on every Bundler >= 2, relaxed rake and hashie, set required_ruby_version, and replaced the dead Travis config with GitHub Actions on Ruby 3.1/3.2/3.3. Phase 2 - harness. Added WebMock with net connections disabled, so an unstubbed request fails rather than reaching the network, plus a stub helper that records decoded request bodies. Global configuration and Record's client now reset between tests, making the suite order-independent. Phase 3 - defects. Fixed all ten confirmed bugs, each with a regression test: configuration precedence (a bare `Redcap.new` silently discarded block configuration), unescaped filterLogic interpolation, the token appearing in log output, `update` reporting failure on multi-record writes, `find` returning a truthy empty record, `flush_cache` not existing when caching was off, duplicated record_id in field lists, `configure` raising without a block, query internals only appearing private, and the five stubs returning nil. Phase 4 - coverage. Every method that talks to REDCap is now exercised, which none were before; 24 examples to 115. Defining error behavior was a prerequisite, so the Redcap::Error hierarchy and request timeouts came forward from R3. Verified by running the new suite against the original library in an isolated copy: 56 of 115 fail there, including a named regression for every defect, and all pass here across five seeds and both cache modes. Released as 0.4.0 rather than 0.3.2 because the error hierarchy and NotImplementedError stubs change observable behavior. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011fTWYMojvbXxVp445oYaJ4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reviews the gem at
4c1e46f, records the findings inPLAN.md, and implements Phases 1–4 of that plan. Refactoring proposals R1–R5 remain open.Why
The suite was green — 24 runs, 0 failures — and that green was misleading. No test performed or stubbed an HTTP request, so every method that talks to REDCap was uncovered, and several config assertions passed vacuously as
nil == nil. Most of the defects below sat in that gap. Separately,bundle installfailed on any modern Bundler because of abundler ~> 1.13pin, so the project could not be set up as shipped.Defects fixed
Each was reproduced against
4c1e46fbefore being fixed, and each ships with a regression test.Redcap.newsilently discarded block configuration. A bareRedcap.newafterRedcap.configure { … }rebuilt the configuration fromENV, replacing the credentials the block had just set withnil. The README's documented setup flow did not work.filterLogicunescaped.where(name: "O'Brien")— or anything caller-supplied — closed the string literal early, so the rest was read as filter syntax and could widen the result set.client.log = true.updatereported failure for multi-record writes, comparing the returned count against a hard-coded1.Record.findreturned a truthy empty record instead ofnilwhen nothing matched, soif (p = Person.find(id))never guarded anything.flush_cachedid not exist unless caching was on at require time, though the README documents calling it.record_idin field lists built from string names;Redcap.configureraisingLocalJumpErrorwithout a block;privatenot applying to thedef self.query internals; five query stubs returningnilsilently.Also changed
Errors now descend from
Redcap::Error—ConfigurationError,ResponseError(carryingstatus/body),ParseError— rather than leakingRestClient::andJSON::exceptions. Requests time out (60s default) instead of hanging indefinitely. Defining error behavior was a prerequisite for Phase 4's error-path tests, so this came forward from proposal R3.Toolchain: dropped the Bundler pin, relaxed
rake/hashie, setrequired_ruby_version >= 3.0, and replaced the dead Travis config with GitHub Actions on Ruby 3.1/3.2/3.3.Tests: WebMock with
disable_net_connect!, so an unstubbed request fails rather than reaching the network, plus a helper that records decoded request bodies — assertions check what the gem sends, not just what it returns. Global state resets between tests, so ordering is safe.Verification
bundle install && bundle exec rake testnow succeeds from clean.gem buildproduces a valid package.Two corrections to the plan, made while implementing it
bindir = "exe"was broken was wrong —bin/for dev scripts andexe/for shipped executables is the standard Bundler layout, and this gem ships none. Changing it would have installedconsoleandsetuponto users' PATH. Left as-is.Client#fields, which would have cost a metadata round-trip on every query.Both are recorded in a status block at the top of
PLAN.md.Known limitations
Nothing is verified against a live REDCap instance; the suite asserts what the gem sends. In particular, backslash-escaping quotes in
filterLogicfollows the common convention but is not confirmed against REDCap's parser — worth checking before relying on it.The one-project-per-process ceiling remains:
Record's client is a class variable shared with every subclass, so two subclasses cannot use different tokens. That is proposal R1, and it is now documented in the README rather than left implicit.Released as
0.4.0rather than the0.3.2the plan anticipated, since the error hierarchy andNotImplementedErrorstubs change observable behavior.