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.
- 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
|