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.
Files changed (54) hide show
  1. data/.gitignore +15 -0
  2. data/Examples/Calculator/Gemfile +4 -5
  3. data/Examples/Calculator/Gemfile.lock +30 -33
  4. data/Examples/Calculator/features/lib/default/tasks/{add.rb → arithmetic/add.rb} +0 -0
  5. data/Examples/Calculator/features/lib/default/tasks/{calculate.rb → arithmetic/calculate.rb} +0 -0
  6. data/Examples/Calculator/features/lib/default/tasks/{subtract.rb → arithmetic/subtract.rb} +0 -0
  7. data/Examples/Calculator/features/lib/default/tasks/{see_the_answer.rb → questions/see_the_answer.rb} +0 -0
  8. data/Examples/Calculator/features/lib/default/tasks/{calculations.rb → reference/calculations.rb} +0 -0
  9. data/Gemfile +2 -7
  10. data/Gemfile.lock +29 -29
  11. data/Rakefile +1 -21
  12. data/cukesalad.gemspec +29 -0
  13. data/features/define_a_task.feature +17 -17
  14. data/features/remember_information_between_steps.feature +5 -5
  15. data/features/support/env.rb +0 -2
  16. data/lib/cukesalad.rb +2 -36
  17. data/lib/cukesalad/actor.rb +49 -0
  18. data/lib/cukesalad/codify/const_name.rb +23 -0
  19. data/lib/cukesalad/cucumber.rb +35 -0
  20. data/lib/cukesalad/director.rb +30 -0
  21. data/lib/cukesalad/salad.rb +3 -0
  22. data/lib/cukesalad/specifics.rb +36 -0
  23. data/lib/cukesalad/task_author.rb +21 -0
  24. data/lib/cukesalad/version.rb +3 -0
  25. data/spec/cukesalad/actor_spec.rb +96 -0
  26. data/spec/cukesalad/codify/as_const_name_spec.rb +30 -0
  27. data/spec/cukesalad/director_spec.rb +36 -0
  28. data/spec/cukesalad/specifics_spec.rb +68 -0
  29. data/spec/cukesalad/task_author_spec.rb +52 -0
  30. data/spec/spec_helper.rb +1 -4
  31. metadata +62 -59
  32. data/examples/Calculator/features/lib/alternative/roles/calculating_web_user.rb +0 -55
  33. data/examples/Calculator/features/lib/default/roles/calculating_individual.rb +0 -32
  34. data/examples/Calculator/features/lib/default/tasks/add.rb +0 -6
  35. data/examples/Calculator/features/lib/default/tasks/calculate.rb +0 -4
  36. data/examples/Calculator/features/lib/default/tasks/calculations.rb +0 -15
  37. data/examples/Calculator/features/lib/default/tasks/see_the_answer.rb +0 -3
  38. data/examples/Calculator/features/lib/default/tasks/subtract.rb +0 -4
  39. data/examples/Calculator/features/lib/default/tasks/switch_on_the_calculator.rb +0 -9
  40. data/examples/Calculator/features/support/env.rb +0 -5
  41. data/examples/Calculator/lib/calculator.rb +0 -53
  42. data/examples/Calculator/lib/web_calculator.rb +0 -82
  43. data/examples/Calculator/spec/calculator_spec.rb +0 -73
  44. data/examples/Calculator/spec/web_calculator_spec.rb +0 -99
  45. data/lib/actor.rb +0 -47
  46. data/lib/codify/const_name.rb +0 -21
  47. data/lib/director.rb +0 -28
  48. data/lib/specifics.rb +0 -34
  49. data/lib/task_author.rb +0 -12
  50. data/spec/actor_spec.rb +0 -96
  51. data/spec/codify/as_const_name_spec.rb +0 -28
  52. data/spec/director_spec.rb +0 -34
  53. data/spec/specifics_spec.rb +0 -67
  54. 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,3 @@
1
+ require 'cukesalad/actor'
2
+ require 'cukesalad/task_author'
3
+ require 'cukesalad/specifics'
@@ -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,3 @@
1
+ module CukeSalad
2
+ VERSION = "0.6.1"
3
+ 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