cukesalad 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  source :rubygems
2
2
  gem "cucumber", "0.10.0"
3
- gem "cukesalad", ">=0.3.0"
3
+ gem "cukesalad", "0.6"
4
4
  gem "rspec", "2.5.0", :require => 'spec'
5
5
  gem "capybara", "0.4.1.2"
6
6
  gem "sinatra", "1.2.0"
@@ -24,7 +24,7 @@ GEM
24
24
  gherkin (~> 2.3.2)
25
25
  json (~> 1.4.6)
26
26
  term-ansicolor (~> 1.0.5)
27
- cukesalad (0.3.0)
27
+ cukesalad (0.6.0)
28
28
  aruba (= 0.3.5)
29
29
  cucumber (= 0.10.0)
30
30
  rspec (= 2.5.0)
@@ -70,6 +70,6 @@ PLATFORMS
70
70
  DEPENDENCIES
71
71
  capybara (= 0.4.1.2)
72
72
  cucumber (= 0.10.0)
73
- cukesalad (>= 0.3.0)
73
+ cukesalad (= 0.6)
74
74
  rspec (= 2.5.0)
75
75
  sinatra (= 1.2.0)
@@ -6,7 +6,7 @@ Feature: Addition
6
6
  Scenario Outline: Find the sum of two numbers
7
7
  Given I am a Calculating Individual
8
8
  And I was able to switch on the calculator
9
- When I attempt to add: the number '<first_number>' to the number '<second_number>'
9
+ When I attempt to add: the number '<first_number>' and the number '<second_number>'
10
10
  Then I should see the answer '<result>'
11
11
 
12
12
 
@@ -6,7 +6,7 @@ Feature: Complex Calculations
6
6
  Scenario Outline: Get the result of a more complex calculation
7
7
  Given I am a calculating individual
8
8
  And I was able to switch on the calculator
9
- When I attempt to calculate: with the following '<calculation>'
9
+ When I attempt to calculate, with the following '<calculation>'
10
10
  Then I should see the answer '<correct_result>'
11
11
 
12
12
  Examples:
@@ -1,11 +1,4 @@
1
- # This demonstrates how to use an attribute mapping
2
- # to make the interactions within the task read more naturally
3
- # In the scenario it might say "add: the number '5', to the number '10'
4
- # The form illustrated below simply maps the elements the_number and to_the_number
5
- # to alternative symbols that make the interactions read more like real instructions
6
- # See subtract.rb for a way of writing tasks that reuses the common interactions
7
- # required to perform calculations.
8
- in_order_to 'add', the_number: :first_number, to_the_number: :second_number do
1
+ in_order_to 'add', the_number: :first_number, and_the_number: :second_number do
9
2
  enter the :first_number
10
3
  press :plus
11
4
  enter the :second_number
@@ -2,7 +2,7 @@ in_order_to "switch on the calculator" do
2
2
  require 'rspec/expectations'
3
3
  extend RSpec::Matchers
4
4
 
5
- @calc = switch_on_the_calculator
5
+ switch_on_the_calculator
6
6
  self.should respond_to :enter
7
7
  self.should respond_to :press
8
8
  self.should respond_to :look_at_the_display
@@ -6,7 +6,7 @@ Feature: Subtraction
6
6
  Scenario Outline: Find the result of subtracting two numbers
7
7
  Given I am a Calculating Individual
8
8
  And I was able to switch on the calculator
9
- When I attempt to subtract: the number '<subtractor>' from the number '<subtractee>'
9
+ When I attempt to subtract, the number '<subtractor>' from the number '<subtractee>'
10
10
  Then I should see the answer '<result>'
11
11
 
12
12
 
data/README.md CHANGED
@@ -75,7 +75,7 @@ Create a new file, `features/lib/tasks/switch_on_the_calculator.rb`
75
75
  Remember the step `When I attempt to switch on the calculator`
76
76
 
77
77
  in_order_to "switch on the calculator" do
78
- @calc = switch_on_the_calculator
78
+ switch_on_the_calculator
79
79
  end
80
80
 
81
81
  Remember the step `Then I should see the answer '0'`
@@ -110,7 +110,7 @@ You'll need a class called Calculator on the load path of course, but that's it.
110
110
 
111
111
  From your project folder, run (_note: '%' is our command prompt_)
112
112
 
113
- % cucumber
113
+ % cucumber
114
114
 
