A YARD plugin that embeds RSpec examples alongside method documentation in the generated YARD documentation.
This plugin allows you to see RSpec test examples directly in your YARD-generated documentation. When you document a method and have corresponding RSpec tests, those tests will automatically appear in a "RSpec Examples" section in the method's documentation.
Add this line to your application's Gemfile:
gem 'yard-rspec-coverage'Or install it yourself:
gem install yard-rspec-coverage- Write your Ruby code with YARD documentation comments
- Write RSpec tests using
describeanditblocks - Generate documentation with the plugin loaded:
yard doc --plugin rspec-coverage 'lib/**/*.rb' 'spec/**/*.rb'List the spec files explicitly: without file arguments (or files in .yardopts) YARD only parses
lib/ and app/, so it finds no examples.
The spec files are parsed for their examples only. Classes, modules and methods they define
outside describe blocks, such as helpers in spec/support, are left out of the documentation and
of yard stats. Spec files are the files in a spec/ directory and files ending in _spec.rb.
Declare the gem with require: false in your Gemfile, so you choose which YARD runs use the
plugin; Bundler.require would load it into every YARD run in the process. Then require the tasks
from your project's Rakefile:
require 'yard_rspec/rake_tasks'
YardRspec::Config.minimum_rspec_coverage = 80.0 # default: 100.0
YardRspec::Config.files = ['{lib,spec}/**/*.rb'] # defaultThis defines two tasks:
rake yard:docgenerates the documentation with therspec-coverageplugin. It writes todoc/, like other YARD tasks such asyard:coverage, so run it last.rake yard:rspec_coveragelists the public methods without RSpec examples and fails when the coverage is belowminimum_rspec_coverage. Attribute readers/writers, aliases and code in spec files are not counted. It also lists describe blocks that name a class or method that cannot be found, such as a typo, without failing. It parses onlyYardRspec::Config.files: the options in.yardopts, such as--exclude, apply, but the files listed there do not.
The plugin never logs YARD warnings, so it is safe in YARD runs with --fail-on-warning.
Or use the provided build script:
./build.shGiven this code:
class String
# Converts a string to pig latin
#
# @return [String] the pig latin version of the string
def pig_latin
self[1..-1] + self[0] + "ay"
end
end
describe String, '#pig_latin' do
it "converts 'hello' to pig latin" do
"hello".pig_latin.should == "ellohay"
end
it "works with single character strings" do
"a".pig_latin.should == "aay"
end
endThe generated documentation for String#pig_latin will include an "RSpec Examples" section showing both test cases.
The plugin consists of four main components:
- Handler (
lib/yard_rspec/handler.rb): Parses RSpecdescribeblocks and extractsitexamples - Template (
templates/default/method_details/html/rspec_specs.erb): Displays the examples in the documentation - Setup (
templates/default/method_details/html/setup.rb): Integrates the template into YARD's rendering pipeline - Assets (
templates/default/fulldoc/html/): A stylesheet and a script for the "expand all" link
Each example shows its description and its syntax-highlighted code. Pending examples are labelled "pending", and a public method without specs gets a red "no specs" label.
The plugin supports the following RSpec syntax:
describe ClassName, '#method_name'for instance methodsdescribe ClassName, '.method_name'for class methodsdescribe ClassName, '.new'(or'#new') for the constructor, documented as#initialize, unless the class defines a class methodnewitselfit "description"blocks within describe blocks, also with a description split over several lines as adjacent strings ('spins ' \ 'twice')specify "description"andexample "description"blocks (aliases forit)xit,xspecifyandxexampleblocks (excluded examples) and examples without a block (it 'spins twice', which RSpec reports as "Not yet implemented"), labelled "pending". They do not count as coverage: a method with only pending examples is reported as without specs.- nested
context "..."anddescribe "..."blocks, shown as groups of examples
These RSpec constructs are not recognized. Examples written with them do not appear in the documentation and do not count towards RSpec coverage.
- Examples that are not written as a command without parentheses followed by a block:
it('x') {}the one-linerit {is_expected.to be_ok}andit do ... endwithout a description. - Focused examples:
fit,fspecifyandfexample. A focused example makes RSpec skip the rest of the suite, so it should not be committed; the plugin does not document it. - The
pendingandskipkeywords. - Capybara's
scenario(andfeatureas a group), and theitsmethod of rspec-its. - Shared examples:
it_behaves_like,it_should_behave_like,include_examplesandinclude_contextare ignored, so the examples of ashared_examplesgroup are not attributed to the methods that use it. The examples inside ashared_examplesblock are attributed to the enclosing method, as if they were written directly in the describe block. - Focused and excluded groups:
fdescribe,xdescribe,fcontext,xcontextandexample_groupare not recognized as groups. Their examples are still collected, but without the group, so the group's description is lost. Adescribe '#method'written with one of these keywords is not linked to the method.
Limitations of the supported constructs:
- A description is shown as written in the spec. So interpolation stays visible
(
it "loop #{index}"is shown asloop #{index}) and so do escape sequences (it "a\tb"is shown asa\tb, where RSpec shows a tab). Examples generated in a loop are listed once. - Examples whose description is not a string literal, or is empty, are shown as
example. That includes a heredoc (it <<~DESC do).
To build the plugin's own documentation, with its specs embedded:
./build.shThen open doc/index.html in your browser. build.sh also runs all the checks below.
Run all checks (RuboCop, a dependency vulnerability audit, the specs with SimpleCov, YARD documentation coverage and RSpec coverage) with:
bundle exec rakeUpdate the version in yard-rspec-coverage.gemspec and CHANGELOG.md (a ## <version> heading
instead of ## Unreleased), commit, and run the checks for a release:
bundle exec rake prereleaseIt checks the commit, runs rake and yard:doc, builds and tests the gem, and runs mutation
testing. Set COMPARE_PROJECT (and COMPARE_RSPEC) to also compare the plugin with
rspec --dry-run in a real project, see AGENTS.md. Then push a matching tag:
git tag v0.2.0
git push origin v0.2.0The release workflow runs all checks and publishes the gem to rubygems.org with Trusted Publishing, so no API key is stored.
MIT License
Inspired by the yard-spec-plugin by Loren Segal.