allure_turnip 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +54 -0
- data/README.md +68 -0
- data/allure_turnip.gemspec +27 -0
- data/lib/allure_turnip.rb +64 -0
- data/lib/allure_turnip/adaptor.rb +15 -0
- data/lib/allure_turnip/dsl.rb +73 -0
- data/lib/allure_turnip/formatter.rb +143 -0
- data/lib/allure_turnip/hooks.rb +86 -0
- data/lib/allure_turnip/turnip_extension.rb +17 -0
- data/lib/allure_turnip/version.rb +5 -0
- data/logo.png +0 -0
- data/spec/ambiguous.feature +3 -0
- data/spec/attach_file.feature +3 -0
- data/spec/autoload_steps.feature +6 -0
- data/spec/backgrounds.feature +6 -0
- data/spec/blank.feature +1 -0
- data/spec/errors.feature +11 -0
- data/spec/interpolation.feature +21 -0
- data/spec/multiline_string.feature +8 -0
- data/spec/pending.feature +3 -0
- data/spec/scenario_outline.feature +10 -0
- data/spec/scenario_outline_multiline_string_substitution.feature +13 -0
- data/spec/scenario_outline_table_substitution.feature +12 -0
- data/spec/simple_feature.feature +5 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/step_calling.feature +16 -0
- data/spec/steps/alignment_steps.rb +23 -0
- data/spec/steps/autoload_steps.rb +5 -0
- data/spec/steps/backtick_steps.rb +10 -0
- data/spec/steps/dragon_steps.rb +41 -0
- data/spec/steps/knight_steps.rb +31 -0
- data/spec/steps/more_steps.rb +7 -0
- data/spec/steps/step_calling_steps.rb +23 -0
- data/spec/steps/steps.rb +132 -0
- data/spec/steps_for.feature +10 -0
- data/spec/steps_for_super.feature +16 -0
- data/spec/steps_with_variations.feature +17 -0
- data/spec/table.feature +8 -0
- data/spec/tags.feature +14 -0
- data/spec/with_backticks.feature +5 -0
- data/spec/with_comments.feature +12 -0
- metadata +187 -0
@@ -0,0 +1,86 @@
|
|
1
|
+
module AllureTurnip
|
2
|
+
module Hooks
|
3
|
+
|
4
|
+
def self.included(cls)
|
5
|
+
cls.extend OverrideHooksMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module OverrideHooksMethods
|
9
|
+
include RSpec::Core::Hooks
|
10
|
+
|
11
|
+
alias_method :old_hooks, :hooks
|
12
|
+
|
13
|
+
def hooks
|
14
|
+
@__hooks ||= OverridenHookCollections.new(old_hooks)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
class OverridenHookCollections < RSpec::Core::Hooks::HookCollections
|
20
|
+
def initialize(original)
|
21
|
+
super(original.instance_eval("@owner"), original.instance_eval("@filterable_item_repo_class"))
|
22
|
+
[:@before_example_hooks, :@after_example_hooks, :@before_context_hooks, :@after_context_hooks, :@around_example_hooks].each { |var|
|
23
|
+
instance_variable_set(var, original.instance_eval("#{var}"))
|
24
|
+
}
|
25
|
+
@before_step_hooks = nil
|
26
|
+
@after_step_hooks = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def run(position, scope, example_or_group)
|
30
|
+
if scope == :step
|
31
|
+
run_owned_hooks_for(position, scope, example_or_group)
|
32
|
+
else
|
33
|
+
super
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
|
39
|
+
# TODO: This code is highly related to the RSpec internals.
|
40
|
+
# It should be supported with every new RSpec version
|
41
|
+
def matching_hooks_for(position, scope, example_or_group)
|
42
|
+
if scope == :step
|
43
|
+
repo = hooks_for(position, scope) || example_or_group.example_group.hooks.hooks_for(position, scope)
|
44
|
+
metadata = case example_or_group
|
45
|
+
when RSpec::Core::ExampleGroup then
|
46
|
+
example_or_group.class.metadata
|
47
|
+
else
|
48
|
+
example_or_group.metadata
|
49
|
+
end
|
50
|
+
repo.nil? ? EMPTY_HOOK_ARRAY : repo.items_for(metadata)
|
51
|
+
else
|
52
|
+
super
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def hooks_for(position, scope)
|
57
|
+
if scope == :step
|
58
|
+
position == :before ? @before_step_hooks : @after_step_hooks
|
59
|
+
else
|
60
|
+
super
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def ensure_hooks_initialized_for(position, scope)
|
65
|
+
if scope == :step
|
66
|
+
if position == :before
|
67
|
+
@before_step_hooks ||= @filterable_item_repo_class.new(:all?)
|
68
|
+
else
|
69
|
+
@after_step_hooks ||= @filterable_item_repo_class.new(:all?)
|
70
|
+
end
|
71
|
+
else
|
72
|
+
super
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
SCOPES = [:example, :context, :step]
|
77
|
+
|
78
|
+
def known_scope?(scope)
|
79
|
+
SCOPES.include?(scope) || super(scope)
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Turnip
|
2
|
+
module Execute
|
3
|
+
|
4
|
+
alias original_step step
|
5
|
+
|
6
|
+
def step(step_or_description, *extra_args)
|
7
|
+
# can use attach_file method in step.
|
8
|
+
def self.attach_file(title, file, opts = {})
|
9
|
+
::RSpec.current_example.attach_file(title, file, opts)
|
10
|
+
end
|
11
|
+
|
12
|
+
::RSpec.current_example.allure_step(step_or_description) do
|
13
|
+
original_step(step_or_description, *extra_args)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/logo.png
ADDED
Binary file
|
data/spec/blank.feature
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# no feature file
|
data/spec/errors.feature
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
Feature: raises errors
|
2
|
+
Scenario: Step missing
|
3
|
+
When a step just does not exist
|
4
|
+
Scenario: Step raises error
|
5
|
+
When raise error
|
6
|
+
Scenario: Incorrect expectation
|
7
|
+
Given there is a monster
|
8
|
+
Then it should die
|
9
|
+
@raise_error_for_unimplemented_steps
|
10
|
+
Scenario: Step missing and raise_error_for_unimplemented_steps is set
|
11
|
+
When a step just does not exist
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Feature: A simple feature
|
2
|
+
Scenario: Interpolation with quotes
|
3
|
+
Given there is a monster called "John Smith"
|
4
|
+
Then it should be called "John Smith"
|
5
|
+
|
6
|
+
Scenario: Interpolation with empty quotes
|
7
|
+
Given there is a monster called "John Smith"
|
8
|
+
When I change its name to ""
|
9
|
+
Then it should be nameless
|
10
|
+
|
11
|
+
Scenario: Interpolation without quotes
|
12
|
+
Given there is a monster called John
|
13
|
+
Then it should be called "John"
|
14
|
+
|
15
|
+
Scenario: Interpolation with mixed quotes
|
16
|
+
Given there is a monster called "O'Flannahan"
|
17
|
+
Then it should be called "O'Flannahan"
|
18
|
+
|
19
|
+
Scenario: Interpolation with customer regexp
|
20
|
+
Given there are 3 monkeys with blue hair
|
21
|
+
Then there should be 3 monkeys with blue hair
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Feature: using scenario outlines
|
2
|
+
Scenario Outline: a simple outline
|
3
|
+
Given there is a monster with <hp> hitpoints
|
4
|
+
When I attack the monster and do <damage> points damage
|
5
|
+
Then the monster should be <state>
|
6
|
+
|
7
|
+
Examples:
|
8
|
+
| hp | damage | state |
|
9
|
+
| 10 | 13 | dead |
|
10
|
+
| 8 | 5 | alive |
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Feature: using scenario outlines
|
2
|
+
Scenario Outline: a simple outline
|
3
|
+
Given there is a monster called <name>
|
4
|
+
Then the monster introduced himself:
|
5
|
+
"""
|
6
|
+
Ahhhhhhh! i'm <name>!
|
7
|
+
"""
|
8
|
+
|
9
|
+
Examples:
|
10
|
+
| name |
|
11
|
+
| John |
|
12
|
+
| "John Smith" |
|
13
|
+
| "O'Flannahan" |
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Feature: using scenario outlines
|
2
|
+
Scenario Outline: a simple outline
|
3
|
+
Given there is a monster with hitpoints:
|
4
|
+
| hit_points |
|
5
|
+
| <hp> |
|
6
|
+
When I attack the monster and do <damage> points damage
|
7
|
+
Then the monster should be <state>
|
8
|
+
|
9
|
+
Examples:
|
10
|
+
| hp | damage | state |
|
11
|
+
| 10 | 13 | dead |
|
12
|
+
| 8 | 5 | alive |
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'allure_turnip'
|
3
|
+
require 'nokogiri'
|
4
|
+
require 'turnip'
|
5
|
+
|
6
|
+
Dir.glob("spec/steps/**/*steps.rb") { |f| load f, true }
|
7
|
+
|
8
|
+
RSpec.configure do |c|
|
9
|
+
c.include AllureTurnip::Adaptor
|
10
|
+
c.before(:suite) do
|
11
|
+
puts 'Before Suite Spec helper'
|
12
|
+
end
|
13
|
+
|
14
|
+
c.before(:all) do
|
15
|
+
puts 'Before all Spec helper'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
AllureTurnip.configure do |c|
|
20
|
+
c.output_dir = "allure"
|
21
|
+
c.feature_with_filename = true
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
@step_calling
|
2
|
+
Feature: Step-calling steps
|
3
|
+
|
4
|
+
@wip
|
5
|
+
Scenario: when the called step is visible
|
6
|
+
Given a visible step call
|
7
|
+
|
8
|
+
Scenario: when the called step is not visible
|
9
|
+
Given an invisible step call
|
10
|
+
|
11
|
+
Scenario: when the called step is global
|
12
|
+
Given a global step call
|
13
|
+
|
14
|
+
@autoload_steps
|
15
|
+
Scenario: when the called step is included via tag
|
16
|
+
Given an included call
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Alignment
|
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
|
8
|
+
|
9
|
+
steps_for :evil do
|
10
|
+
include Alignment
|
11
|
+
|
12
|
+
step "the monster has an alignment" do
|
13
|
+
self.alignment = 'Evil'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
steps_for :neutral do
|
18
|
+
include Alignment
|
19
|
+
|
20
|
+
step "the monster has an alignment" do
|
21
|
+
self.alignment = 'Neutral'
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative "knight_steps"
|
2
|
+
|
3
|
+
module DragonSteps
|
4
|
+
include KnightSteps
|
5
|
+
|
6
|
+
attr_accessor :dragon
|
7
|
+
|
8
|
+
def dragon_attack
|
9
|
+
dragon * 10
|
10
|
+
end
|
11
|
+
|
12
|
+
step "there is a dragon" do
|
13
|
+
self.dragon = 1
|
14
|
+
end
|
15
|
+
|
16
|
+
step "the dragon attacks the knight" do
|
17
|
+
knight.attacked_for(dragon_attack)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module RedDragonSteps
|
22
|
+
include DragonSteps
|
23
|
+
|
24
|
+
attr_accessor :red_dragon
|
25
|
+
|
26
|
+
def dragon_attack
|
27
|
+
attack = super
|
28
|
+
if red_dragon
|
29
|
+
attack + 15
|
30
|
+
else
|
31
|
+
attack
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
step "the dragon breathes fire" do
|
36
|
+
self.red_dragon = 1
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
RSpec.configure { |c| c.include DragonSteps, :dragon => true }
|
41
|
+
RSpec.configure { |c| c.include RedDragonSteps, :red_dragon => true }
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module KnightSteps
|
2
|
+
attr_accessor :knight
|
3
|
+
|
4
|
+
class Knight
|
5
|
+
def initialize
|
6
|
+
@hp = 20
|
7
|
+
end
|
8
|
+
|
9
|
+
def alive?
|
10
|
+
@hp > 0
|
11
|
+
end
|
12
|
+
|
13
|
+
def attacked_for(amount)
|
14
|
+
@hp -= amount
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
step "there is a knight" do
|
19
|
+
self.knight = Knight.new
|
20
|
+
end
|
21
|
+
|
22
|
+
step "the knight is alive" do
|
23
|
+
knight.should be_alive
|
24
|
+
end
|
25
|
+
|
26
|
+
step "the knight is dead" do
|
27
|
+
knight.should_not be_alive
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
RSpec.configure { |c| c.include KnightSteps, :knight => true }
|
@@ -0,0 +1,23 @@
|
|
1
|
+
steps_for :step_calling do
|
2
|
+
step 'visible callee' do
|
3
|
+
@testing = 123
|
4
|
+
end
|
5
|
+
|
6
|
+
step 'a visible step call' do
|
7
|
+
step 'visible callee'
|
8
|
+
@testing.should eq(123)
|
9
|
+
end
|
10
|
+
|
11
|
+
step 'an invisible step call' do
|
12
|
+
step 'this is an unimplemented step'
|
13
|
+
end
|
14
|
+
|
15
|
+
step 'a global step call' do
|
16
|
+
step 'there is a monster'
|
17
|
+
@monster.should == 1
|
18
|
+
end
|
19
|
+
|
20
|
+
step 'an included call' do
|
21
|
+
step 'an auto-loaded step is available'
|
22
|
+
end
|
23
|
+
end
|
data/spec/steps/steps.rb
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
3
|
+
step "there is a monster" do
|
4
|
+
@monster = 1
|
5
|
+
end
|
6
|
+
|
7
|
+
step "there is a strong monster" do
|
8
|
+
@monster = 2
|
9
|
+
end
|
10
|
+
|
11
|
+
step "I attack it" do
|
12
|
+
@monster -= 1
|
13
|
+
end
|
14
|
+
|
15
|
+
step "it should die" do
|
16
|
+
@monster.should eq(0)
|
17
|
+
end
|
18
|
+
|
19
|
+
step "this is ambiguous" do
|
20
|
+
end
|
21
|
+
|
22
|
+
step "this is :ambiguous" do
|
23
|
+
end
|
24
|
+
|
25
|
+
step "there is a monster called :name" do |name|
|
26
|
+
@monster_name = name
|
27
|
+
end
|
28
|
+
|
29
|
+
step 'it should be called "John Smith"' do
|
30
|
+
@monster_name.should == "John Smith"
|
31
|
+
end
|
32
|
+
|
33
|
+
step 'it should be called "John"' do
|
34
|
+
@monster_name.should == "John"
|
35
|
+
end
|
36
|
+
|
37
|
+
step 'it should be called "O\'Flannahan"' do
|
38
|
+
@monster_name.should == "O'Flannahan"
|
39
|
+
end
|
40
|
+
|
41
|
+
step "I change its name to :empty_string" do |empty_string|
|
42
|
+
@monster_name = empty_string
|
43
|
+
end
|
44
|
+
|
45
|
+
step "it should be nameless" do
|
46
|
+
@monster_name.should == ""
|
47
|
+
end
|
48
|
+
|
49
|
+
step "the monster introduced himself:" do |self_introduction|
|
50
|
+
self_introduction.should include @monster_name
|
51
|
+
end
|
52
|
+
|
53
|
+
step "there is a monster with :count hitpoints" do |count|
|
54
|
+
@monster = count
|
55
|
+
end
|
56
|
+
|
57
|
+
step "I attack the monster and do :count points damage" do |count|
|
58
|
+
@monster -= count
|
59
|
+
end
|
60
|
+
|
61
|
+
step "the monster should be alive" do
|
62
|
+
@monster.should > 0
|
63
|
+
end
|
64
|
+
|
65
|
+
step "the monster should be dead" do
|
66
|
+
@monster.should <= 0
|
67
|
+
end
|
68
|
+
|
69
|
+
step "there are the following monsters:" do |table|
|
70
|
+
$monsters = {}
|
71
|
+
table.hashes.each do |hash|
|
72
|
+
$monsters[hash['Name']] = hash['Hitpoints'].to_i
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
step ":monster should have :count hitpoints" do |monster, count|
|
77
|
+
monster.should eq(count.to_i)
|
78
|
+
end
|
79
|
+
|
80
|
+
step "the monster sings the following song" do |song|
|
81
|
+
@song = song
|
82
|
+
end
|
83
|
+
|
84
|
+
step "the song should have :count lines" do |count|
|
85
|
+
@song.to_s.split("\n").length.should eq(count)
|
86
|
+
end
|
87
|
+
|
88
|
+
step "it should be strong/tough" do
|
89
|
+
@monster.should >= 2
|
90
|
+
end
|
91
|
+
|
92
|
+
step "it should be (a) badass" do
|
93
|
+
@monster.should >= 2
|
94
|
+
end
|
95
|
+
|
96
|
+
step "it should be (a) badass" do
|
97
|
+
@monster.should >= 2
|
98
|
+
end
|
99
|
+
|
100
|
+
step "it should be terrible(st)" do
|
101
|
+
@monster.should >= 2
|
102
|
+
end
|
103
|
+
|
104
|
+
step "it (should) have/has :count (terrifying) hitpoint(s)" do |count|
|
105
|
+
@monster.should == count
|
106
|
+
end
|
107
|
+
|
108
|
+
step "raise error" do
|
109
|
+
raise "foobar"
|
110
|
+
end
|
111
|
+
|
112
|
+
step 'attach file' do
|
113
|
+
attach_file "test-file1", Tempfile.new("test")
|
114
|
+
end
|
115
|
+
|
116
|
+
placeholder :count do
|
117
|
+
match (/\d+/) do |count|
|
118
|
+
count.to_i
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
placeholder :color do
|
123
|
+
match (/blue|green|red/) do |color|
|
124
|
+
color.to_sym
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
placeholder :monster do
|
129
|
+
default do |name|
|
130
|
+
$monsters[name]
|
131
|
+
end
|
132
|
+
end
|