turnip 0.3.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/README.md +128 -166
  2. data/examples/autoload_steps.feature +3 -2
  3. data/examples/errors.feature +8 -0
  4. data/examples/step_calling.feature +2 -0
  5. data/examples/steps/alignment_steps.rb +23 -0
  6. data/examples/{autoload_steps.rb → steps/autoload_steps.rb} +0 -0
  7. data/examples/steps/backtick_steps.rb +10 -0
  8. data/examples/steps/dragon_steps.rb +41 -0
  9. data/examples/{knight_steps.rb → steps/knight_steps.rb} +3 -1
  10. data/examples/{more_steps.rb → steps/more_steps.rb} +0 -0
  11. data/examples/{step_calling_steps.rb → steps/step_calling_steps.rb} +0 -0
  12. data/examples/{steps.rb → steps/steps.rb} +25 -1
  13. data/examples/steps_for.feature +2 -2
  14. data/examples/steps_with_variations.feature +17 -0
  15. data/lib/turnip.rb +19 -34
  16. data/lib/turnip/builder.rb +26 -24
  17. data/lib/turnip/define.rb +9 -0
  18. data/lib/turnip/dsl.rb +11 -17
  19. data/lib/turnip/execute.rb +15 -0
  20. data/lib/turnip/rspec.rb +80 -0
  21. data/lib/turnip/step_definition.rb +7 -32
  22. data/lib/turnip/version.rb +1 -1
  23. data/spec/builder_spec.rb +1 -40
  24. data/spec/define_and_execute.rb +38 -0
  25. data/spec/dsl_spec.rb +36 -19
  26. data/spec/integration_spec.rb +5 -1
  27. data/spec/spec_helper.rb +1 -3
  28. data/spec/step_definition_spec.rb +37 -51
  29. metadata +25 -55
  30. data/examples/alignment_steps.rb +0 -7
  31. data/examples/backtick_steps.rb +0 -4
  32. data/examples/dragon_steps.rb +0 -17
  33. data/examples/evil_steps.rb +0 -7
  34. data/examples/neutral_steps.rb +0 -7
  35. data/examples/red_dragon_steps.rb +0 -18
  36. data/lib/turnip/config.rb +0 -18
  37. data/lib/turnip/feature_file.rb +0 -20
  38. data/lib/turnip/loader.rb +0 -16
  39. data/lib/turnip/runner_dsl.rb +0 -9
  40. data/lib/turnip/scenario_context.rb +0 -41
  41. data/lib/turnip/scenario_runner.rb +0 -35
  42. data/lib/turnip/step_loader.rb +0 -27
  43. data/lib/turnip/step_module.rb +0 -89
  44. data/spec/feature_file_spec.rb +0 -18
  45. data/spec/runner_dsl_spec.rb +0 -23
  46. data/spec/scenario_context_spec.rb +0 -51
  47. data/spec/scenario_runner_spec.rb +0 -79
  48. data/spec/step_loader_spec.rb +0 -29
  49. data/spec/step_module_spec.rb +0 -106
