Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
T

transpec

> 编程语言
Open source

The RSpec syntax converter

1.0K stars0 likes0 views
WebsiteGitHub

About

The RSpec syntax converter

Transpec

Transpec is a tool for converting your specs to the latest RSpec syntax with static and dynamic code analysis.

With Transpec you can upgrade your RSpec 2 specs to RSpec 3 in no time. It supports conversions for almost all of the RSpec 3 changes – not only the expect syntax. Also, you can use it on your RSpec 2 project even if you're not going to upgrade it to RSpec 3 for now.

Check out the following posts for the new RSpec syntax and the changes in RSpec 3:

  • RSpec's New Expectation Syntax
  • RSpec's new message expectation syntax
  • Notable Changes in RSpec 3

If you are going to use Transpec in the upgrade process to RSpec 3, read the RSpec official guide:

  • https://relishapp.com/rspec/docs/upgrade

Examples

Here's an example spec:

…

Transpec would convert it to the following form:

…

Actual examples

You can see actual conversion examples below:

  • https://github.com/yujinakayama/guard/commit/transpec-demo
  • https://github.com/yujinakayama/mail/commit/transpec-demo
  • https://github.com/yujinakayama/twitter/commit/transpec-demo

Installation

Simply install transpec with gem command:

bash
$ gem install transpec

Normally you don't need to add transpec to your Gemfile or *.gemspec since this isn't a tool to be used daily.

Basic Usage

Before converting your specs:

  • Make sure your project has rspec gem dependency 2.14 or later. If not, change your Gemfile or *.gemspec to do so.
  • Run rspec and check if all the specs pass.
  • Ensure the Git repository is clean. (You don't want to mix up your changes and Transpec's changes, do you?)

Then, run transpec in the project root directory:

bash
$ cd some-project
$ transpec

This will run the specs, convert them, and overwrite all spec files in the spec directory.

After the conversion, run rspec again and check whether everything is still green:

bash
$ bundle exec rspec

If it's green, commit the changes with an auto-generated message that describes the conversion summary and helps your team members to understand the new syntax:

bash
$ git commit -aeF .git/COMMIT_EDITMSG

And you are done!

Advanced Usage

Convert only specific files

You can pass transpec arbitrary paths to convert:

bash
# You always need to be in the project root directory
$ cd some-project

# Convert only files in `features` directory
$ transpec features

# Convert only files in `spec/foo` and `spec/bar` directory
$ transpec spec/foo spec/bar

# Convert only `spec/baz_spec.rb`
$ transpec spec/baz_spec.rb

Note that the current working directory always needs to be the project root directory, so that Transpec can know where the root is.

Enable/disable specific conversions

You can disable specific conversions that are enabled by default with -k/--keep option, and enable conversions that are disabled by default with the -v/--convert option.

If you are willing to try the latest and modern syntax, run the following on RSpec 3:

$ transpec --convert example_group,hook_scope

See -k/--keep and -v/--convert for more details.

Options

Though Transpec ships with sensible defaults that essentially conform to the RSpec 3 defaults, you can customize the conversion behavior.

-f/--force

Force processing even if the current Git repository is not clean.

bash
$ git status --short
 M spec/spec_helper.rb
$ transpec
The current Git repository is not clean. Aborting. If you want to proceed forcibly, use -f/--force option.
$ transpec --force
Copying project for dynamic analysis...
Running dynamic analysis with command "bundle exec rspec"...

-c/--rspec-command

Specify a command to run your specs which is used for dynamic analysis.

Transpec needs to run your specs in a copied project directory for dynamic analysis. If your project requires some special setup or commands to run specs, use this option. bundle exec rspec is used by default.

Note that the command to run dynamic analysis does not affect to the files or specs to be converted. This means that even if you specify a command that only runs a subset of the files in your spec suite or a subset of the specs in a file, every spec will be converted. For this reason, it's recommended to provide a command that runs full spec suite to -c/--rspec-command. If you want to convert only a subset of the files in a spec suite, pass the paths to transpec. See Advanced Usage for more details.

You can change the temporary directory that the your project will be copied by specifying the TMPDIR environment variable.

bash
$ transpec --rspec-command "./special_setup.sh && bundle exec rspec"

-k/--keep

Keep specific syntaxes by disabling conversions.

bash
$ transpec --keep should_receive,stub

Conversions enabled by default

Note that some syntaxes are available only if your project's RSpec is specific version or later. If they are unavailable, conversions for such syntaxes will be disabled automatically.

Type Target Syntax Converted Syntax
should obj.should matcher expect(obj).to matcher
oneliner it { should ... } it { is_expected.to ... }
should_receive obj.should_receive(:message) expect(obj).to receive(:message)
stub obj.stub(:message) allow(obj).to receive(:message)
have_items expect(obj).to have(n).items expect(obj.size).to eq(n)
its its(:attr) { } describe '#attr' { subject { }; it { } }
pending pending 'is an example' { } skip 'is an example' { }
deprecated All other deprecated syntaxes Latest syntaxes

