| Concept | Meaning |
|---|---|
| Chained method | A sub-method added to a custom matcher with chain |
| Purpose | Extend matcher behavior with extra options or context |
| Example | expect(user).to have_error_message("can't be blank").on_field(:name) |
| Config effect | include_chain_clauses_in_custom_matcher_descriptions = true makes RSpec include .on_field(:name) in failure messages |
| Line | Meaning |
|---|---|
require 'spec_helper' |
Loads the basic RSpec configuration. |
ENV['RAILS_ENV'] |
Ensures Rails runs in the test environment. |
require_relative '../config/environment' |
Loads the Rails application environment. |
| `abort("The Rails environmen |
| Category | 👍 | 💬 Notes |
|---|---|---|
| Bundler & vendor | ✅ | /vendor/* and .bundle correctly ignored. |
| Environment files | ✅ | You’re ignoring .env and .env.* — good for security. |
| Logs & tempfiles | ✅ | Includes .keep exceptions — perfect for Rails conventions. |
| PID & storage dirs | ✅ | Very clean setup for /tmp/pids and /storage. |
| Public assets | ✅ | /public/assets is safely ignored — prevents committing precompiled assets. |
| Credentials | ✅ | `/config/maste |
| Line | Meaning |
|---|---|
RSpec.configure do |
Opens the RSpec configuration block — all settings go inside this. |
config.expect_with :rspec do |
Configures how expectations (expect) work. |
expectations.include_..._descriptions = true |
Improves custom matcher messages by including chained conditions for clearer failure output. |
config.mock_with :rspec do |
Configures RSpec’s mocking framework. |
| Controller Output | Expectation Type | Result |
|---|---|---|
| Array of hashes | Array of strings | ❌ Fail (structural mismatch) |
| Array of strings | Array of strings | ✅ Pass (matches your current code) |
| Form | Example | When to Use |
|---|---|---|
| New (symbol) | { status: 'ok' } |
✅ Rails default & preferred |
| Old (rocket) | { 'status' => 'ok' } |
When keys aren’t symbols (like strings or variables) |
Controller Hash → JSON → RSpec Test
| Step | Controller Code Example | JSON Output | RSpec Expectation json = JSON.parse(response.body) (*) json = JSON.parse(response.body, symbolize_names: true) |
|---|---|---|---|
| 1. Symbol keys | render json: { status: :ok, code: 200 } |
{'status':'ok','code':200} |
expect(json['status']).to eq('ok') |
| 2. String keys |
| Aspect | Benefit | Possible Drawback |
|---|---|---|
| Memory use | Fewer objects | None significant |
| Performance | Faster for literal-heavy code | Slower if code needs to mutate |
| Code safety | Prevents accidental mutation | Breaks mutation-based logic |
| Compatibility | Works fine in modern code | May break older gems |
| Predictability | Immutable by default | Surprising when global, invisible switch |
| Aspect | Effect |
|---|---|
| Performance | Slightly improved (fewer allocations). |
| Memory usage | Reduced. |
| Safety | More immutable code, fewer side effects. |
| Compatibility | Might break older gems or DSLs relying on mutable strings. |
| Rails core | Generally safe, but not guaranteed for all gems. |
| Situation | Recommended Action |
|---|---|
| Modern app with well-maintained gems | Safe to try globally (test in dev/test first). |
| Legacy code or older gems | Risky — better use the magic comment per file. |
| Gem development | Avoid setting it globally — you’ll affect consumers. |
| Rails itself | Rails 7+ core code is largely safe with frozen literals, but it doesn’t assume global freezing. |