@@ -1,7 +0,0 @@
1
- steps_for :alignment do
2
- attr_accessor :alignment
3
-
4
- step "that alignment should be :alignment" do |expected_alignment|
5
- alignment.should eq(expected_alignment)
6
- end
7
- end
@@ -1,4 +0,0 @@
1
- step "I run `:cmd`" do |cmd|
2
- step('I attack it') if cmd == 'killall monsters'
3
- end
4
-
@@ -1,17 +0,0 @@
1
- steps_for :dragon do
2
- use_steps :knight
3
-
4
- attr_accessor :dragon
5
-
6
- def dragon_attack
7
- dragon * 10
8
- end
9
-
10
- step "there is a dragon" do
11
- self.dragon = 1
12
- end
13
-
14
- step "the dragon attacks the knight" do
15
- knight.attacked_for(dragon_attack)
16
- end
17
- end
@@ -1,7 +0,0 @@
1
- steps_for :evil do
2
- use_steps :alignment
3
-
4
- step "the monster has an alignment" do
5
- self.alignment = 'Evil'
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- steps_for :neutral do
2
- use_steps :alignment
3
-
4
- step "the monster has an alignment" do
5
- self.alignment = 'Neutral'
6
- end
7
- end
@@ -1,18 +0,0 @@
1
- steps_for :red_dragon do
2
- use_steps :dragon
3
-
4
- attr_accessor :red_dragon
5
-
6
- def dragon_attack
7
- attack = super
8
- if red_dragon
9
- attack + 15
10
- else
11
- attack
12
- end
13
- end
14
-
15
- step "the dragon breathes fire" do
16
- self.red_dragon = 1
17
- end
18
- end
@@ -1,18 +0,0 @@
1
- module Turnip
2
- module Config
3
- extend self
4
-
5
- attr_accessor :autotag_features
6
-
7
- def step_dirs
8
- @step_dirs ||= ['spec']
9
- end
10
-
11
- def step_dirs=(dirs)
12
- @step_dirs = [] unless @step_dirs
13
- @step_dirs.concat(Array(dirs))
14
- end
15
- end
16
- end
17
-
18
- Turnip::Config.autotag_features = true
@@ -1,20 +0,0 @@
1
- module Turnip
2
- class FeatureFile
3
- attr_accessor :file_name, :content, :feature_name
4
-
5
- def initialize(file_name)
6
- @file_name = file_name
7
- end
8
-
9
- def feature_name
10
- @feature_name ||= begin
11
- file = Pathname.new(file_name).basename.to_s
12
- file[0...file.index('.feature')]
13
- end
14
- end
15
-
16
- def content
17
- @content ||= File.read(file_name)
18
- end
19
- end
20
- end
@@ -1,16 +0,0 @@
1
- module Turnip
2
- module Loader
3
- def load(*a, &b)
4
- if a.first.end_with?('.feature')
5
- begin
6
- require 'spec_helper'
7
- rescue LoadError
8
- end
9
- Turnip::StepLoader.load_steps
10
- Turnip.run(Turnip::FeatureFile.new(a.first))
11
- else
12
- super
13
- end
14
- end
15
- end
16
- end
@@ -1,9 +0,0 @@
1
- module Turnip
2
- module RunnerDSL
3
- attr_accessor :turnip_runner
4
-
5
- def step(description, extra_arg = nil)
6
- turnip_runner.run_steps([Turnip::Builder::Step.new(description, extra_arg)])
7
- end
8
- end
9
- end
@@ -1,41 +0,0 @@
1
- module Turnip
2
- class ScenarioContext
3
- attr_accessor :feature
4
- attr_accessor :scenario
5
-
6
- def initialize(feature, scenario)
7
- self.feature = feature
8
- self.scenario = scenario
9
- end
10
-
11
- def available_background_steps
12
- available_steps_for(*feature_tags)
13
- end
14
-
15
- def available_scenario_steps
16
- available_steps_for(*scenario_tags)
17
- end
18
-
19
- def backgrounds
20
- feature.backgrounds
21
- end
22
-
23
- def modules
24
- Turnip::StepModule.modules_for(*scenario_tags)
25
- end
26
-
27
- private
28
-
29
- def available_steps_for(*tags)
30
- Turnip::StepModule.all_steps_for(*tags)
31
- end
32
-
33
- def feature_tags
34
- @feature_tags ||= feature.active_tags.uniq
35
- end
36
-
37
- def scenario_tags
38
- @scenario_tags ||= (feature_tags + scenario.active_tags).uniq
39
- end
40
- end
41
- end
@@ -1,35 +0,0 @@
1
- module Turnip
2
- class ScenarioRunner
3
- attr_accessor :available_steps
4
- attr_accessor :context
5
- attr_accessor :world
6
-
7
- def initialize(world)
8
- self.world = world
9
- end
10
-
11
- def load(context)
12
- self.context = context
13
- world.extend Turnip::RunnerDSL
14
- world.turnip_runner = self
15
- context.modules.each {|mod| world.extend mod }
16
- self
17
- end
18
-
19
- def run
20
- self.available_steps = context.available_background_steps
21
- context.backgrounds.each do |background|
22
- run_steps(background.steps)
23
- end
24
-
25
- self.available_steps = context.available_scenario_steps
26
- run_steps(context.scenario.steps)
27
- end
28
-
29
- def run_steps(steps)
30
- steps.each do |step|
31
- Turnip::StepDefinition.execute(world, available_steps, step)
32
- end
33
- end
34
- end
35
- end
@@ -1,27 +0,0 @@
1
- module Turnip
2
- module StepLoader
3
- extend self
4
-
5
- attr_accessor :steps_loaded
6
-
7
- def load_steps
8
- return if steps_loaded?
9
- load_step_files
10
- self.steps_loaded = true
11
- end
12
-
13
- def steps_loaded?
14
- @steps_loaded
15
- end
16
-
17
- private
18
-
19
- def load_step_files
20
- Turnip::Config.step_dirs.each do |dir|
21
- Pathname.glob(Pathname.new(dir) + '**' + "*steps.rb").each do |step_file|
22
- load step_file, true
23
- end
24
- end
25
- end
26
- end
27
- end
@@ -1,89 +0,0 @@
1
- require 'pathname'
2
-
3
- module Turnip
4
- module StepModule
5
- module DSL
6
- def placeholder(name, &block)
7
- Turnip::Placeholder.add(name, &block)
8
- end
9
-
10
- def step(description, &block)
11
- steps << Turnip::StepDefinition.new(description, &block)
12
- end
13
-
14
- def steps
15
- @steps ||= []
16
- end
17
-
18
- def use_steps(*tags)
19
- uses_steps.concat(tags)
20
- end
21
-
22
- def uses_steps
23
- @uses_steps ||= []
24
- end
25
- end
26
-
27
- class Entry < Struct.new(:for_tag, :step_module, :uses_steps)
28
- def all_modules(already_visited = [])
29
- if already_visited.include?(for_tag)
30
- []
31
- else
32
- already_visited << for_tag
33
- uses_modules(already_visited) << step_module
34
- end
35
- end
36
-
37
- def uses_modules(already_visited)
38
- uses_steps.map do |uses_tag|
39
- StepModule.module_registry[uses_tag].map do |entry|
40
- entry.all_modules(already_visited)
41
- end
42
- end.flatten.uniq
43
- end
44
- end
45
-
46
- extend self
47
-
48
- def all_steps_for(*taggings)
49
- modules_for(*taggings).map do |step_module|
50
- step_module.steps
51
- end.flatten
52
- end
53
-
54
- def clear_module_registry
55
- module_registry.clear
56
- end
57
-
58
- def modules_for(*taggings)
59
- taggings.map do |tag|
60
- module_registry[tag].map do |entry|
61
- entry.all_modules
62
- end
63
- end.flatten.uniq
64
- end
65
-
66
- def module_registry
67
- @module_registry ||= Hash.new { |hash, key| hash[key] = [] }
68
- end
69
-
70
- def registered?(module_name)
71
- module_registry.has_key? module_name
72
- end
73
-
74
- def steps_for(tag, &block)
75
- anon = step_module(&block)
76
-
77
- entry = Entry.new(tag, anon, anon.uses_steps)
78
-
79
- module_registry[tag] << entry
80
- end
81
-
82
- def step_module(&block)
83
- anon = Module.new
84
- anon.extend(Turnip::StepModule::DSL)
85
- anon.module_eval(&block)
86
- anon
87
- end
88
- end
89
- end
@@ -1,18 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Turnip::FeatureFile do
4
- let(:file_name) {File.expand_path('../examples/with_comments.feature', File.dirname(__FILE__))}
5
- let(:feature_file) {Turnip::FeatureFile.new(file_name)}
6
-
7
- describe '.feature_name' do
8
- it 'allows access to short name for the feature based on the file name' do
9
- feature_file.feature_name.should == 'with_comments'
10
- end
11
- end
12
-
13
- describe '.content' do
14
- it 'allows access to the content in the feature file' do
15
- feature_file.content.should be
16
- end
17
- end
18
- end
@@ -1,23 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Turnip::RunnerDSL do
4
- describe '#step' do
5
- include Turnip::RunnerDSL
6
-
7
- it 'runs the step' do
8
- self.turnip_runner = Class.new do
9
- attr_accessor :args
10
- def run_steps(steps)
11
- self.args << steps
12
- end
13
- end.new
14
- self.turnip_runner.args = []
15
-
16
- step('description', 'extra_arg')
17
- step = turnip_runner.args.flatten.first
18
- step.should be_kind_of(Turnip::Builder::Step)
19
- step.description.should eq('description')
20
- step.extra_arg.should eq('extra_arg')
21
- end
22
- end
23
- end
@@ -1,51 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Turnip::ScenarioContext do
4
- let(:context) { Turnip::ScenarioContext.new(feature, scenario) }
5
- let(:feature) { stub(:active_tags => feature_tags) }
6
- let(:feature_tags) { %w(feature both) }
7
- let(:scenario) { stub(:active_tags => scenario_tags) }
8
- let(:scenario_tags) { %w(scenario both) }
9
- let(:unique_tags) { (feature_tags + scenario_tags).uniq }
10
-
11
- describe '#initialize' do
12
- let(:feature) { stub }
13
- let(:scenario) { stub }
14
-
15
- it 'keeps track of the feature' do
16
- Turnip::ScenarioContext.new(feature, scenario).feature.should eq(feature)
17
- end
18
-
19
- it 'keeps track of the scenario' do
20
- Turnip::ScenarioContext.new(feature, scenario).scenario.should eq(scenario)
21
- end
22
- end
23
-
24
- describe '#available_background_steps' do
25
- it 'gathers the steps for the feature tags' do
26
- Turnip::StepModule.should_receive(:all_steps_for).with(*feature_tags)
27
- context.available_background_steps
28
- end
29
- end
30
-
31
- describe '#available_scenario_steps' do
32
- it 'gathers the steps for the unique scenario and feature tags' do
33
- Turnip::StepModule.should_receive(:all_steps_for).with(*unique_tags)
34
- context.available_scenario_steps
35
- end
36
- end
37
-
38
- describe '#backgrounds' do
39
- it 'delegates to the feature' do
40
- feature.should_receive :backgrounds
41
- context.backgrounds
42
- end
43
- end
44
-
45
- describe '#modules' do
46
- it 'gathers the modules for the unique scenario and feature tags' do
47
- Turnip::StepModule.should_receive(:modules_for).with(*unique_tags)
48
- context.modules
49
- end
50
- end
51
- end
@@ -1,79 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Turnip::ScenarioRunner do
4
- let(:runner) { Turnip::ScenarioRunner.new(world) }
5
- let(:world) { Object.new }
6
-
7
- describe '#initialize' do
8
- it 'keeps track of the world' do
9
- Turnip::ScenarioRunner.new(world).world.should eq(world)
10
- end
11
- end
12
-
13
- describe '#load' do
14
- let(:context) { stub(:modules => [some_module]) }
15
- let(:some_module) { Module.new }
16
-
17
- it 'is chainable' do
18
- runner.load(context).should eq(runner)
19
- end
20
-
21
- it 'keeps track of the scenario context' do
22
- runner.load(context).context.should eq(context)
23
- end
24
-
25
- it 'loads the given modules into the world' do
26
- runner.load(context).world.should be_kind_of(some_module)
27
- end
28
-
29
- it 'loads the DSL module into the world' do
30
- runner.load(context).world.should be_kind_of(Turnip::RunnerDSL)
31
- end
32
-
33
- it 'adds the runner to the world' do
34
- runner.load(context).world.turnip_runner.should eq(runner)
35
- end
36
- end
37
-
38
- describe '#run' do
39
- it 'iterates over the background steps' do
40
- runner.context = stub(:backgrounds => (0..2).map { stub(:steps => [stub]) },
41
- :available_background_steps => [],
42
- :available_scenario_steps => [],
43
- :scenario => stub(:steps => []))
44
-
45
- Turnip::StepDefinition.should_receive(:execute).exactly(3).times
46
- runner.run
47
- end
48
-
49
- it 'iterates over the scenario steps' do
50
- runner.context = stub(:backgrounds => [],
51
- :available_background_steps => [],
52
- :available_scenario_steps => [],
53
- :scenario => stub(:steps => (0..3)))
54
-
55
- Turnip::StepDefinition.should_receive(:execute).exactly(4).times
56
- runner.run
57
- end
58
- end
59
-
60
- describe '#run_steps' do
61
- let(:available_steps) { stub }
62
-
63
- it 'executes the steps with the current world' do
64
- step = stub
65
- steps = [step]
66
- runner.available_steps = available_steps
67
-
68
- Turnip::StepDefinition.should_receive(:execute).with(world, available_steps, step)
69
- runner.run_steps(steps)
70
- end
71
-
72
- it 'iterates over the steps' do
73
- steps = (0..2)
74
-
75
- Turnip::StepDefinition.should_receive(:execute).exactly(3).times
76
- runner.run_steps(steps)
77
- end
78
- end
79
- end