cukesalad 0.2.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.
Files changed (76) hide show
  1. data/.rspec +1 -0
  2. data/Examples/Calculator/Gemfile +5 -0
  3. data/Examples/Calculator/Gemfile.lock +66 -0
  4. data/Examples/Calculator/cucumber.yml +4 -0
  5. data/Examples/Calculator/features/LOOK_MA_NO_STEP_DEFS.txt +2 -0
  6. data/Examples/Calculator/features/a_place_to_start.feature +9 -0
  7. data/Examples/Calculator/features/addition.feature +19 -0
  8. data/Examples/Calculator/features/complex_calculations.feature +16 -0
  9. data/Examples/Calculator/features/lib/alternative/roles/calculating_web_user.rb +55 -0
  10. data/Examples/Calculator/features/lib/default/roles/calculating_individual.rb +32 -0
  11. data/Examples/Calculator/features/lib/default/tasks/add.rb +13 -0
  12. data/Examples/Calculator/features/lib/default/tasks/calculate.rb +4 -0
  13. data/Examples/Calculator/features/lib/default/tasks/calculations.rb +15 -0
  14. data/Examples/Calculator/features/lib/default/tasks/see_the_answer.rb +3 -0
  15. data/Examples/Calculator/features/lib/default/tasks/subtract.rb +4 -0
  16. data/Examples/Calculator/features/lib/default/tasks/switch_on_the_calculator.rb +9 -0
  17. data/Examples/Calculator/features/subtraction.feature +20 -0
  18. data/Examples/Calculator/features/support/env.rb +6 -0
  19. data/Examples/Calculator/features/typical_workflow.feature +18 -0
  20. data/Examples/Calculator/lib/calculator.rb +53 -0
  21. data/Examples/Calculator/lib/config.ru +4 -0
  22. data/Examples/Calculator/lib/web_calculator.rb +82 -0
  23. data/Examples/Calculator/spec/calculator_spec.rb +73 -0
  24. data/Examples/Calculator/spec/web_calculator_spec.rb +99 -0
  25. data/Gemfile +9 -0
  26. data/Gemfile.lock +47 -0
  27. data/LICENSE +21 -0
  28. data/README.md +273 -0
  29. data/Rakefile +53 -0
  30. data/VERSION +1 -0
  31. data/bin/cukesalad +28 -0
  32. data/cucumber.yml +4 -0
  33. data/cukesalad/cli.rb +68 -0
  34. data/examples/Calculator/features/lib/alternative/roles/calculating_web_user.rb +55 -0
  35. data/examples/Calculator/features/lib/default/roles/calculating_individual.rb +32 -0
  36. data/examples/Calculator/features/lib/default/tasks/add.rb +13 -0
  37. data/examples/Calculator/features/lib/default/tasks/calculate.rb +4 -0
  38. data/examples/Calculator/features/lib/default/tasks/calculations.rb +15 -0
  39. data/examples/Calculator/features/lib/default/tasks/see_the_answer.rb +3 -0
  40. data/examples/Calculator/features/lib/default/tasks/subtract.rb +4 -0
  41. data/examples/Calculator/features/lib/default/tasks/switch_on_the_calculator.rb +9 -0
  42. data/examples/Calculator/features/support/env.rb +6 -0
  43. data/examples/Calculator/lib/calculator.rb +53 -0
  44. data/examples/Calculator/lib/web_calculator.rb +82 -0
  45. data/examples/Calculator/spec/calculator_spec.rb +73 -0
  46. data/examples/Calculator/spec/web_calculator_spec.rb +99 -0
  47. data/features/a_new_cukesalad_project.feature +34 -0
  48. data/features/define_a_role.feature +31 -0
  49. data/features/define_a_task.feature +55 -0
  50. data/features/lib/roles/step_free_cuker.rb +5 -0
  51. data/features/lib/tasks/create_a_file.rb +3 -0
  52. data/features/lib/tasks/create_a_new_cukesalad_project.rb +11 -0
  53. data/features/lib/tasks/create_a_role.rb +4 -0
  54. data/features/lib/tasks/create_a_task.rb +4 -0
  55. data/features/lib/tasks/create_directories.rb +5 -0
  56. data/features/lib/tasks/not_create_a_role.rb +2 -0
  57. data/features/lib/tasks/not_create_a_task.rb +3 -0
  58. data/features/lib/tasks/run.rb +4 -0
  59. data/features/lib/tasks/run_a_scenario.rb +7 -0
  60. data/features/lib/tasks/see_a_reply.rb +3 -0
  61. data/features/lib/tasks/see_the_step_has.rb +4 -0
  62. data/features/support/env.rb +7 -0
  63. data/lib/actor.rb +32 -0
  64. data/lib/codify/const_name.rb +21 -0
  65. data/lib/cukesalad.rb +33 -0
  66. data/lib/director.rb +28 -0
  67. data/lib/specifics.rb +30 -0
  68. data/lib/task_author.rb +12 -0
  69. data/spec/actor_spec.rb +72 -0
  70. data/spec/codify/as_const_name_spec.rb +28 -0
  71. data/spec/cukesalad/cli_spec.rb +99 -0
  72. data/spec/director_spec.rb +34 -0
  73. data/spec/spec_helper.rb +8 -0
  74. data/spec/specifics_spec.rb +36 -0
  75. data/spec/task_author_spec.rb +50 -0
  76. metadata +202 -0
