mrackwitz/CLIntegracon

View on GitHub
README.md

Summary

Maintainability
Test Coverage
# CLIntegracon

[![Gem](https://img.shields.io/gem/v/clintegracon.svg?style=flat)](http://rubygems.org/gems/clintegracon)
[![Build Status](https://img.shields.io/travis/mrackwitz/CLIntegracon/master.svg?style=flat)](https://travis-ci.org/mrackwitz/CLIntegracon)
[![Code Climate](https://img.shields.io/codeclimate/github/mrackwitz/CLIntegracon.svg?style=flat)](https://codeclimate.com/github/mrackwitz/CLIntegracon)
[![Inline docs](http://inch-ci.org/github/mrackwitz/CLIntegracon.svg?branch=master&style=flat)](http://inch-ci.org/github/mrackwitz/CLIntegracon)
[![Dependency Status](http://img.shields.io/gemnasium/mrackwitz/CLIntegracon.svg?style=flat)](https://gemnasium.com/mrackwitz/CLIntegracon)

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](http://www.rubydoc.info/github/mrackwitz/CLIntegracon/master/frames).


## 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*

  ```ruby
  require 'CLIntegracon'
  ```

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

  ```ruby
  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:

  ```ruby
  # 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](/../assets/term-output-bacon.png?raw=true)


## Acknowledgement

This gem was inspired by the idea behind the integration tests of the
[CocoaPods](cp-main)'s main project and was integrated there.  
See [the integration in CocoaPods][cp-integration] 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

[cp-main]: https://github.com/CocoaPods/CocoaPods
[cp-integration]: https://github.com/CocoaPods/CocoaPods/blob/master/spec/integration.rb