RSpec::RfcHelper
RSpec RFC Helper is a RSpec module to help tracking implementation of big specifications, when having only comments in code or tests becomes too tedious to maintain and follow.
Installation
Add the gem to your Gemfile:
gem 'rspec-rfc-helper'
Usage
- Write the specs: read the RFC/specifications that needs to be implemented and extract everything that has to be implemented. This is tedious.
- Use the gem in Rspec
- Sprinkle your tests to reference the specs
- Run the tests
- Open the report
Writing specs
...in a YAML file
Specs in a YAML file can be loaded easily when integrated in RSpec; the format is simple:
# Optional, the specification/RFC name
name:
# Optional, the URL to the RFC/specification
url:
# Here we are
specs:
# You should at least have one section in the file
#
# Required. Section/chapter... It's converted to a string when imported
- section: 1
# Required. Unique section identifier. IDs of the specs in this section will be prefixed by it. Converted to symbol
# so only the character class used for symbols should be used.
id:
# Optional: URL to the section
url:
specs:
# Optional. A spec without an ID will appear with an "unknown" status in the report. It allows you to fill the
# specs list without thinking right now how you will identify it.
# Spec IDS must be unique across all the specs, but are automatically prefixed with the section's ID, which allows
# definition of two specs with the same ID over different sections.
- id:
# Required. Text must be unique across specs. Imperative verbs have to be bracketed, so you can use the same paragraph
# in multiple specs, targeting something different without losing context.
text: It [[MUST]] work
For more example, there is a fixture in spec/fixtures/rfc.yaml
, and the example spec file in spec/rfc.yaml
.
...programmatically
Declaring specs programmatically can be interesting if you manage somehow to process the original specification automatically.
# Create an instance of the Specs class: it holds the specs. "name" and "url" are optional
specs = RSpec::RfcHelper::Specs.new name: 'The easy thing RFC', url: 'https://somewhere'
# Create a section
spec.add_section number: '1.1', title: 'Implementation', id: :implementation
# Add a spec:
# ID is optional. A spec without an ID will appear with an "unknown" status in the report. It allows you to fill the
# specs list without thinking right now how you will identify it.
# Spec IDS must be unique across all the specs, but are automatically prefixed with the section's ID, which allows
# definition of two specs with the same ID over different sections.
#
# Here, spec ID will be :implementation__do_something
spec.add section: '1.1', text: 'It [[MUST]] do something', id: :do_something
# For long texts, use heredocs:
spec.add section: '1.1', text: <<~TXT, id: :do_something
Some long text, but the context is important to understand
what you [[MUST]] implement, how you SHOULD do it
and what you MAY do if you feel like it
TXT
Usage in RSpec
...with the spec file: use the module
# spec_helper.rb
require 'rspec/rfc-helper'
RSpec.configure do |config|
config.before(:suite) do
RSpec::RfcHelper.start_from_file 'path/to/your/spec.yaml'
end
config.after do |example|
RSpec::RfcHelper.add_example example
end
config.after( :suite) do
RSpec::RfcHelper.save_markdown_report 'path/to/report.md'
end
end
...programmatically: use the classes
# spec_helper.rb
require 'rspec-rfc-helper'
RSpec.configure do |config|
# Putting all the specs in the spec_helper.rb is not a good idea, but as you go programmatically, i'll let you find
# a way to organize yourself better.
# The main point here is to use the same instance for the definitions and the usages in the RSpec hooks
rfc_helper = RSpec::RfcHelper::Spec.new name: 'Plumbus management', url: 'https://somewhere'
rfc_helper.add_section #...
rfc_helper.add #...
# Alternatively, you can still load a file
rfc_helper = RSpec::RfcHelper::Spec.new_from_file 'path_to_file'
config.after do |example|
rfc_helper.add_example example
end
config.after( :suite) do
rfc_helper.save_markdown_report 'path/to/report.md'
end
end
Reference the specs in your suite
RFC Helper uses the RSpec tagging system to track and assign examples to specs.
RSpec.describe 'Something' do
# references spec "spec_id" in section "section1"
it 'works', rfc: :section1__spec_id do
# ...
end
# references spec "spec_id" in section "section1", and "other_spec_id" in "other_section"
it 'works', rfc: [:section1__spec_id, :other_section__other_spec_id] do
# ...
end
end
Development
After checking out the repo, run bundle install
to install dependencies. Then, run bundle exec rspec
to run the tests.
You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the
version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version,
push git commits and the created tag, and push the .gem
file to rubygems.org.
Tools
Well, we use RSpec for testing.
Also, we use Rubocop for code style.
Contributing
All contributions, ideas and discussions are welcome. Feel free to open issues and feature requests on the bug tracker.
You also can join the ExperimentsLabs Matrix chatroom to discuss of the project.