115
115
  We now have our first passing Feature, without creating a single step definition!
116
116
 
@@ -121,30 +121,34 @@ Let's try another scenario...
121
121
  Scenario Outline: Find the sum of two numbers
122
122
  Given I am a Calculating Individual
123
123
  And I was able to switch on the calculator
124
- When I attempt to add: the number '10' to the number '10'
124
+ When I attempt to add: the number '10' and the number '10'
125
125
  Then I should see the answer '20'
126
126
 
127
127
  Notice that we've reused 'switch on the calculator'.
128
128
 
129
129
  The new _When_ step has a slightly different layout.
130
- Let's examine that for a second... Notice the ':' (colon) after <do something> and the name-value pairs:
130
+ Let's examine that for a second... See below. Notice the ':' (colon) after `<do something>` followed by the name-value pairs:
131
131
 
132
132
  When I attempt to <do something>: <name> '<value>' <name> '<value>'
133
133
 
134
- You can have as many name-value pairs as you like.
134
+ You can also use a ',' (comma) in situations where a colon wouldn't quite work:
135
+
136
+ When I attempt to <do something>, <name> '<value>' <name> '<value>'
135
137
 
136
- So, we need a task called `tasks/add.rb` that explains the individual actions required to complete the task:
138
+ `<do something>` can be as many words as you like. You can have as many name-value pairs as you like.
139
+
140
+ For this to work we need a task called `tasks/add.rb` that explains the individual actions required to complete the task:
137
141
 
138
142
  in_order_to "add" do
139
143
  enter @value_of(:the_number)
140
144
  press :plus
141
- enter @value_of(:to_the_number)
145
+ enter @value_of(:and_the_number)
142
146
  press :equals
143
147
  end
144
148
 
145
149
  Notice how the `value_of` lines use symbols that correspond to the wording `'the number '10' to the number '10'` in the "When" step.
146
150
 
147
- There is some 'syntactic sugar' that we can use to dress this up a little and make it read nicer... a simple attribute mapping:
151
+ There is some 'syntactic sugar' that we can use to dress this up a little and make it read nicer... a simple attribute mapping (using Ruby 1.9.x syntax):
148
152
 
149
153
  in_order_to "add", the_number: :first_number, to_the_number: :second_number do
150
154
  enter the :first_number
@@ -153,9 +157,9 @@ There is some 'syntactic sugar' that we can use to dress this up a little and ma
153
157
  press :equals
154
158
  end
155
159
 
156
- All we've done is mapped "the_number" to "first_number". There is a special method called "the" that allows you to reference the mapped values rather than the symbols derived from the scenario.
160
+ All we've done is mapped `:the_number` to `:first_number` and `:to_the_number` to `:second_number`. There is a special method called "the" that allows you to reference the mapped values rather than the symbols derived from the scenario.
157
161
 
158
- Now all we need to do is modify our `calculating_individual.rb` to receive those calls...
162
+ Now all we need to do is create the corresponding methods in `calculating_individual.rb`.
159
163
 
160
164
  module CalculatingIndividual
161
165
 
@@ -188,6 +192,8 @@ Now all we need to do is modify our `calculating_individual.rb` to receive those
188
192
  end
189
193
  end
190
194
 
195
+ Of course you'll have to [implement the calculator too](https://github.com/RiverGlide/CukeSalad/blob/master/Examples/Calculator/lib/calculator.rb)
196
+
191
197
  Now, you can run cucumber again:
192
198
 
193
199
  % cucumber
@@ -196,14 +202,74 @@ There's no need to write `step_definitions`...
196
202
  Simply express the _roles_ and the _tasks_ in clear,
197
203
  concise, easy to read classes.
198
204
 
