cukesalad 0.6.0 → 0.6.1
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.
- data/.gitignore +15 -0
- data/Examples/Calculator/Gemfile +4 -5
- data/Examples/Calculator/Gemfile.lock +30 -33
- data/Examples/Calculator/features/lib/default/tasks/{add.rb → arithmetic/add.rb} +0 -0
- data/Examples/Calculator/features/lib/default/tasks/{calculate.rb → arithmetic/calculate.rb} +0 -0
- data/Examples/Calculator/features/lib/default/tasks/{subtract.rb → arithmetic/subtract.rb} +0 -0
- data/Examples/Calculator/features/lib/default/tasks/{see_the_answer.rb → questions/see_the_answer.rb} +0 -0
- data/Examples/Calculator/features/lib/default/tasks/{calculations.rb → reference/calculations.rb} +0 -0
- data/Gemfile +2 -7
- data/Gemfile.lock +29 -29
- data/Rakefile +1 -21
- data/cukesalad.gemspec +29 -0
- data/features/define_a_task.feature +17 -17
- data/features/remember_information_between_steps.feature +5 -5
- data/features/support/env.rb +0 -2
- data/lib/cukesalad.rb +2 -36
- data/lib/cukesalad/actor.rb +49 -0
- data/lib/cukesalad/codify/const_name.rb +23 -0
- data/lib/cukesalad/cucumber.rb +35 -0
- data/lib/cukesalad/director.rb +30 -0
- data/lib/cukesalad/salad.rb +3 -0
- data/lib/cukesalad/specifics.rb +36 -0
- data/lib/cukesalad/task_author.rb +21 -0
- data/lib/cukesalad/version.rb +3 -0
- data/spec/cukesalad/actor_spec.rb +96 -0
- data/spec/cukesalad/codify/as_const_name_spec.rb +30 -0
- data/spec/cukesalad/director_spec.rb +36 -0
- data/spec/cukesalad/specifics_spec.rb +68 -0
- data/spec/cukesalad/task_author_spec.rb +52 -0
- data/spec/spec_helper.rb +1 -4
- metadata +62 -59
- data/examples/Calculator/features/lib/alternative/roles/calculating_web_user.rb +0 -55
- data/examples/Calculator/features/lib/default/roles/calculating_individual.rb +0 -32
- data/examples/Calculator/features/lib/default/tasks/add.rb +0 -6
- data/examples/Calculator/features/lib/default/tasks/calculate.rb +0 -4
- data/examples/Calculator/features/lib/default/tasks/calculations.rb +0 -15
- data/examples/Calculator/features/lib/default/tasks/see_the_answer.rb +0 -3
- data/examples/Calculator/features/lib/default/tasks/subtract.rb +0 -4
- data/examples/Calculator/features/lib/default/tasks/switch_on_the_calculator.rb +0 -9
- data/examples/Calculator/features/support/env.rb +0 -5
- data/examples/Calculator/lib/calculator.rb +0 -53
- data/examples/Calculator/lib/web_calculator.rb +0 -82
- data/examples/Calculator/spec/calculator_spec.rb +0 -73
- data/examples/Calculator/spec/web_calculator_spec.rb +0 -99
- data/lib/actor.rb +0 -47
- data/lib/codify/const_name.rb +0 -21
- data/lib/director.rb +0 -28
- data/lib/specifics.rb +0 -34
- data/lib/task_author.rb +0 -12
- data/spec/actor_spec.rb +0 -96
- data/spec/codify/as_const_name_spec.rb +0 -28
- data/spec/director_spec.rb +0 -34
- data/spec/specifics_spec.rb +0 -67
- data/spec/task_author_spec.rb +0 -50
@@ -0,0 +1,23 @@
|
|
1
|
+
module CukeSalad
|
2
|
+
module Codify
|
3
|
+
module ConstName
|
4
|
+
def ConstName.from sentence
|
5
|
+
joined_together capitalised( words_from sentence )
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
def ConstName.joined_together words
|
10
|
+
words.join
|
11
|
+
end
|
12
|
+
|
13
|
+
def ConstName.words_from this_sentence
|
14
|
+
on_word_boundary = /\s|([A-Z][a-z]+)/
|
15
|
+
this_sentence.split( on_word_boundary )
|
16
|
+
end
|
17
|
+
|
18
|
+
def ConstName.capitalised words
|
19
|
+
words.collect{ | word | word.capitalize }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'cukesalad'
|
2
|
+
|
3
|
+
def in_order_to(do_something, *with_attributes, &actions)
|
4
|
+
CukeSalad::TaskAuthor.in_order_to(do_something, *with_attributes, &actions)
|
5
|
+
end
|
6
|
+
|
7
|
+
World(CukeSalad::TaskAuthor)
|
8
|
+
World(CukeSalad::Specifics)
|
9
|
+
|
10
|
+
When /^I say hello CukeSalad$/ do
|
11
|
+
puts "CukeSalad says: Hello!!"
|
12
|
+
end
|
13
|
+
|
14
|
+
Given /^(?:I am|you are) a ([a-zA-Z ]+)$/ do |role|
|
15
|
+
@actor = CukeSalad::Actor.new(role)
|
16
|
+
end
|
17
|
+
|
18
|
+
When /^(?:I|you) (?:attempt to|was able to|were able to|did)? ([A-Z a-z_-]*)(?:[:|,] (.*))?:?$/ do | this_task, details, *and_more |
|
19
|
+
info = understand_the details unless details.nil?
|
20
|
+
info[info.keys.last] = and_more[0] unless and_more.empty?
|
21
|
+
@actor.perform this_task, info unless info.nil?
|
22
|
+
@actor.perform this_task if info.nil?
|
23
|
+
end
|
24
|
+
|
25
|
+
Then /^(?:I|you) should ([^':]*)(?: '([^']*)')$/ do | this_question, expect_value |
|
26
|
+
@actor.answer( this_question ).to_s.should == expect_value
|
27
|
+
end
|
28
|
+
|
29
|
+
Then /^(?:I|you) should ([^':]+)$/ do | this_question |
|
30
|
+
@actor.answer( this_question )
|
31
|
+
end
|
32
|
+
|
33
|
+
Then /^(?:I|you) should ([^']*) that includes:$/ do | this_question, expected_content |
|
34
|
+
@actor.answer( this_question ).should include( expected_content )
|
35
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'cukesalad/codify/const_name'
|
2
|
+
module CukeSalad
|
3
|
+
class Director
|
4
|
+
|
5
|
+
include Codify
|
6
|
+
|
7
|
+
#TODO: Needs refactoring
|
8
|
+
def explain_the_role description
|
9
|
+
name = ConstName.from description
|
10
|
+
begin
|
11
|
+
find_directives_for name
|
12
|
+
rescue NameError
|
13
|
+
raise "I can't find a role called '#{ name }'. Have you created it?\ne.g.\n module #{ name }\n end"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def how_do_i_perform something
|
18
|
+
name = ConstName.from something
|
19
|
+
begin
|
20
|
+
find_directives_for name
|
21
|
+
rescue NameError
|
22
|
+
raise "I can't find a task called '#{ something }'. Have you created it?\ne.g.\n in_order_to '#{ something }' do\n # the actions\n end"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def find_directives_for something
|
27
|
+
Kernel.const_get( something )
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module CukeSalad
|
2
|
+
module Specifics
|
3
|
+
def understand_the details
|
4
|
+
@info = with_specifics_from( details )
|
5
|
+
end
|
6
|
+
|
7
|
+
def value_of(symbol)
|
8
|
+
@info[symbol]
|
9
|
+
end
|
10
|
+
|
11
|
+
def with_specifics_from details
|
12
|
+
result = {}
|
13
|
+
names_and_values_in(details).each_slice(2) do |name_value|
|
14
|
+
result[symbolized name_value[0]] = the_value_from_the name_value[1]
|
15
|
+
end
|
16
|
+
result
|
17
|
+
end
|
18
|
+
|
19
|
+
def set_last value
|
20
|
+
@info[@info.keys.last] = value
|
21
|
+
end
|
22
|
+
|
23
|
+
def names_and_values_in details
|
24
|
+
specifics_pattern = /('[^']+')/
|
25
|
+
details.split(specifics_pattern)
|
26
|
+
end
|
27
|
+
|
28
|
+
def symbolized name
|
29
|
+
name.strip.gsub(' ', '_').to_sym
|
30
|
+
end
|
31
|
+
|
32
|
+
def the_value_from_the item
|
33
|
+
item.gsub(/(^'|'$)/, '') unless item.nil?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'cukesalad/codify/const_name'
|
2
|
+
module CukeSalad
|
3
|
+
module TaskAuthor
|
4
|
+
|
5
|
+
def in_order_to do_something, *with_attributes, &actions
|
6
|
+
TaskAuthor.in_order_to do_something, *with_attributes, &actions
|
7
|
+
end
|
8
|
+
|
9
|
+
def TaskAuthor.in_order_to do_something, *with_attributes, &actions
|
10
|
+
attr_map = with_attributes[0]
|
11
|
+
name = Codify::ConstName.from do_something
|
12
|
+
m = Module.new do
|
13
|
+
define_method :perform_task, &actions
|
14
|
+
define_method :the do | value |
|
15
|
+
value_of( attr_map.key value )
|
16
|
+
end
|
17
|
+
end
|
18
|
+
Kernel.const_set name, m
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module SetThePlaceAtTheTable
|
4
|
+
|
5
|
+
def perform_task
|
6
|
+
place = []
|
7
|
+
place_the_fork_on_the_left_of place
|
8
|
+
place_the_knife_on_the_right_of place
|
9
|
+
place
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module LayTheTable
|
14
|
+
|
15
|
+
def perform_task
|
16
|
+
value_of( :with_places_for ).to_i
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module Butler
|
21
|
+
|
22
|
+
def place_the_fork_on_the_left_of place
|
23
|
+
place.unshift "fork"
|
24
|
+
end
|
25
|
+
|
26
|
+
def place_the_knife_on_the_right_of place
|
27
|
+
place.push "knife"
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
module CukeSalad
|
33
|
+
describe Actor do
|
34
|
+
|
35
|
+
it "gets into character" do
|
36
|
+
role_description = "Butler"
|
37
|
+
director = double("director")
|
38
|
+
director.should_receive( :explain_the_role ).with( role_description ).and_return( Butler )
|
39
|
+
|
40
|
+
actor = Actor.new role_description, director
|
41
|
+
end
|
42
|
+
|
43
|
+
it "performs a simple task as that character" do
|
44
|
+
role_description = "Butler"
|
45
|
+
|
46
|
+
task_description = "set the place at the table"
|
47
|
+
|
48
|
+
director = double("director")
|
49
|
+
director.should_receive( :explain_the_role ).with( role_description ).and_return( Butler )
|
50
|
+
director.should_receive( :how_do_i_perform ).with( task_description ).and_return( SetThePlaceAtTheTable )
|
51
|
+
|
52
|
+
actor = Actor.new role_description, director
|
53
|
+
|
54
|
+
actor.perform(task_description).should == ["fork","knife"]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "can perform a task that requires certain details" do
|
58
|
+
role_description = "Butler"
|
59
|
+
|
60
|
+
task_description = "Lay The Table"
|
61
|
+
details = { with_places_for: '5' }
|
62
|
+
|
63
|
+
director = double("director")
|
64
|
+
director.should_receive( :explain_the_role ).with( role_description ).and_return( Butler )
|
65
|
+
director.should_receive( :how_do_i_perform ).with( task_description ).and_return( LayTheTable )
|
66
|
+
|
67
|
+
actor = Actor.new role_description, director
|
68
|
+
|
69
|
+
actor.perform( task_description, details ).should == 5
|
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
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'cukesalad/codify/const_name'
|
3
|
+
|
4
|
+
module CukeSalad
|
5
|
+
module Codify
|
6
|
+
describe ConstName do
|
7
|
+
|
8
|
+
it "gives you ClassName from when it's already a class name" do
|
9
|
+
ConstName.from( "ClassName" ).should == "ClassName"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "gives you ClassName when separated by spaces" do
|
13
|
+
ConstName.from( "Class Name" ).should == "ClassName"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "gives you ClassName from lowercase class name" do
|
17
|
+
ConstName.from( "class name" ).should == "ClassName"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "gives you ClassName from lower case class name with leading/trailing spaces" do
|
21
|
+
ConstName.from( " class name " ).should == "ClassName"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "formats as a ClassName from a mix of class format and lower case" do
|
25
|
+
ConstName.from( "AnotherClass name " ).should == "AnotherClassName"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class Something
|
4
|
+
end
|
5
|
+
class Another
|
6
|
+
end
|
7
|
+
class MoreThanOneWord
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
module CukeSalad
|
12
|
+
describe Director do
|
13
|
+
|
14
|
+
before :each do
|
15
|
+
@director = Director.new
|
16
|
+
end
|
17
|
+
|
18
|
+
it "gives you directives (i.e. a class) for Something" do
|
19
|
+
the_thing_we_found = @director.how_do_i_perform "something"
|
20
|
+
the_thing_we_found.should == Something
|
21
|
+
end
|
22
|
+
|
23
|
+
it "finds directives (i.e. a class) for something described with more than one word" do
|
24
|
+
the_thing_we_found = @director.how_do_i_perform "more than one word"
|
25
|
+
the_thing_we_found.should == MoreThanOneWord
|
26
|
+
end
|
27
|
+
|
28
|
+
it "apologises when it can't find the role" do
|
29
|
+
lambda { @director.explain_the_role "non existent role" }.should raise_error RuntimeError
|
30
|
+
end
|
31
|
+
|
32
|
+
it "apologises when it can't find the task" do
|
33
|
+
lambda { @director.how_do_i_perform "non existent task" }.should raise_error RuntimeError
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class NeedingSpecifics
|
4
|
+
include CukeSalad::Specifics
|
5
|
+
end
|
6
|
+
|
7
|
+
module CukeSalad
|
8
|
+
describe Specifics do
|
9
|
+
|
10
|
+
it "has an item of specific information" do
|
11
|
+
something = NeedingSpecifics.new
|
12
|
+
something.understand_the "specific 'information'"
|
13
|
+
something.value_of(:specific).should == "information"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "has items of specific information" do
|
17
|
+
something = NeedingSpecifics.new
|
18
|
+
something.understand_the "first 'item' second 'another'"
|
19
|
+
something.value_of(:first).should == "item"
|
20
|
+
something.value_of(:second).should == "another"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "copes with names having more than one word" do
|
24
|
+
something = NeedingSpecifics.new
|
25
|
+
something.understand_the "first thing 'item' second thing 'another'"
|
26
|
+
something.value_of(:first_thing).should == "item"
|
27
|
+
something.value_of(:second_thing).should == "another"
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should cope with values having more than one word" do
|
31
|
+
something = NeedingSpecifics.new
|
32
|
+
something.understand_the "first thing 'item' second thing 'another thing'"
|
33
|
+
something.value_of(:first_thing).should == "item"
|
34
|
+
something.value_of(:second_thing).should == "another thing"
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'the last item' do
|
38
|
+
it "can be empty" do
|
39
|
+
something = NeedingSpecifics.new
|
40
|
+
something.understand_the "containing"
|
41
|
+
something.value_of(:containing).should be_nil
|
42
|
+
end
|
43
|
+
|
44
|
+
it "can be the only item and have a value assigned" do
|
45
|
+
something = NeedingSpecifics.new
|
46
|
+
something.understand_the "containing"
|
47
|
+
something.set_last('some value')
|
48
|
+
something.value_of(:containing).should == 'some value'
|
49
|
+
end
|
50
|
+
|
51
|
+
it "can be the only item and be empty" do
|
52
|
+
something = NeedingSpecifics.new
|
53
|
+
something.understand_the "called 'something' containing"
|
54
|
+
something.value_of(:called).should == 'something'
|
55
|
+
something.value_of(:containing).should be_nil
|
56
|
+
end
|
57
|
+
|
58
|
+
it "can have a value assigned" do
|
59
|
+
something = NeedingSpecifics.new
|
60
|
+
something.understand_the "called 'something' containing"
|
61
|
+
something.value_of(:called).should == 'something'
|
62
|
+
something.set_last('some value')
|
63
|
+
something.value_of(:containing).should == 'some value'
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'cukesalad/task_author'
|
3
|
+
|
4
|
+
class SomeActor
|
5
|
+
def see_how_to_do something
|
6
|
+
extend something
|
7
|
+
end
|
8
|
+
def do_your_thing
|
9
|
+
perform_task
|
10
|
+
end
|
11
|
+
def value_of thing
|
12
|
+
"this is the info"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module CukeSalad
|
17
|
+
describe 'TaskAuthor' do
|
18
|
+
include TaskAuthor
|
19
|
+
|
20
|
+
it "creates a module by the same name" do
|
21
|
+
in_order_to "SomeTask" do;end
|
22
|
+
|
23
|
+
SomeActor.new.see_how_to_do SomeTask
|
24
|
+
end
|
25
|
+
|
26
|
+
it "creates a module by a similar name" do
|
27
|
+
in_order_to "some different task" do;end
|
28
|
+
|
29
|
+
SomeActor.new SomeDifferentTask
|
30
|
+
end
|
31
|
+
|
32
|
+
it "enables the actor to do something" do
|
33
|
+
in_order_to "SomeOtherTask" do
|
34
|
+
"done"
|
35
|
+
end
|
36
|
+
|
37
|
+
actor = SomeActor.new
|
38
|
+
actor.see_how_to_do SomeOtherTask
|
39
|
+
actor.do_your_thing.should == "done"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "maps some attributes" do
|
43
|
+
in_order_to "YetAnotherTask", with_info: :info do
|
44
|
+
the :info
|
45
|
+
end
|
46
|
+
|
47
|
+
actor = SomeActor.new
|
48
|
+
actor.see_how_to_do YetAnotherTask
|
49
|
+
actor.do_your_thing.should == "this is the info"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|