@@ -0,0 +1,53 @@
1
+
2
+ class Calculator
3
+
4
+ attr_reader :display
5
+
6
+ def initialize
7
+ show 0
8
+ @operands = []
9
+ end
10
+
11
+ def enter value
12
+ show value
13
+ @operands.push value
14
+ end
15
+
16
+ def get_ready_to op
17
+ calculate_if_necessary
18
+ start_next_calculation
19
+ @operator = op
20
+ end
21
+
22
+ def equals
23
+ we_need_two_operands
24
+ deal_with_repeated_equals
25
+ unless @operator.nil?
26
+ show @operands.inject (@operator)
27
+ @last_operator = @operator
28
+ @operator = nil
29
+ @operands[0] = @display
30
+ end
31
+ end
32
+
33
+ private
34
+ def show value
35
+ @display = value
36
+ end
37
+
38
+ def calculate_if_necessary
39
+ equals if @operands.size == 2
40
+ end
41
+
42
+ def start_next_calculation
43
+ @operands = [@display] if @operator.nil?
44
+ end
45
+
46
+ def we_need_two_operands
47
+ @operands.concat @operands if @operands.size == 1
48
+ end
49
+
50
+ def deal_with_repeated_equals
51
+ @operator = @last_operator if @operands.size == 2 && @operator.nil? && @last_operator
52
+ end
53
+ end
@@ -0,0 +1,82 @@
1
+ require 'sinatra/base'
2
+ require 'erb'
3
+ $:.unshift(File.dirname(__FILE__), '.')
4
+ require 'calculator'
5
+
6
+ Sinatra::Base.enable :inline_templates
7
+ Sinatra::Base.enable :sessions
8
+
9
+ class WebCalculator < Sinatra::Base
10
+
11
+ helpers do
12
+ def operate_with
13
+ { 'plus' => :+, 'minus' => :-}
14
+ end
15
+
16
+ def persist calc
17
+ session[:calc] = calc
18
+ end
19
+
20
+ def display_result_from calc
21
+ @display = calc.display
22
+ erb :index
23
+ end
24
+
25
+ def user_input
26
+ params[:number].to_i
27
+ end
28
+
29
+ def selected_operator
30
+ params[:operator]
31
+ end
32
+
33
+ def display_result_from_session
34
+ @display = session[:calc].display ||= 0
35
+ erb :index
36
+ end
37
+
38
+ def input_entered?
39
+ not params[:number].empty?
40
+ end
41
+
42
+ def equals_pressed?
43
+ selected_operator == "equals"
44
+ end
45
+
46
+ def load_calculator
47
+ session[:calc] ||= Calculator.new
48
+ end
49
+
50
+ end
51
+
52
+ get '/' do
53
+ load_calculator
54
+ display_result_from_session
55
+ end
56
+
57
+ post '/' do
58
+ calculator = load_calculator
59
+ calculator.enter user_input if input_entered?
60
+ if equals_pressed?
61
+ calculator.equals
62
+ else
63
+ calculator.get_ready_to operate_with[selected_operator]
64
+ end
65
+ persist calculator
66
+ display_result_from calculator
67
+ end
68
+ end
69
+
70
+ __END__
71
+ @@ layout
72
+ <h1>Calculator is Ready!</h1>
73
+ <%= yield %>
74
+
75
+ @@ index
76
+ <form method="POST" action="/">
77
+ <input type="text" disabled name="display" id="display" value="<%=@display %>" />
78
+ <input type="text" name="number" id="number" />
79
+ <input type="submit" name="operator" id="minus" text="-" value="minus" />
80
+ <input type="submit" name="operator" id="plus" text="+" value="plus" />
81
+ <input type="submit" name="operator" id="equals" text="=" value="equals" />
82
+ </form>
@@ -0,0 +1,73 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
2
+ require 'rubygems'
3
+ require 'bundler'
4
+ Bundler.setup
5
+ require 'calculator'
6
+
7
+ describe Calculator do
8
+
9
+ it "starts with zero" do
10
+ calc = Calculator.new
11
+
12
+ calc.display.should == 0
13
+ end
14
+
15
+ it "shows the current number" do
16
+ calc = Calculator.new
17
+ calc.enter 1
18
+
19
+ calc.display.should == 1
20
+ end
21
+
22
+ it "displays the same when equals alone is pressed" do
23
+ calc = Calculator.new
24
+ calc.enter 1
25
+
26
+ calc.equals
27
+
28
+ calc.display.should == 1
29
+ end
30
+
31
+ it "treats 1 + = like 1 + 1 =" do
32
+ calc = Calculator.new
33
+
34
+ calc.enter 1
35
+ calc.get_ready_to :+
36
+ calc.equals
37
+
38
+ calc.display.should == 2
39
+ end
40
+
41
+ it "repeats the last operation" do
42
+ calc = Calculator.new
43
+ calc.enter 1
44
+ calc.get_ready_to :+
45
+ calc.equals
46
+ calc.equals
47
+ calc.display.should == 3
48
+ end
49
+
50
+ it "starts again when you enter a number after equals" do
51
+ calc = Calculator.new
52
+ calc.enter 1
53
+ calc.get_ready_to :+
54
+ calc.enter 1
55
+ calc.equals
56
+ calc.enter 5
57
+ calc.get_ready_to :+
58
+ calc.equals
59
+
60
+ calc.display.should == 10
61
+ end
62
+
63
+ it "calculate what it has so far" do
64
+ calc = Calculator.new
65
+ calc.enter 1
66
+ calc.get_ready_to :+
67
+ calc.enter 1
68
+ calc.get_ready_to :+
69
+
70
+ calc.display.should == 2
71
+ end
72
+
73
+ end
@@ -0,0 +1,99 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib/')
2
+ require 'web_calculator'
3
+ require 'capybara'
4
+ require 'capybara/dsl'
5
+
6
+ Capybara.app = WebCalculator
7
+ Capybara.default_driver = :rack_test
8
+
9
+ describe "WebCalculator", :type => :request do
10
+
11
+ include Capybara
12
+
13
+ before(:each) do
14
+ Capybara.reset_sessions!
15
+ end
16
+
17
+ context "homepage" do
18
+ it "is successful" do
19
+ visit '/'
20
+ page.should have_content 'Calculator is Ready!'
21
+ end
22
+ end
23
+
24
+ def calculator_display
25
+ find_field('display').value.to_i
26
+ end
27
+
28
+ context "storing calculator display state" do
29
+ it "starts with nothing" do
30
+ visit '/'
31
+ calculator_display.should == 0
32
+ end
33
+
34
+ it "udpates the display when an operator is pressed" do
35
+ visit '/'
36
+ fill_in 'number', :with => '10'
37
+ click_button 'minus'
38
+ calculator_display.should == 10
39
+ end
40
+
41
+ it "updates the display when a different different operator is pressed" do
42
+ visit '/'
43
+ fill_in 'number', :with => '15'
44
+ click_button 'plus'
45
+ calculator_display.should == 15
46
+ end
47
+
48
+ it "updates the display when a sequence of operators are entered" do
49
+ visit '/'
50
+ fill_in 'number', :with => '1'
51
+ click_button 'plus'
52
+ fill_in 'number', :with => '1'
53
+ click_button 'plus'
54
+ calculator_display.should == 2
55
+ end
56
+
57
+ it "persists the display between requests" do
58
+ visit '/'
59
+ fill_in 'number', :with => '15'
60
+ click_button 'plus'
61
+ calculator_display.should == 15
62
+ visit '/'
63
+ calculator_display.should == 15
64
+ end
65
+ end
66
+
67
+ context "doing simple arithmetic" do
68
+ it "adds two numbers" do
69
+ visit '/'
70
+ fill_in 'number', :with => '1'
71
+ click_button 'plus'
72
+ fill_in 'number', :with => '0'
73
+ click_button 'equals'
74
+ calculator_display.should == 1
75
+ end
76
+
77
+ it "adds two of the same number" do
78
+ visit '/'
79
+ fill_in 'number', :with => '1'
80
+ click_button 'plus'
81
+ fill_in 'number', :with => '1'
82
+ click_button 'equals'
83
+ calculator_display.should == 2
84
+ end
85
+ end
86
+
87
+ context "doing meta calculations" do
88
+ it "allows double equals calculator functionality" do
89
+ visit '/'
90
+ fill_in 'number', :with => '1'
91
+ click_button 'plus'
92
+ click_button 'equals'
93
+ calculator_display.should == 2
94
+ click_button 'equals'
95
+ calculator_display.should == 3
96
+ end
97
+ end
98
+
99
+ end
@@ -0,0 +1,34 @@
1
+ Feature: Cuke Salad
2
+ As a Step Free Cuker
3
+ You want to set up your project to use use Cuke Salad
4
+ So that you can start writing scenarios without step definitions
5
+
6
+ Scenario: Set up your project and verify that you can use CukeSalad
7
+ Given you are a Step Free Cuker
8
+ And you were able to create directories: as follows
9
+ """
10
+ features
11
+ features/lib
12
+ features/lib/roles
13
+ features/lib/tasks
14
+ features/support
15
+ """
16
+ And you were able to create a file: at 'features/support/env.rb' containing
17
+ """
18
+ $:.unshift(File.dirname(__FILE__) + "/../../../../lib") #where to find CukeSalad
19
+
20
+ require "cukesalad"
21
+ """
22
+ And you were able to create a file: at 'features/hello_cukesalad.feature' containing
23
+ """
24
+ Feature: Hello CukeSalad
25
+
26
+ Scenario: Greetings
27
+ When I say hello CukeSalad
28
+ """
29
+ When you attempt to run: the command 'cucumber'
30
+ Then you should see a reply that includes:
31
+ """
32
+ CukeSalad says: Hello!!
33
+ """
34
+ And you should see it has 'passed'
@@ -0,0 +1,31 @@
1
+ Feature: Define the Role
2
+ As a Step Free Cuker
3
+ You want to define a role
4
+ So that you are ready to explain the tasks
5
+
6
+ Background:
7
+ Given you are a Step Free Cuker
8
+ And you were able to create a new Cuke Salad project
9
+
10
+ Scenario: We'll tell you what you need to do to establish the role
11
+ Given you did not create a role: called 'NewCustomer'
12
+ When you attempt to run a scenario: containing
13
+ """
14
+ Given I am a New Customer
15
+ """
16
+ Then you should see it has 'failed'
17
+ And you should see a reply that includes:
18
+ """
19
+ I can't find a role called 'NewCustomer'. Have you created it?
20
+ e.g.
21
+ module NewCustomer
22
+ end
23
+ """
24
+
25
+ Scenario: Once you've created the role, you see the step pass
26
+ Given you did create a role: called 'NewCustomer'
27
+ When you attempt to run a scenario: containing
28
+ """
29
+ Given I am a New Customer
30
+ """
31
+ Then you should see it has 'passed'
@@ -0,0 +1,55 @@
1
+ Feature: Define the Task
2
+ As a Step Free Cuker
3
+ You want to describe a task
4
+ So that your steps that use that role are executed
5
+
6
+
7
+ Background:
8
+ Given you are a Step Free Cuker
9
+ And you were able to create a new Cuke Salad project
10
+ And you were able to create a role: called 'NewCustomer'
11
+
12
+ Scenario: We'll tell you what you need to do to describe the task
13
+ Given you did not create a task: called 'do something'
14
+ When you attempt to run a scenario: containing
15
+ """
16
+ Given I am a New Customer
17
+ And I was able to do something
18
+ """
19
+ Then you should see it has 'failed'
20
+ And you should see a reply that includes:
21
+ """
22
+ I can't find a task called 'do something'. Have you created it?
23
+ e.g.
24
+ in_order_to 'do something' do
25
+ # the actions
26
+ end
27
+ """
28
+
29
+ Scenario Outline: Once you've created the task, you see the step pass
30
+ Given you did create a task: called 'do something'
31
+ When you attempt to run a scenario: containing
32
+ """
33
+ Given I am a New Customer
34
+ <step using the task>
35
+ """
36
+ Then you should see it has 'passed'
37
+
38
+ Examples:
39
+ | step using the task |
40
+ | Given I was able to do something |
41
+ | And I was able to do something |
42
+ | But I did do something |
43
+ | Given you were able to do something |
44
+ | And you were able to do something |
45
+ | But you did do something |
46
+ | When I attempt to do something |
47
+ | And I attempt to do something |
48
+ | And I did do something |
49
+ | When you attempt to do something |
50
+ | And you attempt to do something |
51
+ | And you did do something |
52
+ | Then I should do something |
53
+ | And I should do something |
54
+ | Then you should do something |
55
+ | And you should do something |
@@ -0,0 +1,5 @@
1
+ require 'aruba/api'
2
+ #TODO: Consider wrapping Aruba
3
+ module StepFreeCuker
4
+ include Aruba::Api
5
+ end
@@ -0,0 +1,3 @@
1
+ in_order_to "CreateAFile", at: :path, containing: :content do
2
+ write_file( the(:path), the(:content ))
3
+ end
@@ -0,0 +1,11 @@
1
+ #TOOO: consider doing this as a feature since it's part of how you set up the project.
2
+ in_order_to "CreateANewCukeSaladProject" do
3
+ create_dir 'features'
4
+ create_dir 'features/support'
5
+ write_file 'features/support/env.rb', "$:.unshift(File.dirname(__FILE__) + '/../../../../lib') #where to find CukeSalad
6
+
7
+ require 'cukesalad'"
8
+ create_dir 'features/lib'
9
+ create_dir 'features/lib/roles'
10
+ create_dir 'features/lib/tasks'
11
+ end
@@ -0,0 +1,4 @@
1
+ #TODO: Consider exposing this detail in the examples since it shows you what to do
2
+ in_order_to 'create a role', called: :name_of_role do
3
+ write_file 'features/lib/roles/my_role.rb', "module #{the :name_of_role}\nend"
4
+ end
@@ -0,0 +1,4 @@
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"
4
+ end
@@ -0,0 +1,5 @@
1
+ in_order_to "CreateDirectories", as_follows: :several_directories do
2
+ the( :several_directories ).split( " " ).each do | path |
3
+ create_dir path
4
+ end
5
+ end
@@ -0,0 +1,2 @@
1
+ in_order_to "NotCreateARole" do # Nothing!
2
+ end
@@ -0,0 +1,3 @@
1
+ in_order_to 'not create a task' do
2
+ # Nothing
3
+ end
@@ -0,0 +1,4 @@
1
+ in_order_to "Run", the_command: :command do
2
+ run_simple unescape( the :command )
3
+ end
4
+
@@ -0,0 +1,7 @@
1
+ in_order_to "RunAScenario", containing: :step do
2
+ write_file 'features/a.feature', "Feature: A Feature
3
+
4
+ Scenario: A Scenario
5
+ #{the :step}"
6
+ run_simple unescape( 'cucumber features/a.feature' ), false
7
+ end
@@ -0,0 +1,3 @@
1
+ in_order_to "SeeAReply" do
2
+ all_output
3
+ end
@@ -0,0 +1,4 @@
1
+ in_order_to "SeeItHas" do
2
+ outcome = {1 => "failed", 0 => "passed"}
3
+ outcome[@last_exit_status]
4
+ end
@@ -0,0 +1,7 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../../lib') #where to find CukeSalad
2
+
3
+ require 'cukesalad'
4
+
5
+ After do
6
+ FileUtils.rm_rf 'tmp'
7
+ end
data/lib/actor.rb ADDED
@@ -0,0 +1,32 @@
1
+ require 'specifics'
2
+ require 'director'
3
+
4
+ class Actor
5
+ include Specifics
6
+
7
+ def initialize this_type_of_role, directed_by=Director.new
8
+ @director = directed_by
9
+ get_into_character_for this_type_of_role
10
+ end
11
+
12
+ def perform described_task, *details
13
+ get_ready_to_perform described_task
14
+ understand_the *details unless details.empty?
15
+ perform_task
16
+ end
17
+ alias :answer :perform
18
+
19
+ def get_into_character_for described_role
20
+ the_role = @director.explain_the_role described_role
21
+ see_how_to_do the_role
22
+ end
23
+
24
+ def get_ready_to_perform something
25
+ the_thing = @director.how_do_i_perform something
26
+ see_how_to_do the_thing
27
+ end
28
+
29
+ def see_how_to_do something
30
+ extend something
31
+ end
32
+ end
@@ -0,0 +1,21 @@
1
+ module Codify
2
+ module ConstName
3
+ def ConstName.from sentence
4
+ joined_together capitalised( words_from sentence )
5
+ end
6
+
7
+ private
8
+ def ConstName.joined_together words
9
+ words.join
10
+ end
11
+
12
+ def ConstName.words_from this_sentence
13
+ on_word_boundary = /\s|([A-Z][a-z]+)/
14
+ this_sentence.split( on_word_boundary )
15
+ end
16
+
17
+ def ConstName.capitalised words
18
+ words.collect{ | word | word.capitalize }
19
+ end
20
+ end
21
+ end
data/lib/cukesalad.rb ADDED
@@ -0,0 +1,33 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
2
+ require 'rubygems'
3
+ require 'bundler'
4
+ require 'actor'
5
+ require 'task_author'
6
+ Bundler.setup
7
+
8
+ When /^I say hello CukeSalad$/ do
9
+ puts "CukeSalad says: Hello!!"
10
+ end
11
+
12
+ Given /^(?:I am|you are) a ([a-zA-Z ]+)$/ do |role|
13
+ @actor = Actor.new(role)
14
+ end
15
+
16
+ When /^(?:I|you) (?:attempt to|was able to|were able to|did)? ([A-Z a-z_-]*)(?:: (.*))?$/ do | this_task, with_these_details, *and_more |
17
+ with_these_details ||= ""
18
+ with_these_details << " '#{and_more[0]}'" unless and_more.empty?
19
+ @actor.perform this_task, with_these_details unless with_these_details.nil?
20
+ @actor.perform this_task if with_these_details.nil?
21
+ end
22
+
23
+ Then /^(?:I|you) should ([^':]*)(?: '([^']*)')$/ do | this_question, expect_value |
24
+ @actor.answer( this_question ).to_s.should == expect_value
25
+ end
26
+
27
+ Then /^(?:I|you) should ([^':]+)$/ do | this_question |
28
+ @actor.answer( this_question )
29
+ end
30
+
31
+ Then /^(?:I|you) should ([^']*) that includes:$/ do | this_question, expected_content |
32
+ @actor.answer( this_question ).should include( expected_content )
33
+ end
data/lib/director.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'codify/const_name'
2
+ class Director
3
+
4
+ include Codify
5
+
6
+ #TODO: Needs refactoring
7
+ def explain_the_role description
8
+ name = ConstName.from description
9
+ begin
10
+ find_directives_for name
11
+ rescue NameError
12
+ raise "I can't find a role called '#{ name }'. Have you created it?\ne.g.\n module #{ name }\n end"
13
+ end
14
+ end
15
+
16
+ def how_do_i_perform something
17
+ name = ConstName.from something
18
+ begin
19
+ find_directives_for name
20
+ rescue NameError
21
+ 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"
22
+ end
23
+ end
24
+
25
+ def find_directives_for something
26
+ Kernel.const_get( something )
27
+ end
28
+ end
data/lib/specifics.rb ADDED
@@ -0,0 +1,30 @@
1
+ module Specifics
2
+ def understand_the details
3
+ @info = with_specifics_from( details )
4
+ end
5
+
6
+ def value_of(symbol)
7
+ @info[symbol]
8
+ end
9
+
10
+ def with_specifics_from details
11
+ result = {}
12
+ names_and_values_in(details).each_slice(2) do |name_value|
13
+ result[symbolized name_value[0]] = the_value_from_the name_value[1]
14
+ end
15
+ result
16
+ end
17
+
18
+ def names_and_values_in details
19
+ specifics_pattern = /('[^']+')/
20
+ details.split(specifics_pattern)
21
+ end
22
+
23
+ def symbolized name
24
+ name.strip.gsub(' ', '_').to_sym
25
+ end
26
+
27
+ def the_value_from_the item
28
+ item.gsub(/(^'|'$)/, '')
29
+ end
30
+ end
@@ -0,0 +1,12 @@
1
+ require 'codify/const_name'
2
+ def in_order_to do_something, *with_attributes, &actions
3
+ attr_map = with_attributes[0]
4
+ name = Codify::ConstName.from do_something
5
+ m = Module.new do
6
+ define_method :perform_task, &actions
7
+ define_method :the do | value |
8
+ value_of( attr_map.key value )
9
+ end
10
+ end
11
+ Kernel.const_set name, m
12
+ end