<commit_before># Given/When/Then for RSpec and Minitest

| Master |
| :----: |
| [![Master Build Status](https://secure.travis-ci.org/jimweirich/rspec-given.png?branch=master)](https://travis-ci.org/jimweirich/rspec-given) |

Covering rspec-given, minitest-given, and given-core, version 3.0.0.beta.1.

rspec-given and minitest-given are extensions to your favorite testing
framework to allow Given/When/Then notation when writing specs.

# Why Given/When/Then

RSpec has done a great job of making specifications more readable for
humans. However, I really like the given/when/then nature of Cucumber
stories and would like to follow the same structure in my unit tests.
rspec-given (and now minitest-given) allows a simple given/when/then
structure RSpec specifications.

## Status

* rspec-given is ready for production use.
* minitest-given is experimental.

### RSpec/Given

The rspec-given gem is the original given/when/then extension for
RSpec. It now depends on a given_core gem for the basic functionality
and then adds the RSpec specific code.

* rspec-given now requires RSpec version 2.12 or better.

### Minitest/Given

A new minitest-given gem allows Given/When/Then notation directly in
Minitest::Spec specifications.

To use minitest-given, just place the following require at the top of
the file (or in a convenient spec_helper).

```ruby
require 'minitest/given'
```

All the features of rspec-given are available in minitest-given.

When switching from RSpec/Given to Minitest/Given, here are some
things to watch out for:

* You need to use Minitest version 4.3 or better (yes, Minitest 5.x
  should work as well).

* Minitest/Given adds the missing "context" block to Minitest::Spec.

* Only one before block is allowed in any given Minitest::Spec
  describe block. This doesn't effect the number of Givens you are
  allowed to use, but it may surprise if you are use to RSpec.

### Auto Selecting

If you use natural assertions exclusively in your specs, it's quite
possible to write specs that run under both RSpec and Minitest::Spec.

Use this at the start of your spec file:

```ruby
if defined?(RSpec)
  require 'rspec/given'
else
  require 'minitest/autorun'
  require 'minitest/given'
end
```

See
[stack_spec.rb](https://github.com/jimweirich/rspec-given/blob/minispec/examples/stack/stack_spec.rb)
and
[example_helper.rb](https://github.com/jimweirich/rspec-given/blob/minispec/examples/example_helper.rb)

## Example

Here is a specification written in the rspec-given framework:

```ruby
require 'rspec/given'
require 'spec_helper'
require 'stack'

describe Stack do
  def stack_with(initial_contents)
    stack = Stack.new
    initial_contents.each do |item| stack.push(item) end
    stack
  end

  Given(:stack) { stack_with(initial_contents) }
  Invariant { stack.empty?.should == (stack.depth == 0) }

  context "with no items" do
    Given(:initial_contents) { [] }
    Then { stack.depth.should == 0 }

    context "when pushing" do
      When { stack.push(:an_item) }

      Then { stack.depth.should == 1 }
      Then { stack.top.should == :an_item }
    end

    context "when popping" do
      When(:result) { stack.pop }
      Then { result.should have_failed(Stack::UnderflowError, /empty/) }
    end
  end

  context "with one item" do
    Given(:initial_contents) { [:an_item] }

    context "when popping" do
      When(:pop_result) { stack.pop }

      Then { pop_result.should == :an_item }
      Then { stack.depth.should == 0 }
    end
  end

  context "with several items" do
    Given(:initial_contents) { [:second_item, :top_item] }
    Given!(:original_depth) { stack.depth }

    context "when pushing" do
      When { stack.push(:new_item) }

      Then { stack.top.should == :new_item }
      Then { stack.depth.should == original_depth + 1 }
    end

    context "when popping" do
      When(:pop_result) { stack.pop }

      Then { pop_result.should == :top_item }
      Then { stack.top.should == :second_item }
      Then { stack.depth.should == original_depth - 1 }
    end
  end
end
```

Let's talk about the individual statements used in the Given
framework.

### Given
<commit_msg>Stack example switched to Natural Assertions.<commit_after># Given/When/Then for RSpec and Minitest

| Master |
| :----: |
| [![Master Build Status](https://secure.travis-ci.org/jimweirich/rspec-given.png?branch=master)](https://travis-ci.org/jimweirich/rspec-given) |

Covering rspec-given, minitest-given, and given-core, version 3.0.0.beta.1.

rspec-given and minitest-given are extensions to your favorite testing
framework to allow Given/When/Then notation when writing specs.

# Why Given/When/Then

RSpec has done a great job of making specifications more readable for
humans. However, I really like the given/when/then nature of Cucumber
stories and would like to follow the same structure in my unit tests.
rspec-given (and now minitest-given) allows a simple given/when/then
structure RSpec specifications.

## Status

* rspec-given is ready for production use.
* minitest-given is experimental.

### RSpec/Given

The rspec-given gem is the original given/when/then extension for
RSpec. It now depends on a given_core gem for the basic functionality
and then adds the RSpec specific code.

* rspec-given now requires RSpec version 2.12 or better.

### Minitest/Given

A new minitest-given gem allows Given/When/Then notation directly in
Minitest::Spec specifications.

To use minitest-given, just place the following require at the top of
the file (or in a convenient spec_helper).

```ruby
require 'minitest/given'
```

All the features of rspec-given are available in minitest-given.

When switching from RSpec/Given to Minitest/Given, here are some
things to watch out for:

* You need to use Minitest version 4.3 or better (yes, Minitest 5.x
  should work as well).

* Minitest/Given adds the missing "context" block to Minitest::Spec.

* Only one before block is allowed in any given Minitest::Spec
  describe block. This doesn't effect the number of Givens you are
  allowed to use, but it may surprise if you are use to RSpec.

### Auto Selecting

If you use natural assertions exclusively in your specs, it's quite
possible to write specs that run under both RSpec and Minitest::Spec.

Use this at the start of your spec file:

```ruby
if defined?(RSpec)
  require 'rspec/given'
else
  require 'minitest/autorun'
  require 'minitest/given'
end
```

See
[stack_spec.rb](https://github.com/jimweirich/rspec-given/blob/minispec/examples/stack/stack_spec.rb)
and
[example_helper.rb](https://github.com/jimweirich/rspec-given/blob/minispec/examples/example_helper.rb)

## Example

Here is a specification written in the rspec-given framework:

```ruby
require 'rspec/given'
require 'spec_helper'
require 'stack'

Given.use_natural_assertions

describe Stack do
  def stack_with(initial_contents)
    stack = Stack.new
    initial_contents.each do |item| stack.push(item) end
    stack
  end

  Given(:stack) { stack_with(initial_contents) }
  Invariant { stack.empty? == (stack.depth == 0) }

  context "with no items" do
    Given(:initial_contents) { [] }
    Then { stack.depth == 0 }

    context "when pushing" do
      When { stack.push(:an_item) }

      Then { stack.depth == 1 }
      Then { stack.top == :an_item }
    end

    context "when popping" do
      When(:result) { stack.pop }
      Then { result == Failure(Stack::UnderflowError, /empty/) }
    end
  end

  context "with one item" do
    Given(:initial_contents) { [:an_item] }

    context "when popping" do
      When(:pop_result) { stack.pop }

      Then { pop_result == :an_item }
      Then { stack.depth == 0 }
    end
  end

  context "with several items" do
    Given(:initial_contents) { [:second_item, :top_item] }
    Given!(:original_depth) { stack.depth }

    context "when pushing" do
      When { stack.push(:new_item) }

      Then { stack.top == :new_item }
      Then { stack.depth == original_depth + 1 }
    end

    context "when popping" do
      When(:pop_result) { stack.pop }

      Then { pop_result == :top_item }
      Then { stack.top == :second_item }
      Then { stack.depth == original_depth - 1 }
    end
  end
end
```

Let's talk about the individual statements used in the Given
framework.

### Given

{'fraction_non_alphanumeric': 0.09984286232322011, 'fraction_numerical': 0.0038680043515048955, 'mean_word_length': 3.5788599889319315, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 8, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5334785', 'n_tokens_mistral': 2723, 'n_tokens_neox': 2564, 'n_words': 884}