199
- After adding some more scenarios and tasks and an alternative "Calculating Individual" (see below for why), our finished Calculator directory structure looks like this...
205
+ If we want to know what things we can say, instead of trawling through a step-def ruby file, we can look in our tasks folder:
206
+
207
+ features/lib/default/tasks/
208
+ ├── add.rb
209
+ ├── calculate.rb
210
+ ├── calculations.rb
211
+ ├── see_the_answer.rb
212
+ ├── subtract.rb
213
+ └── switch_on_the_calculator.rb
214
+
215
+ You can structure your tasks as you see fit. For example, as the project grows, it might end up looking like this:
216
+
217
+ features/lib/default/tasks/
218
+ ├── all_purpose
219
+ | └── calculate.rb
220
+ ├── arithmetic
221
+ | ├── add.rb
222
+ | ├── divide.rb
223
+ | ├── multiply.rb
224
+ | └── subtract.rb
225
+ ├── extras
226
+ | ├── recall_from_memory.rb
227
+ | ├── store_in_memory.rb
228
+ | └── switch_on_the_calculator.rb
229
+ ├── questions
230
+ | ├── see_the_answer.rb
231
+ | ├── see_the_following_indicators.rb
232
+ | └── switch_on_the_calculator.rb
233
+ ├── trigonometry
234
+ | ├── sine.rb
235
+ | ├── cosine.rb
236
+ | └── tangent.rb
237
+ └── reference_material
238
+ └── calculations.rb
239
+
240
+ ## Alternative Roles
241
+
242
+ As our features _describe the value of a calculator application and not its
243
+ implementation_, we have the opportunity to reuse them.
244
+
245
+ In the Calculator example, we create a new _role_ in
246
+ `./features/lib/alternative/roles/calculating_web_user.rb`, which we can swap
247
+ into our tests using a Cucumber profile defined in `features/cucumber.yml`:
248
+
249
+ default --exclude features/lib/alternative/
250
+ alternative -r features/lib/alternative/ -r features/support/env.rb -r features/lib/default/tasks/
251
+
252
+ We can run our alternative configuration like so:
253
+
254
+ `%cucumber --profile alternative`
255
+
256
+ The Calculating Web User masquerades as the Calculating Individual from our
257
+ previous example, and provides the same API, allowing us to reuse all of our
258
+ existing features and _tasks_.
259
+
260
+ The alternative, `./lib/web_calculator.rb`, implementation is a simple [Sinatra](http://www.sinatrarb.com) application,
261
+ which we drive with the [Capybara](http://github.com/jnicklas/capybara) web testing framework.
262
+
263
+ By writing a single new _role_ class we're able to reuse all of our existing features,
264
+ _tasks_ and even the `Calculator` itself, which the web calculator delegates to in order to do its calculations.
265
+
266
+ After adding some more scenarios and tasks and an alternative "Calculating Individual" (see below for why), our Calculator directory structure currently looks like this...
200
267
 
201
268
  ├── cucumber.yml
202
269
  ├── features
203
270
  │   ├── A_PlaceToStart.feature
204
271
  │   ├── Addition.feature
205
272
  │   ├── Complex_calculations.feature
206
- │   ├── LOOK_MA_NO_STEP_DEFS.txt
207
273
  │   ├── Subtraction.feature
208
274
  │   ├── Typical_workflow.feature
209
275
  │   ├── lib
@@ -230,29 +296,3 @@ After adding some more scenarios and tasks and an alternative "Calculating Indiv
230
296
  └── web_calculator_spec.rb
231
297
 
232
298
  Take a look around the examples and the code to see how it all works. We hope you enjoy reading as much as we enjoyed writing it.
233
-
234
- ## Alternative Roles
235
-
236
- As our features _describe the value of a calculator application and not its
237
- implementation_, we have the opportunity to reuse them.
238
-
239
- In the Calculator example, we create a new _role_ in
240
- `./features/lib/alternative/roles/calculating_web_user.rb`, which we can swap
241
- into our tests using a Cucumber profile defined in `features/cucumber.yml`:
242
-
243
- default --exclude features/lib/alternative/
244
- alternative -r features/lib/alternative/ -r features/support/env.rb -r features/lib/default/tasks/
245
-
246
- We can run our alternative configuration like so:
247
-
248
- `%cucumber --profile alternative`
249
-
250
- The Calculating Web User masquerades as the Calculating Individual from our
251
- previous example, and provides the same API, allowing us to reuse all of our
252
- existing features and _tasks_.
253
-
254
- The alternative, `./lib/web_calculator.rb`, implementation is a simple [Sinatra](http://www.sinatrarb.com) application,
255
- which we drive with the [Capybara](http://github.com/jnicklas/capybara) web testing framework.
256
-
257
- By writing a single new _role_ class we're able to reuse all of our existing features,
258
- _tasks_ and even the `Calculator` itself, which the web calculator delegates to in order to do its calculations.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.0
1
+ 0.6.0
@@ -1,11 +1,4 @@
1
- # This demonstrates how to use an attribute mapping
2
- # to make the interactions within the task read more naturally
3
- # In the scenario it might say "add: the number '5', to the number '10'
4
- # The form illustrated below simply maps the elements the_number and to_the_number
5
- # to alternative symbols that make the interactions read more like real instructions
6
- # See subtract.rb for a way of writing tasks that reuses the common interactions
7
- # required to perform calculations.
8
- in_order_to 'add', the_number: :first_number, to_the_number: :second_number do
1
+ in_order_to 'add', the_number: :first_number, and_the_number: :second_number do
9
2
  enter the :first_number
10
3
  press :plus
11
4
  enter the :second_number
@@ -2,7 +2,7 @@ in_order_to "switch on the calculator" do
2
2
  require 'rspec/expectations'
3
3
  extend RSpec::Matchers
4
4
 
5
- @calc = switch_on_the_calculator
5
+ switch_on_the_calculator
6
6
  self.should respond_to :enter
7
7
  self.should respond_to :press
8
8
  self.should respond_to :look_at_the_display
@@ -1,4 +1,12 @@
1
- #TODO: Consider exposing this detail in the examples since it shows you what to do
2
- in_order_to 'create a task', called: :name_of_task do
3
- write_file 'features/lib/tasks/some_task.rb', "in_order_to '#{the :name_of_task}' do\nend"
1
+ in_order_to 'create a task', called: :name_of_task, containing: :code do
2
+ file_name = the( :name_of_task ).gsub(" ", "_")
3
+
4
+ default_content =
5
+ "in_order_to '#{the :name_of_task}' do
6
+ #nothing
7
+ end"
8
+ content = the :code
9
+ content = default_content if content.nil?
10
+
11
+ write_file "features/lib/tasks/#{file_name}.rb", content
4
12
  end
@@ -0,0 +1,3 @@
1
+ in_order_to 'not previously take note of something' do
2
+ # nothing
3
+ end
@@ -1,7 +1,7 @@
1
- in_order_to "RunAScenario", containing: :step do
1
+ in_order_to "RunAScenario", containing: :steps do
2
2
  write_file 'features/a.feature', "Feature: A Feature
3
3
 
4
4
  Scenario: A Scenario
5
- #{the :step}"
5
+ #{the :steps}"
6
6
  run_simple unescape( 'cucumber features/a.feature' ), false
7
7
  end
@@ -0,0 +1,50 @@
1
+ Feature: Remember information between steps
2
+ As a Step Free Cuker
3
+ I want information captured in one step to be available in a later step
4
+ So that I can deal with situations where dynamic information is required in later steps
5
+
6
+ Background:
7
+ Given you are a Step Free Cuker
8
+ And you were able to create a new Cuke Salad project
9
+ And you were able to create a role: called 'NewCustomer'
10
+
11
+ Scenario: You can reuse information
12
+ Given you were able to create a task, called 'do something' containing
13
+ """
14
+ in_order_to 'do something', remembering: :value do
15
+ take_note_of :some_key, the( :value )
16
+ end
17
+ """
18
+ And you were able to create a task, called 'find that the thing remembered was' containing
19
+ """
20
+ in_order_to 'find that the thing remembered was' do
21
+ recall :some_key
22
+ end
23
+ """
24
+ When you attempt to run a scenario: containing
25
+ """
26
+ Given I am a New Customer
27
+ When I attempt to do something, remembering 'a value'
28
+ Then I should find that the thing remembered was 'a value'
29
+ """
30
+ Then you should see it has 'passed'
31
+
32
+ Scenario: You'll get feedback if you ask for something that wasn't noted
33
+ Given you did not previously take note of something
34
+ And you were able to create a task, called 'find that the thing remembered was' containing
35
+ """
36
+ in_order_to 'find that the thing remembered was' do
37
+ recall :some_key
38
+ end
39
+ """
40
+ When I attempt to run a scenario: containing
41
+ """
42
+ Given I am a New Customer
43
+ Then I should find that the thing remembered was 'a value'
44
+ """
45
+ Then I should see it has 'failed'
46
+ And I should see a reply that includes:
47
+ """
48
+ You tried to recall ':some_key' but no previous step appears to have taken note of that information
49
+ """
50
+
data/lib/actor.rb CHANGED
@@ -1,10 +1,11 @@
1
1
  require 'director'
2
2
 
3
3
  class Actor
4
-
4
+
5
5
  def initialize this_type_of_role, directed_by=Director.new
6
6
  @director = directed_by
7
7
  get_into_character_for this_type_of_role
8
+ @note_pad = {}
8
9
  end
9
10
 
10
11
  def perform described_task, details = {}
@@ -31,4 +32,16 @@ class Actor
31
32
  def value_of(symbol)
32
33
  @info[symbol]
33
34
  end
35
+
36
+ def take_note_of key, value
37
+ @note_pad.store key, value
38
+ end
39
+
40
+ def recall key
41
+ begin
42
+ @note_pad.fetch key
43
+ rescue KeyError
44
+ raise KeyError, "You tried to recall ':#{key}' but no previous step appears to have taken note of that information."
45
+ end
46
+ end
34
47
  end
data/lib/cukesalad.rb CHANGED
@@ -16,8 +16,8 @@ Given /^(?:I am|you are) a ([a-zA-Z ]+)$/ do |role|
16
16
  @actor = Actor.new(role)
17
17
  end
18
18
 
19
- When /^(?:I|you) (?:attempt to|was able to|were able to|did)? ([A-Z a-z_-]*)(?:[:|,] (.*))?$/ do | this_task, with_these_details, *and_more |
20
- info = understand_the with_these_details unless with_these_details.nil?
19
+ When /^(?:I|you) (?:attempt to|was able to|were able to|did)? ([A-Z a-z_-]*)(?:[:|,] (.*))?:?$/ do | this_task, details, *and_more |
20
+ info = understand_the details unless details.nil?
21
21
  info[info.keys.last] = and_more[0] unless and_more.empty?
22
22
  @actor.perform this_task, info unless info.nil?
23
23
  @actor.perform this_task if info.nil?
data/spec/actor_spec.rb CHANGED
@@ -33,8 +33,8 @@ end
33
33
  describe Actor do
34
34
 
35
35
  it "gets into character" do
36
- director = double("director")
37
36
  role_description = "Butler"
37
+ director = double("director")
38
38
  director.should_receive( :explain_the_role ).with( role_description ).and_return( Butler )
39
39
 
40
40
  actor = Actor.new role_description, director
@@ -68,5 +68,29 @@ describe Actor do
68
68
 
69
69
  actor.perform( task_description, details ).should == 5
70
70
  end
71
+
72
+ it "can take note of information" do
73
+ role_description = "Butler"
74
+
75
+ director = double("director")
76
+ director.should_receive( :explain_the_role ).with( role_description ).and_return( Butler )
77
+
78
+ actor = Actor.new role_description, director
79
+
80
+ actor.take_note_of :something, "of importance"
81
+ actor.recall( :something ).should == "of importance"
82
+ end
83
+
84
+ it "tells you when it can't find the information you're looking for" do
85
+ role_description = "Butler"
86
+
87
+ director = double("director")
88
+ director.should_receive( :explain_the_role ).with( role_description ).and_return( Butler )
89
+
90
+ actor = Actor.new role_description, director
91
+
92
+ lambda {actor.recall( :something )}.should raise_error KeyError,
93
+ "You tried to recall ':something' but no previous step appears to have taken note of that information."
94
+ end
71
95
  end
72
96
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: cukesalad
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.5.0
5
+ version: 0.6.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - RiverGlide
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-04-21 00:00:00 Z
13
+ date: 2011-04-22 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: cucumber
@@ -121,10 +121,12 @@ files:
121
121
  - features/lib/tasks/create_directories.rb
122
122
  - features/lib/tasks/not_create_a_role.rb
123
123
  - features/lib/tasks/not_create_a_task.rb
124
+ - features/lib/tasks/not_previously_take_note_of_something.rb
124
125
  - features/lib/tasks/run.rb
125
126
  - features/lib/tasks/run_a_scenario.rb
126
127
  - features/lib/tasks/see_a_reply.rb
127
128
  - features/lib/tasks/see_the_step_has.rb
129
+ - features/remember_information_between_steps.feature
128
130
  - features/support/env.rb
129
131
  - lib/actor.rb
130
132
  - lib/codify/const_name.rb
@@ -166,7 +168,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
166
168
  requirements:
167
169
  - - ">="
168
170
  - !ruby/object:Gem::Version
169
- hash: -2598108803398810333
171
+ hash: -826541078781353768
170
172
  segments:
171
173
  - 0
172
174
  version: "0"