cukesalad 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/Examples/Calculator/Gemfile +5 -0
- data/Examples/Calculator/Gemfile.lock +66 -0
- data/Examples/Calculator/cucumber.yml +4 -0
- data/Examples/Calculator/features/LOOK_MA_NO_STEP_DEFS.txt +2 -0
- data/Examples/Calculator/features/a_place_to_start.feature +9 -0
- data/Examples/Calculator/features/addition.feature +19 -0
- data/Examples/Calculator/features/complex_calculations.feature +16 -0
- data/Examples/Calculator/features/lib/alternative/roles/calculating_web_user.rb +55 -0
- data/Examples/Calculator/features/lib/default/roles/calculating_individual.rb +32 -0
- data/Examples/Calculator/features/lib/default/tasks/add.rb +13 -0
- data/Examples/Calculator/features/lib/default/tasks/calculate.rb +4 -0
- data/Examples/Calculator/features/lib/default/tasks/calculations.rb +15 -0
- data/Examples/Calculator/features/lib/default/tasks/see_the_answer.rb +3 -0
- data/Examples/Calculator/features/lib/default/tasks/subtract.rb +4 -0
- data/Examples/Calculator/features/lib/default/tasks/switch_on_the_calculator.rb +9 -0
- data/Examples/Calculator/features/subtraction.feature +20 -0
- data/Examples/Calculator/features/support/env.rb +6 -0
- data/Examples/Calculator/features/typical_workflow.feature +18 -0
- data/Examples/Calculator/lib/calculator.rb +53 -0
- data/Examples/Calculator/lib/config.ru +4 -0
- data/Examples/Calculator/lib/web_calculator.rb +82 -0
- data/Examples/Calculator/spec/calculator_spec.rb +73 -0
- data/Examples/Calculator/spec/web_calculator_spec.rb +99 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +47 -0
- data/LICENSE +21 -0
- data/README.md +273 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/bin/cukesalad +28 -0
- data/cucumber.yml +4 -0
- data/cukesalad/cli.rb +68 -0
- data/examples/Calculator/features/lib/alternative/roles/calculating_web_user.rb +55 -0
- data/examples/Calculator/features/lib/default/roles/calculating_individual.rb +32 -0
- data/examples/Calculator/features/lib/default/tasks/add.rb +13 -0
- data/examples/Calculator/features/lib/default/tasks/calculate.rb +4 -0
- data/examples/Calculator/features/lib/default/tasks/calculations.rb +15 -0
- data/examples/Calculator/features/lib/default/tasks/see_the_answer.rb +3 -0
- data/examples/Calculator/features/lib/default/tasks/subtract.rb +4 -0
- data/examples/Calculator/features/lib/default/tasks/switch_on_the_calculator.rb +9 -0
- data/examples/Calculator/features/support/env.rb +6 -0
- data/examples/Calculator/lib/calculator.rb +53 -0
- data/examples/Calculator/lib/web_calculator.rb +82 -0
- data/examples/Calculator/spec/calculator_spec.rb +73 -0
- data/examples/Calculator/spec/web_calculator_spec.rb +99 -0
- data/features/a_new_cukesalad_project.feature +34 -0
- data/features/define_a_role.feature +31 -0
- data/features/define_a_task.feature +55 -0
- data/features/lib/roles/step_free_cuker.rb +5 -0
- data/features/lib/tasks/create_a_file.rb +3 -0
- data/features/lib/tasks/create_a_new_cukesalad_project.rb +11 -0
- data/features/lib/tasks/create_a_role.rb +4 -0
- data/features/lib/tasks/create_a_task.rb +4 -0
- data/features/lib/tasks/create_directories.rb +5 -0
- data/features/lib/tasks/not_create_a_role.rb +2 -0
- data/features/lib/tasks/not_create_a_task.rb +3 -0
- data/features/lib/tasks/run.rb +4 -0
- data/features/lib/tasks/run_a_scenario.rb +7 -0
- data/features/lib/tasks/see_a_reply.rb +3 -0
- data/features/lib/tasks/see_the_step_has.rb +4 -0
- data/features/support/env.rb +7 -0
- data/lib/actor.rb +32 -0
- data/lib/codify/const_name.rb +21 -0
- data/lib/cukesalad.rb +33 -0
- data/lib/director.rb +28 -0
- data/lib/specifics.rb +30 -0
- data/lib/task_author.rb +12 -0
- data/spec/actor_spec.rb +72 -0
- data/spec/codify/as_const_name_spec.rb +28 -0
- data/spec/cukesalad/cli_spec.rb +99 -0
- data/spec/director_spec.rb +34 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/specifics_spec.rb +36 -0
- data/spec/task_author_spec.rb +50 -0
- 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,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
|
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
|
data/lib/task_author.rb
ADDED
@@ -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
|