cucumber-the 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +9 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +100 -0
- data/Rakefile +2 -0
- data/cucumber-the.gemspec +21 -0
- data/features/cucumber_factory.feature +40 -0
- data/features/message_access.feature +23 -0
- data/features/readme.md +50 -0
- data/features/simple_usage.feature +122 -0
- data/features/smart_error_messages.feature +15 -0
- data/features/step_definitions/error_messages_steps.rb +15 -0
- data/features/step_definitions/feature_factory_steps.rb +36 -0
- data/features/support/feature_factory.rb +83 -0
- data/lib/cucumber-the.rb +13 -0
- data/lib/cucumber-the/registry.rb +44 -0
- data/lib/cucumber-the/version.rb +5 -0
- data/spec/cucumber-the_spec.rb +15 -0
- data/spec/registry_spec.rb +38 -0
- data/spec/spec_helper.rb +16 -0
- metadata +111 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Magnus Bergmark
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
# Cucumber::The
|
2
|
+
[![Build Status](https://secure.travis-ci.org/Mange/cucumber-the.png)](http://travis-ci.org/Mange/cucumber-the)
|
3
|
+
|
4
|
+
Adds quick access to instances to help you write more fluid steps.
|
5
|
+
|
6
|
+
```ruby
|
7
|
+
Given 'a published post' do
|
8
|
+
The[:post] = FactoryGirl.create :post, :published
|
9
|
+
end
|
10
|
+
|
11
|
+
Given 'I publish a post' do
|
12
|
+
The.post = FactoryGirl.create :post, :published, user: The(:logged_in_user)
|
13
|
+
end
|
14
|
+
|
15
|
+
When 'I go to the post' do
|
16
|
+
visit post_path The.post
|
17
|
+
end
|
18
|
+
|
19
|
+
Then 'I should see the post title' do
|
20
|
+
page.should have_content The[:post].title
|
21
|
+
end
|
22
|
+
```
|
23
|
+
|
24
|
+
Note that this gem does not generate anything for you, it's up to you to use this to write your own steps in your own style.
|
25
|
+
|
26
|
+
## Why?
|
27
|
+
|
28
|
+
It's an eyesore to see scenarios like this:
|
29
|
+
|
30
|
+
```gherkin
|
31
|
+
Scenario: Displaying post tags
|
32
|
+
Given a post titled "10 things you can do with a broken dishwasher"
|
33
|
+
And that the post "10 things you can do with a broken dishwasher" has the tags "topten" and "hackery"
|
34
|
+
When I go to the post "10 things you can do with a broken dishwasher"
|
35
|
+
Then I should see "topten" and "hackery"
|
36
|
+
```
|
37
|
+
|
38
|
+
It reads a lot better like this:
|
39
|
+
|
40
|
+
```gherkin
|
41
|
+
Scenario: Displaying post tags
|
42
|
+
Given a post titled "10 things you can do with a broken dishwasher"
|
43
|
+
And that the post has the tags "topten" and "hackery"
|
44
|
+
When I go to the post
|
45
|
+
Then I should see the tags
|
46
|
+
```
|
47
|
+
|
48
|
+
Note how we can say "the post" and "the tag" instead of referring to the raw data in them. Also note how the second scenario is easier to extend with additional logic, for example:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
Then 'I should see the tags' do
|
52
|
+
The.tags.each do |tag|
|
53
|
+
page.should have_css('.tag', text: tag.name)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
## Why not just variables?
|
59
|
+
|
60
|
+
You can implement this yourself by using instance variables, but it has one major drawback:
|
61
|
+
|
62
|
+
Every time you want to read the variable, you'll need to check that it is set and fail otherwise. If you don't you'll get `NoMethodError on NilClass` further down the stack, making for a very bad experience for the user.
|
63
|
+
|
64
|
+
At that point, you start wrapping these up inside a method and bam, you've implemented this gem. If you don't want the extra dependencies, skip this gem and implement it yourself. If you want to save some time, just use this gem instead of reinventing the wheel.
|
65
|
+
|
66
|
+
## Installation
|
67
|
+
|
68
|
+
Add this line to your application's Gemfile:
|
69
|
+
|
70
|
+
gem 'cucumber-the', require: false, group: :test
|
71
|
+
|
72
|
+
And then execute:
|
73
|
+
|
74
|
+
$ bundle
|
75
|
+
|
76
|
+
Then, `require 'cucumber-the'` inside `features/support/env.rb` (or a similar one that you control).
|
77
|
+
|
78
|
+
## Documentation
|
79
|
+
|
80
|
+
You can [read the documentation](https://www.relishapp.com/mange/cucumber-the/) using [Relish](https://www.relishapp.com).
|
81
|
+
|
82
|
+
## Contributing
|
83
|
+
|
84
|
+
1. Fork it
|
85
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
86
|
+
3. Write tests
|
87
|
+
4. Implement feature
|
88
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
89
|
+
6. Create new Pull Request
|
90
|
+
|
91
|
+
## Ruby versions
|
92
|
+
|
93
|
+
This gem supports the following versions of Ruby:
|
94
|
+
|
95
|
+
* Ruby 1.8.7
|
96
|
+
* Ruby 1.9.3
|
97
|
+
* JRuby (1.8 mode)
|
98
|
+
* JRuby (1.9 mode)
|
99
|
+
* Rubinius (1.8 mode)
|
100
|
+
* Rubinius (1.9 mode)
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Encoding: utf-8
|
2
|
+
require File.expand_path('../lib/cucumber-the/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Magnus Bergmark"]
|
6
|
+
gem.email = ["magnus.bergmark@gmail.com"]
|
7
|
+
gem.description = %q{Adds quick access to instances to help you write more fluid steps.}
|
8
|
+
gem.summary = %q{Adds quick access to instances to help you write more fluid steps.}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "cucumber-the"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Cucumber::The::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency 'cucumber', '~> 1.2'
|
19
|
+
|
20
|
+
gem.add_development_dependency 'rspec'
|
21
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
Feature: Cucumber factory
|
2
|
+
In order to test cucumber-the in an easy way
|
3
|
+
As a developer
|
4
|
+
I want to dynamically generate cucumber features and run them
|
5
|
+
|
6
|
+
Scenario: Creating passing feature
|
7
|
+
Given a feature "tautology.feature" with the following scenario:
|
8
|
+
"""
|
9
|
+
Scenario: 1 is 1
|
10
|
+
Then 1 should equal 1
|
11
|
+
"""
|
12
|
+
And step definitions:
|
13
|
+
"""
|
14
|
+
Then /^(\d+) should equal (\d+)$/ do |a, b|
|
15
|
+
fail unless a == b
|
16
|
+
end
|
17
|
+
"""
|
18
|
+
When I run the features
|
19
|
+
Then all scenarios should pass
|
20
|
+
|
21
|
+
Scenario: Creating failing feature
|
22
|
+
Given a feature "lies.feature" with the following scenario:
|
23
|
+
"""
|
24
|
+
Scenario: Big brother
|
25
|
+
Given slavery
|
26
|
+
Then that is freedom
|
27
|
+
"""
|
28
|
+
And step definitions:
|
29
|
+
"""
|
30
|
+
Given 'slavery' do
|
31
|
+
@slavery = true
|
32
|
+
end
|
33
|
+
|
34
|
+
Then 'that is freedom' do
|
35
|
+
fail if @slavery
|
36
|
+
end
|
37
|
+
"""
|
38
|
+
When I run the features
|
39
|
+
Then a scenario should fail
|
40
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Feature: Message access
|
2
|
+
Some people prefer `The.post` over `The[:post]` and we want to support this.
|
3
|
+
|
4
|
+
Scenario: Referrings to items using messages
|
5
|
+
Given a feature "calculator.feature" with the following scenario:
|
6
|
+
"""
|
7
|
+
Scenario: Addition
|
8
|
+
When I add 2 and 2
|
9
|
+
Then the sum should be 4
|
10
|
+
"""
|
11
|
+
And step definitions:
|
12
|
+
"""
|
13
|
+
When 'I add 2 and 2' do
|
14
|
+
The.sum = 2 + 2
|
15
|
+
end
|
16
|
+
|
17
|
+
Then 'the sum should be 4' do
|
18
|
+
fail if The.sum != 4
|
19
|
+
end
|
20
|
+
"""
|
21
|
+
And the gem is loaded
|
22
|
+
When I run the features
|
23
|
+
Then all scenarios should pass
|
data/features/readme.md
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# Cucumber::The
|
2
|
+
|
3
|
+
`Cucumber::The` adds quick access to instances to help you write more fluid steps.
|
4
|
+
|
5
|
+
## Why?
|
6
|
+
|
7
|
+
It's an eyesore to see scenarios like this:
|
8
|
+
|
9
|
+
```gherkin
|
10
|
+
Scenario: Displaying post tags
|
11
|
+
Given a post titled "10 things you can do with a broken dishwasher"
|
12
|
+
And that the post "10 things you can do with a broken dishwasher" has the tags "topten" and "hackery"
|
13
|
+
When I go to the post "10 things you can do with a broken dishwasher"
|
14
|
+
Then I should see "topten" and "hackery"
|
15
|
+
```
|
16
|
+
|
17
|
+
It reads a lot better like this:
|
18
|
+
|
19
|
+
```gherkin
|
20
|
+
Scenario: Displaying post tags
|
21
|
+
Given a post titled "10 things you can do with a broken dishwasher"
|
22
|
+
And that the post has the tags "topten" and "hackery"
|
23
|
+
When I go to the post
|
24
|
+
Then I should see the tags
|
25
|
+
```
|
26
|
+
|
27
|
+
Note how we can say "the post" and "the tag" instead of referring to the raw data in them. Also note how the second scenario is easier to extend with additional logic, for example:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
Then 'I should see the tags' do
|
31
|
+
The.tags.each do |tag|
|
32
|
+
page.should have_css('.tag', text: tag.name)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
```
|
36
|
+
|
37
|
+
## How?
|
38
|
+
|
39
|
+
Take a peek at the features to see how to use this project.
|
40
|
+
|
41
|
+
## Ruby versions
|
42
|
+
|
43
|
+
This gem supports the following versions of Ruby:
|
44
|
+
|
45
|
+
* Ruby 1.8.7
|
46
|
+
* Ruby 1.9.3
|
47
|
+
* JRuby (1.8 mode)
|
48
|
+
* JRuby (1.9 mode)
|
49
|
+
* Rubinius (1.8 mode)
|
50
|
+
* Rubinius (1.9 mode)
|
@@ -0,0 +1,122 @@
|
|
1
|
+
Feature: Simple usage
|
2
|
+
In the most simple case, just use `The` as a getter and setter inside the tests.
|
3
|
+
|
4
|
+
Scenario: Referring to previously set value
|
5
|
+
Given a feature "calculator.feature" with the following scenario:
|
6
|
+
"""
|
7
|
+
Scenario: Addition
|
8
|
+
When I add 2 and 2
|
9
|
+
Then the sum should be 4
|
10
|
+
"""
|
11
|
+
And step definitions:
|
12
|
+
"""
|
13
|
+
When 'I add 2 and 2' do
|
14
|
+
The[:sum] = 2 + 2
|
15
|
+
end
|
16
|
+
|
17
|
+
Then 'the sum should be 4' do
|
18
|
+
fail if The[:sum] != 4
|
19
|
+
end
|
20
|
+
"""
|
21
|
+
And the gem is loaded
|
22
|
+
When I run the features
|
23
|
+
Then all scenarios should pass
|
24
|
+
|
25
|
+
Scenario: Failing on missing values
|
26
|
+
Given a feature "dog.feature" with the following scenario:
|
27
|
+
"""
|
28
|
+
Scenario: Humping
|
29
|
+
When I hump the leg
|
30
|
+
Then I should be happy
|
31
|
+
"""
|
32
|
+
And step definitions:
|
33
|
+
"""
|
34
|
+
class Dog
|
35
|
+
def happy?
|
36
|
+
@humped
|
37
|
+
end
|
38
|
+
|
39
|
+
def hump(item)
|
40
|
+
@humped = true
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
When 'I hump the leg' do
|
45
|
+
@dog = Dog.new
|
46
|
+
@dog.hump The[:leg]
|
47
|
+
end
|
48
|
+
|
49
|
+
Then 'I should be happy' do
|
50
|
+
@dog.happy?
|
51
|
+
end
|
52
|
+
"""
|
53
|
+
And the gem is loaded
|
54
|
+
When I run the features
|
55
|
+
Then a scenario should fail with:
|
56
|
+
"""
|
57
|
+
Don't know what "the leg" is. Did you forget to assign it and/or run a prerequisite step before this step?
|
58
|
+
"""
|
59
|
+
|
60
|
+
Scenario: No pollution between scenarios
|
61
|
+
Given a feature "cat.feature" with the following scenarios:
|
62
|
+
"""
|
63
|
+
Background:
|
64
|
+
Given I am a cat
|
65
|
+
|
66
|
+
Scenario: Sleeping
|
67
|
+
When I sleep on a blanket
|
68
|
+
Then I should be as warm as the blanket
|
69
|
+
|
70
|
+
Scenario:
|
71
|
+
When I pee on the blanket
|
72
|
+
Then I should be smug about it
|
73
|
+
"""
|
74
|
+
And step definitions:
|
75
|
+
"""
|
76
|
+
class Cat
|
77
|
+
def sleep_on(item)
|
78
|
+
@sleeping_on = item
|
79
|
+
end
|
80
|
+
|
81
|
+
def temperature
|
82
|
+
@sleeping_on.temperature
|
83
|
+
end
|
84
|
+
|
85
|
+
def pee_on(item)
|
86
|
+
item.ruin
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class Blanket
|
91
|
+
def temperature() 22 end # Celcius, because standards are nice
|
92
|
+
def ruin() @ruined = true end
|
93
|
+
def ruined?() @ruined end
|
94
|
+
end
|
95
|
+
|
96
|
+
Given 'I am a cat' do
|
97
|
+
@cat = Cat.new
|
98
|
+
end
|
99
|
+
|
100
|
+
When 'I sleep on a blanket' do
|
101
|
+
The[:blanket] = Blanket.new
|
102
|
+
@cat.sleep_on The[:blanket]
|
103
|
+
end
|
104
|
+
|
105
|
+
When 'I pee on the blanket' do
|
106
|
+
@cat.pee_on The[:blanket]
|
107
|
+
end
|
108
|
+
|
109
|
+
Then 'I should be smug about it' do
|
110
|
+
@cat.instance_of?(Cat) # Cats are always smug
|
111
|
+
end
|
112
|
+
|
113
|
+
Then 'I should be as warm as the blanket' do
|
114
|
+
@cat.temperature.should == The[:blanket].temperature
|
115
|
+
end
|
116
|
+
"""
|
117
|
+
And the gem is loaded
|
118
|
+
When I run the features
|
119
|
+
Then a scenario should fail with:
|
120
|
+
"""
|
121
|
+
Don't know what "the blanket" is.
|
122
|
+
"""
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Feature: Smart error messages
|
2
|
+
Error messages should be clear and easy to understand.
|
3
|
+
|
4
|
+
Background:
|
5
|
+
Given there is a The registry
|
6
|
+
|
7
|
+
Scenario Outline: A simple name
|
8
|
+
Given I try to access <Key> from the registry
|
9
|
+
Then I should get an error containing "<Text>"
|
10
|
+
|
11
|
+
Examples:
|
12
|
+
| Key | Text |
|
13
|
+
| :bar | the bar |
|
14
|
+
| :smart_creationist | the smart creationist |
|
15
|
+
| :10_goons | the 10 goons |
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'cucumber-the/registry'
|
2
|
+
|
3
|
+
Given 'there is a The registry' do
|
4
|
+
@the_registry = Cucumber::The::Registry.new
|
5
|
+
end
|
6
|
+
|
7
|
+
Given /^I try to access :(\w+) from the registry$/ do |key|
|
8
|
+
@the_key = key.to_sym
|
9
|
+
end
|
10
|
+
|
11
|
+
Then 'I should get an error containing "$message"' do |message|
|
12
|
+
expect {
|
13
|
+
@the_registry[@the_key]
|
14
|
+
}.to raise_error { |error| error.message.should include message }
|
15
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
Given /^a feature "([^"]+)" with the following scenarios?:$/ do |name, scenario_body|
|
2
|
+
@cucumber_factory.create_feature name, scenario_body
|
3
|
+
end
|
4
|
+
|
5
|
+
Given 'step definitions:' do |body|
|
6
|
+
@cucumber_factory.create_step_definitions 'all.rb', body
|
7
|
+
end
|
8
|
+
|
9
|
+
Given 'the gem is loaded' do
|
10
|
+
gempath = File.expand_path '../../../lib', __FILE__
|
11
|
+
@cucumber_factory.create_support 'env.rb', <<-RUBY
|
12
|
+
$LOAD_PATH << #{gempath.inspect}
|
13
|
+
require "cucumber-the"
|
14
|
+
RUBY
|
15
|
+
end
|
16
|
+
|
17
|
+
When 'I run the features' do
|
18
|
+
@cucumber_factory.run
|
19
|
+
end
|
20
|
+
|
21
|
+
Then 'all scenarios should pass' do
|
22
|
+
unless @cucumber_factory.status.success?
|
23
|
+
fail "Some scenario did not pass. Output:\n#{@cucumber_factory.output}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
Then 'a scenario should fail' do
|
28
|
+
if @cucumber_factory.status.success?
|
29
|
+
fail "Scenarios passed, but shouldn't have. Output:\n#{@cucumber_factory.output}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
Then 'a scenario should fail with:' do |text|
|
34
|
+
fail "Scenarios passed" if @cucumber_factory.status.success?
|
35
|
+
@cucumber_factory.output.should include text
|
36
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'timeout'
|
4
|
+
|
5
|
+
class CucumberFactory
|
6
|
+
def self.use
|
7
|
+
# Travis CI + JRuby have trouble with Dir.mktmpdir. After the resource
|
8
|
+
# block is done Dir tries to remove the tmp directory, but that fails in
|
9
|
+
# that configuration. We ignore these errors, but only after safeguarding
|
10
|
+
# that we're not ignoring errors that was actually caused by our own code.
|
11
|
+
error_in_test = false
|
12
|
+
|
13
|
+
Dir.mktmpdir do |dir|
|
14
|
+
@instance = new dir
|
15
|
+
begin
|
16
|
+
yield
|
17
|
+
rescue Errno::EACCES
|
18
|
+
error_in_test = true
|
19
|
+
raise
|
20
|
+
end
|
21
|
+
end
|
22
|
+
rescue Errno::EACCES => error
|
23
|
+
raise if error_in_test
|
24
|
+
warn "Could not remove temporary directory. Error: #{error}"
|
25
|
+
ensure
|
26
|
+
@instance = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.instance() @instance end
|
30
|
+
|
31
|
+
attr_reader :status, :output
|
32
|
+
|
33
|
+
def initialize(root)
|
34
|
+
@root = Pathname(root)
|
35
|
+
@status = nil
|
36
|
+
@output = "(Have not been run yet)"
|
37
|
+
ensure_structure
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_feature(name, body)
|
41
|
+
@root.join(name).open('w') do |file|
|
42
|
+
file << "Feature: #{clean_name name}\n\n"
|
43
|
+
file << body
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def create_step_definitions(name, body)
|
48
|
+
create_file @root.join('step_definitions', name), body
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_support(name, body)
|
52
|
+
create_file @root.join('support', name), body
|
53
|
+
end
|
54
|
+
|
55
|
+
def run
|
56
|
+
IO.popen("#{$0} #{@root.to_s}") do |output|
|
57
|
+
@output = output.read
|
58
|
+
end
|
59
|
+
@status = $?
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
def clean_name(name)
|
64
|
+
name.gsub(/\.feature$/, '').gsub('_', ' ')
|
65
|
+
end
|
66
|
+
|
67
|
+
def ensure_structure
|
68
|
+
@root.join('support').mkpath
|
69
|
+
@root.join('step_definitions').mkpath
|
70
|
+
end
|
71
|
+
|
72
|
+
def create_file(path, body)
|
73
|
+
path.open('w') { |file| file << body }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
Around do |scenario, block|
|
78
|
+
CucumberFactory.use(&block)
|
79
|
+
end
|
80
|
+
|
81
|
+
Before do
|
82
|
+
@cucumber_factory = CucumberFactory.instance
|
83
|
+
end
|
data/lib/cucumber-the.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
module Cucumber
|
2
|
+
module The
|
3
|
+
class Registry
|
4
|
+
def []=(name, value)
|
5
|
+
thread_registry[name] = value
|
6
|
+
end
|
7
|
+
|
8
|
+
def [](name)
|
9
|
+
thread_registry[name] || raise_error(name)
|
10
|
+
end
|
11
|
+
|
12
|
+
def clear
|
13
|
+
thread_registry.clear
|
14
|
+
end
|
15
|
+
|
16
|
+
def method_missing(name, *args)
|
17
|
+
key_name = name.to_s
|
18
|
+
if key_name.chomp! '='
|
19
|
+
self[key_name.to_sym] = args.first
|
20
|
+
else
|
21
|
+
self[name]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def responds_to(name, *)
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def thread_registry
|
31
|
+
Thread.current[:the_registry] ||= {}
|
32
|
+
end
|
33
|
+
|
34
|
+
def raise_error(name, trace = caller(2))
|
35
|
+
raise RuntimeError, error_message(name), trace
|
36
|
+
end
|
37
|
+
|
38
|
+
def error_message(name)
|
39
|
+
formatted_name = name.to_s.gsub('_', ' ')
|
40
|
+
%(Don't know what "the #{formatted_name}" is. Did you forget to assign it and/or run a prerequisite step before this step?)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Cucumber::The do
|
5
|
+
it "adds a The constant with a Registry" do
|
6
|
+
The.should be_instance_of(Cucumber::The::Registry)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "adds a Before block that clears the registry on every step" do
|
10
|
+
The.should_receive(:clear)
|
11
|
+
|
12
|
+
before_blocks.should have_at_least(1).block
|
13
|
+
before_blocks.each(&:call)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
module Cucumber
|
5
|
+
module The
|
6
|
+
describe Registry do
|
7
|
+
subject(:registry) { Registry.new }
|
8
|
+
|
9
|
+
it "can set and access values using hash notation" do
|
10
|
+
registry[:foo] = "bar"
|
11
|
+
registry[:foo].should == "bar"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "can set and access values using messages" do
|
15
|
+
registry.foo = "bar"
|
16
|
+
registry.foo.should == "bar"
|
17
|
+
end
|
18
|
+
|
19
|
+
it "raises an error when accessing unset values using hash notation" do
|
20
|
+
expect {
|
21
|
+
registry[:elephant]
|
22
|
+
}.to raise_error /the elephant/
|
23
|
+
end
|
24
|
+
|
25
|
+
it "raises an error when accessing unset values using hash notation" do
|
26
|
+
expect {
|
27
|
+
registry.elephant
|
28
|
+
}.to raise_error /the elephant/
|
29
|
+
end
|
30
|
+
|
31
|
+
it "can be cleared" do
|
32
|
+
registry[:foo] = "bar"
|
33
|
+
registry.clear
|
34
|
+
expect { registry[:foo] }.to raise_error
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
RSpec.configure do |config|
|
2
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
3
|
+
config.run_all_when_everything_filtered = true
|
4
|
+
config.filter_run :focus
|
5
|
+
config.order = 'random'
|
6
|
+
end
|
7
|
+
|
8
|
+
def before_blocks
|
9
|
+
Thread.current[:before_blocks] ||= []
|
10
|
+
end
|
11
|
+
|
12
|
+
def Before(&block)
|
13
|
+
before_blocks << block
|
14
|
+
end
|
15
|
+
|
16
|
+
require 'cucumber-the'
|
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cucumber-the
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Magnus Bergmark
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-10-26 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: cucumber
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.2'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.2'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: Adds quick access to instances to help you write more fluid steps.
|
47
|
+
email:
|
48
|
+
- magnus.bergmark@gmail.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- .gitignore
|
54
|
+
- .rspec
|
55
|
+
- .travis.yml
|
56
|
+
- Gemfile
|
57
|
+
- LICENSE
|
58
|
+
- README.md
|
59
|
+
- Rakefile
|
60
|
+
- cucumber-the.gemspec
|
61
|
+
- features/cucumber_factory.feature
|
62
|
+
- features/message_access.feature
|
63
|
+
- features/readme.md
|
64
|
+
- features/simple_usage.feature
|
65
|
+
- features/smart_error_messages.feature
|
66
|
+
- features/step_definitions/error_messages_steps.rb
|
67
|
+
- features/step_definitions/feature_factory_steps.rb
|
68
|
+
- features/support/feature_factory.rb
|
69
|
+
- lib/cucumber-the.rb
|
70
|
+
- lib/cucumber-the/registry.rb
|
71
|
+
- lib/cucumber-the/version.rb
|
72
|
+
- spec/cucumber-the_spec.rb
|
73
|
+
- spec/registry_spec.rb
|
74
|
+
- spec/spec_helper.rb
|
75
|
+
homepage: ''
|
76
|
+
licenses: []
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options: []
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ! '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
requirements: []
|
94
|
+
rubyforge_project:
|
95
|
+
rubygems_version: 1.8.24
|
96
|
+
signing_key:
|
97
|
+
specification_version: 3
|
98
|
+
summary: Adds quick access to instances to help you write more fluid steps.
|
99
|
+
test_files:
|
100
|
+
- features/cucumber_factory.feature
|
101
|
+
- features/message_access.feature
|
102
|
+
- features/readme.md
|
103
|
+
- features/simple_usage.feature
|
104
|
+
- features/smart_error_messages.feature
|
105
|
+
- features/step_definitions/error_messages_steps.rb
|
106
|
+
- features/step_definitions/feature_factory_steps.rb
|
107
|
+
- features/support/feature_factory.rb
|
108
|
+
- spec/cucumber-the_spec.rb
|
109
|
+
- spec/registry_spec.rb
|
110
|
+
- spec/spec_helper.rb
|
111
|
+
has_rdoc:
|