See Supported Conversions for more details.

-v/--convert

Enable specific conversions that are disabled by default.

bash
$ transpec --convert example_group

Conversions disabled by default

Most of these target syntaxes are not deprecated in both RSpec 2 and 3, but the new syntaxes provide more modern and clear ways.

Type Target Syntax Converted Syntax
example_group describe 'something' { } RSpec.describe 'something' { }
hook_scope before(:all) { } before(:context) { }
stub_with_hash obj.stub(:message => value) allow(obj).to receive(:message).and_return(value)

Note: Specifying stub_with_hash enables conversion of obj.stub(:message => value) to allow(obj).to receive(:message).and_return(value) when allow(obj).to receive_messages(:message => value) is unavailable (prior to RSpec 3.0), and it will be converted to multiple statements if the hash includes multiple pairs. If your project's RSpec is 3.0 or later, it will be converted to receive_messages(:message => value) regardless of this option.

See Supported Conversions - Method stubs with a hash argument for more details.

-o/--convert-only

Convert specific syntaxes while keeping all other syntaxes.

This option would be useful when you want to convert a non-deprecated syntax while keeping another syntax that would be converted by default. (e.g. converting the hook scope aliases while keeping the one-liner should).

bash
$ transpec --convert-only example_group,hook_scope

-s/--skip-dynamic-analysis

Skip dynamic analysis and convert with only static analysis. The use of this option is basically discouraged since it significantly decreases the overall conversion accuracy.

This would be useful only if your spec suite takes really long (like an hour) to run and you prefer a combination of the rough but fast conversion by Transpec and manual fixes after that.

-n/--negative-form

Specify a negative form of to which is used in the expect syntax. Either not_to or to_not. not_to is used by default.

bash
$ transpec --negative-form to_not

-b/--boolean-matcher

Specify a boolean matcher type which be_true and be_false will be converted to. Any of truthy,falsey, truthy,falsy or true,false can be specified. truthy,falsey is used by default.

bash
$ transpec --boolean-matcher true,false

See Supported Conversions - Boolean matchers for more details.

-e/--explicit-spec-type

Add explicit spec :type metadata to example groups in a project using rspec-rails.

See Supported Conversions - Implicit spec types in rspec-rails for more details.

-a/--no-yield-any-instance

Suppress yielding receiver instances to any_instance implementation blocks as the first block argument.

By default in RSpec 3, any_instance implementation blocks will be yielded the receiving instance as the first block argument, and by default Transpec converts specs by adding instance arguments to the blocks so that they conform to the behavior of RSpec 3. Specifying this option suppresses the conversion and keeps them compatible with RSpec 2. Note that this is not same as --keep deprecated since this configures yield_receiver_to_any_instance_implementation_blocks with RSpec.configure.

See Supported Conversions - any_instance implementation blocks for more details.

-p/--no-parens-matcher-arg

Suppress parenthesizing arguments of matchers when converting should with operator matcher to expect with non-operator matcher (the expect syntax does not directly support the operator matchers). Note that it will be parenthesized even if this option is specified when parentheses are necessary to keep the meaning of the expression.

…

Inconvertible Specs

You might see the following warning while conversion:

Cannot convert #should into #expect since #expect is not available in the context.
spec/awesome_spec.rb:4:      1.should == 1

This message would be shown with specs like:

ruby
describe '#should that cannot be converted to #expect' do
  class MyAwesomeTestRunner
    def run
      1.should == 1
    end
  end

  it 'is 1' do
    test_runner = MyAwesomeTestRunner.new
    test_runner.run
  end
end

Reason

  • should is defined on BasicObject class, so you can use should everywhere.
  • expect is defined on RSpec::Matchers module which is included by RSpec::Core::ExampleGroup class, so you can use expect only where self is an instance of RSpec::Core::ExampleGroup (i.e. in it blocks, :each hook blocks or included module methods) or other classes that explicitly include RSpec::Matchers.

With the above example, in the context of 1.should == 1, the self is an instance of MyAwesomeTestRunner. Transpec tracks contexts and skips conversion if the syntax cannot be converted in a case like this.

Solution

Include or extend any of the following module to make RSpec syntax available in the context:

  • RSpec::Matchers for expect(obj).to some_matcher
  • RSpec::Mocks::ExampleMethods for expect/allow(obj).to receive(:message)
ruby
  class MyAwesomeTestRunner
    include RSpec::Matchers

    def run
      1.should == 1
    end
  end

Then run transpec again.

Two Types of should

There are two types of should:

ruby
describe 'the monkey-patched should' do
  subject { [] }

  it 'is empty' do
    subject.should be_empty
    #       ^^^^^^ BasicObject#should in RS

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

Rubyconverterrspecruby

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言