Skip to content

Repository files navigation

The Reviewable Codebase — examples

Runnable Ruby from the RubyConf Africa talk The Reviewable Codebase: Architecture and Performance Gates in Ruby, by Victor Turuthi.

Slides: https://www.turuthi.xyz/talks/reviewable-codebase/

One directory per example, covering the four properties: gates, budgets, boundaries and blessed paths.

Everything here is plain Ruby. No Rails, no database, no ActiveSupport — the query-budget example ships a forty-line notification bus of its own so the pattern can be read without framework knowledge. Where a Rails application would differ, the file says so.

Running it

bundle install
bundle exec rspec          # 44 examples
bundle exec rubocop        # clean
02_verify/bin/verify .     # the whole gate, one command

bin/verify is the interesting one:

+ rubocop clean
+ rspec: 44 examples, 0 failures
+ query budget: within budget

Neither the Brakeman nor the pending-migrations verifier appears, because this repository is not a Rails application and has no db/migrate — that is the pattern working, not a gap. Each verifier decides for itself whether it applies.

Tools worth naming

Three of these do work you would otherwise write yourself:

Tool Job Where it runs
brakeman Rails security warnings — SQL injection, mass assignment, unsafe redirects A verifier: 02_verify/lib/verify/brakeman.rb
prosopite / bullet Detect N+1s while the suite runs, and name the line The test suite: 04_query_budget/rails/prosopite.rb
derailed_benchmarks Memory and boot time, per gem On demand, when a boot budget fails

The detectors and the budget do different jobs and belong together. A detector tells you where the N+1 is; the budget asserts a number, so it also catches the page that got expensive without repeating itself, and stops the count creeping back once it is fixed.

The examples

Directory Property What it shows
01_discount_calculator Gates A green test with full line coverage that verifies almost nothing, and the mutation run that measures the gap
02_verify Gates The verifier pattern: self-selecting checks, short failure output, no skip flag
03_pre_push_hook Gates Lint the diff, not the repository; fix before complaining
04_query_budget Budgets Query count as an assertion, and the N+1 it catches
05_allocations Budgets Allocations instead of wall-clock, because a flaky gate gets disabled
06_boundaries Boundaries The same feature as a fat controller and as a service object
07_scope_check Boundaries Did the change stay where it said it would?
08_types_gate Gates A signature on the boundary, and the spec that fails when the class drifts from it
09_boot_budget Budgets Boot time, the Puma worker that will not come up, and the manifest that catches it

Numbers in the talk, and how to reproduce them

Every figure on a slide comes from this repository.

Mutation coverage — 32.78%

01_discount_calculator/bin/mutant-shipped

61 mutations, 20 killed, 41 alive against the shipped test. The recorded run is in 01_discount_calculator/mutant_output.txt, including the mutation that replaces @order.customer.vip? with true and survives.

The same subject scored against the hardened suite:

01_discount_calculator/bin/mutant-shipped hardened

59 killed, 2 alive, 96.72%.

Query budget — 412 queries

The unbatched report costs one query for the orders plus three per order, so the count is a function of the fixture:

04_query_budget/bin/demo               # 25 orders  ->  76
04_query_budget/bin/demo --orders 137  # 137 orders -> 412

Boot budget — 0.007s and two libraries

09_boot_budget/bin/boot-profile

Adding one line — require "csv" — takes that to 0.057s and ten libraries. Recorded in 09_boot_budget/boot_output.txt.

Allocations — 308

A fifty-item order serialises in 308 allocations on Ruby 3.4, the same number on every run. The budget in the spec is 400.

The deck

The slides are published at https://www.turuthi.xyz/talks/reviewable-codebase/ — their source lives in a separate repository, since it carries the speaker notes.

Layout

Each numbered directory keeps its own lib/ and spec/, so a directory can be copied out on its own and still make sense. The shared spec/spec_helper.rb puts every lib/ on the load path, which is what lets one rspec run cover all of them.

About

Runnable Ruby from the RubyConf Africa talk: gates, budgets, boundaries and blessed paths

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages