CLIntegracon

Gem Build Status Code Climate Inline docs Dependency Status

CLIntegracon allows you to build Integration specs for your CLI, independent if they are based on Ruby or another technology. It is especially useful if your command modifies the file system. Furthermore it provides an integration for Bacon.

Take a look in the documentation.

Installation

Add this line to your application's Gemfile:

gem 'clintegracon'

And then execute:

$ bundle

Or install it yourself as:

$ gem install clintegracon

Usage

This description assumes the following file system layout of your CLI project. This is not fixed, but if yours differ, you have to change paths accordingly.

─┬─/ (root)
 
 ├─┬─spec
  ├───spec_helper.rb
  └─┬─integration
    ├─┬─arg1
     ├─┬─before
      ├───source.h
      └───source.c
     └─┬─after
       ├───execution_output.txt
       ├───source.h
       ├───source.c
       └───source.o
    └─┬─arg2
      ├─┬─before
       
      └─┬─after
        
 └───tmp

Bacon

  1. Include CLIntegracon in your spec_helper.rb

    require 'CLIntegracon'
    
  2. Setup the basic configuration and hook into Bacon as test framework:

    CLIntegracon.configure do |c|
    c.spec_path = File.expand_path('../integration', __FILE__)
    c.temp_path = File.expand_path('../../tmp', __FILE__)
    
    # Ignore certain files ...
    c.ignores '.gitkeep'
    
    # ... or explicitly ignore all hidden files. (While the default is that they
    # are included in the file tree diff.)
    c.include_hidden_files = true
    
    c.hook_into :bacon
    end
    
  3. Describe your specs with the extended DSL:

    # Ensure that all the helpers are included in this context
    describe_cli 'coffee-maker' do
    
    # Setup our subject
    subject do |s|
      # Provide a display name (optional, default would be 'subject')
      s.name = 'coffee-maker'
    
      # Provide the real command line (required)
      s.executable = 'bundle exec ruby spec/fixtures/bin/coffeemaker.rb"'
    
      # Set environments variables needed on execution
      s.environment_vars = {
          'COFFEE_MAKER_FILE' => 'Coffeemakerfile.yml'
      }
    
      # Define default arguments
      s.default_args = [
          '--verbose',
          '--no-ansi'
      ]
    
      # Replace special paths in execution output by a placeholder, so that the
      # compared outputs doesn't differ dependent on the absolute location where
      # your tested CLI was executed.
      s.replace_path ROOT.to_s, 'ROOT'
    end
    
    describe 'Brew recipes' do
    
      describe 'without milk' do
        # +behaves_like+ is provided by bacon.
        # +cli_spec+ expects as first argument the directory of the spec, and
        # as second argument the arguments passed to the subject on launch.
        # The defined default arguments will be appended after that.
        # If you need to append arguments after the default arguments, because
        # of the way your command line interface is defined and how its option
        # parser works, you can pass them as third argument to +cli_spec+.
        behaves_like cli_spec('coffeemaker_no_milk', '--no-milk')
    
        # Implementation details:
        # +cli_spec+ will define on-the-fly a new shared set of expectations
        # and will return its name and pass it to +behaves_like+, so that it
        # will be immediately executed.
      end
    
      describe 'with honey as sweetner' do
        behaves_like cli_spec('coffeemaker_sweetner_honey', '--sweetner=honey')
      end
    
    end
    
    describe 'Get help' do
      behaves_like cli_spec('coffeemaker_help', '--help')
    end
    
    end
    
  4. Profit

    Bacon Example Terminal Output

Acknowledgement

This gem was inspired by the idea behind the integration tests of the CocoaPods's main project and was integrated there.
See the integration in CocoaPods for a real-world example with very extensive usage of all features.

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request