Fixrb

Fix guide, version 1

Getting started

A first specification: see it fail, make it pass, run it with the fix command.

This page builds a small project, greeting, with a class in lib/greeting.rb and its specification in fix/greeting_fix.rb.

Install

gem install fix-command

fix-command brings fix with it: the fix gem holds the language of specifications, and fix-command the fix command, which runs them. In a project with a Gemfile, add gem "fix-command" to it instead, run bundle install, and run the commands of this guide through bundle exec.

A specification

Specifications live in the fix directory of a project, usually one per file, in files whose names end with _fix.rb. In fix/greeting_fix.rb:

require "fix"
require_relative "../lib/greeting"

Fix :Greeting do
  on :call, "Alice" do
    it MUST eq "Hello, Alice!"
  end
end

exit(Fix[:Greeting].test { Greeting.new })

The specification names no class: it says what a greeting does, and the test, on the last line, picks what to test. The same specification could test another class tomorrow.

The code

A first version of the class, in lib/greeting.rb:

class Greeting
  def call(name) = "Hello #{name}!"
end

A first run

A specification file is a Ruby program: run it with ruby, from the root of the project, so that the lines name the file from there.

ruby fix/greeting_fix.rb
fix/greeting_fix.rb:6: Failure: expected "Hello Alice!" to eq "Hello, Alice!"

One line per expectation: where it is, the file and the line of its it; its outcome, Failure; and what happened, expected ACTUAL to eq EXPECTED. A comma is missing. The status of the process is 1, as for any failing program, which is all a terminal, a Rakefile or a CI service needs to know.

Making it pass

With the comma, in lib/greeting.rb:

class Greeting
  def call(name) = "Hello, #{name}!"
end

This time, run the fix command, from the root of the project:

fix
fix/greeting_fix.rb:6: Success: expected "Hello, Alice!" to eq "Hello, Alice!"
1 file met

The expectation is met. fix runs each _fix.rb file of the fix directory in a process of its own, lets its lines through, and ends with how many files were met; its status is 0 when all of them are. With one file, it says what ruby said; with fifty, it is the command to run.

That is the whole cycle: a specification says what a subject must do, a test picks the subject, and the status tells whether it does. The next page writes richer specifications: several contexts, parameters, and the two other levels, SHOULD and MAY.