allure_turnip 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +3 -0
  5. data/Gemfile.lock +54 -0
  6. data/README.md +68 -0
  7. data/allure_turnip.gemspec +27 -0
  8. data/lib/allure_turnip.rb +64 -0
  9. data/lib/allure_turnip/adaptor.rb +15 -0
  10. data/lib/allure_turnip/dsl.rb +73 -0
  11. data/lib/allure_turnip/formatter.rb +143 -0
  12. data/lib/allure_turnip/hooks.rb +86 -0
  13. data/lib/allure_turnip/turnip_extension.rb +17 -0
  14. data/lib/allure_turnip/version.rb +5 -0
  15. data/logo.png +0 -0
  16. data/spec/ambiguous.feature +3 -0
  17. data/spec/attach_file.feature +3 -0
  18. data/spec/autoload_steps.feature +6 -0
  19. data/spec/backgrounds.feature +6 -0
  20. data/spec/blank.feature +1 -0
  21. data/spec/errors.feature +11 -0
  22. data/spec/interpolation.feature +21 -0
  23. data/spec/multiline_string.feature +8 -0
  24. data/spec/pending.feature +3 -0
  25. data/spec/scenario_outline.feature +10 -0
  26. data/spec/scenario_outline_multiline_string_substitution.feature +13 -0
  27. data/spec/scenario_outline_table_substitution.feature +12 -0
  28. data/spec/simple_feature.feature +5 -0
  29. data/spec/spec_helper.rb +23 -0
  30. data/spec/step_calling.feature +16 -0
  31. data/spec/steps/alignment_steps.rb +23 -0
  32. data/spec/steps/autoload_steps.rb +5 -0
  33. data/spec/steps/backtick_steps.rb +10 -0
  34. data/spec/steps/dragon_steps.rb +41 -0
  35. data/spec/steps/knight_steps.rb +31 -0
  36. data/spec/steps/more_steps.rb +7 -0
  37. data/spec/steps/step_calling_steps.rb +23 -0
  38. data/spec/steps/steps.rb +132 -0
  39. data/spec/steps_for.feature +10 -0
  40. data/spec/steps_for_super.feature +16 -0
  41. data/spec/steps_with_variations.feature +17 -0
  42. data/spec/table.feature +8 -0
  43. data/spec/tags.feature +14 -0
  44. data/spec/with_backticks.feature +5 -0
  45. data/spec/with_comments.feature +12 -0
  46. metadata +187 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ca1aa10aa83c24d6d56bc9f3e1888bc775de1b050a3c338951932e2d33d3cd8a
4
+ data.tar.gz: 76c304a7fe8836de50bfd89005d077ca0c31f5cd0496b6cbeeadfaa2ea730b97
5
+ SHA512:
6
+ metadata.gz: 5ab5374519296e590373cd7582c50a3d2f6511e4e740489d09c62983d3bf43e56243c6b70488578fa51f6d0eaf34e08af1404422f795e47ccef021041b4746e3
7
+ data.tar.gz: 3688674f916a7b16d2517c09f6bcf57e52bbf3388c36c090ccec4261b6253aa23a157d6246cf09df1ceea9082b08a5d3732fe172ab8a637a53a9b451674f41f4
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ *.class
2
+
3
+ # Package Files #
4
+ *.jar
5
+ *.war
6
+ *.ear
7
+ *.gem
8
+
9
+ allure-report
10
+ target
11
+ allure
12
+ .idea
13
+ *.iml
14
+ *.ipr
15
+ *.iws
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ -r turnip/rspec
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,54 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ allure_turnip (0.1.0)
5
+ allure-ruby-adaptor-api (= 0.7.0)
6
+ rspec (~> 3.5)
7
+ turnip (~> 3.0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ allure-ruby-adaptor-api (0.7.0)
13
+ mimemagic
14
+ nokogiri (~> 1.7)
15
+ uuid
16
+ diff-lcs (1.3)
17
+ gherkin (5.1.0)
18
+ macaddr (1.7.1)
19
+ systemu (~> 2.6.2)
20
+ mimemagic (0.3.3)
21
+ mini_portile2 (2.4.0)
22
+ nokogiri (1.10.1)
23
+ mini_portile2 (~> 2.4.0)
24
+ rake (10.4.2)
25
+ rspec (3.8.0)
26
+ rspec-core (~> 3.8.0)
27
+ rspec-expectations (~> 3.8.0)
28
+ rspec-mocks (~> 3.8.0)
29
+ rspec-core (3.8.0)
30
+ rspec-support (~> 3.8.0)
31
+ rspec-expectations (3.8.2)
32
+ diff-lcs (>= 1.2.0, < 2.0)
33
+ rspec-support (~> 3.8.0)
34
+ rspec-mocks (3.8.0)
35
+ diff-lcs (>= 1.2.0, < 2.0)
36
+ rspec-support (~> 3.8.0)
37
+ rspec-support (3.8.0)
38
+ systemu (2.6.5)
39
+ turnip (3.1.0)
40
+ gherkin (~> 5.0)
41
+ rspec (>= 3.0, < 4.0)
42
+ uuid (2.3.9)
43
+ macaddr (~> 1.0)
44
+
45
+ PLATFORMS
46
+ ruby
47
+
48
+ DEPENDENCIES
49
+ allure_turnip!
50
+ bundler
51
+ rake
52
+
53
+ BUNDLED WITH
54
+ 2.0.1
data/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # Allure Turnip
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/allure-rspec.svg)](http://badge.fury.io/rb/allure-rspec)
4
+
5
+ Adaptor to use the Allure framework along with the [Turnip](https://github.com/jnicklas/turnip).
6
+
7
+ ## What's new
8
+
9
+ See the [releases](https://github.com/aha-oretama/allure_turnip/releases) tab.
10
+
11
+
12
+ ## Setup
13
+
14
+ Add the dependency to your Gemfile. Choose the version carefully:
15
+
16
+ | Allure Turnip | Turnip |
17
+ | ------------- | ------ |
18
+ | >= 0.1.x | >= 3.0 |
19
+
20
+ ```ruby
21
+ gem 'allure_turnip'
22
+ ```
23
+
24
+ And then include it in your spec_helper.rb:
25
+
26
+ ```ruby
27
+ require 'allure_turnip'
28
+
29
+ RSpec.configure do |c|
30
+ c.include AllureRSpec::Adaptor
31
+ end
32
+ ```
33
+
34
+ ## Advanced options
35
+
36
+ You can specify the directory where the Allure test results will appear. By default it would be 'gen/allure-results'
37
+ within your current directory.
38
+ When you add a `feature_with_filename` option, the suites of the the Allure test results include file's name as a prefix.
39
+ This options is useful if you have some same feature names. Because Allure overwrites the same feature name's result if there are some same feature names.
40
+
41
+ ```ruby
42
+ AllureRSpec.configure do |c|
43
+ c.output_dir = "/whatever/you/like" # default: gen/allure-results
44
+ c.clean_dir = false # clean the output directory first? (default: true)
45
+ c.logging_level = Logger::DEBUG # logging level (default: DEBUG)
46
+ c.feature_with_filename = true # default: false
47
+ end
48
+ ```
49
+
50
+ ## DSL
51
+ In your *step* method, you can call `attach_file` method.
52
+ The method attaches the file in the Allure result.
53
+
54
+ ## Usage examples
55
+
56
+ **feature**
57
+ ```ruby
58
+ Feature: Attach File
59
+ Scenario: This is an attaching file feature
60
+ Given attach file
61
+ ```
62
+
63
+ **steps**
64
+ ```ruby
65
+ step 'attach file' do
66
+ attach_file "test-file1", Tempfile.new("test")
67
+ end
68
+ ```
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
3
+ require "allure_turnip/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'allure_turnip'
7
+ s.version = AllureTurnip::Version::STRING
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ['aha-oretama']
10
+ s.email = ['sekine_y_529@msn.com']
11
+ s.description = %q{Adaptor to use Allure framework along with the Turnip}
12
+ s.summary = "allure_turnip-#{AllureTurnip::Version::STRING}"
13
+ s.homepage = 'https://github.com/aha-oretama/allure_turnip'
14
+ s.license = 'Apache-2.0'
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ['lib']
20
+
21
+ s.add_dependency 'rspec', '~> 3.5'
22
+ s.add_dependency 'allure-ruby-adaptor-api', '0.7.0'
23
+ s.add_dependency 'turnip', '~> 3.0'
24
+
25
+ s.add_development_dependency 'bundler'
26
+ s.add_development_dependency 'rake'
27
+ end
@@ -0,0 +1,64 @@
1
+ require 'allure-ruby-adaptor-api'
2
+ require 'turnip'
3
+ require 'allure_turnip/version'
4
+ require 'allure_turnip/formatter'
5
+ require 'allure_turnip/adaptor'
6
+ require 'allure_turnip/dsl'
7
+ require 'allure_turnip/hooks'
8
+ require 'allure_turnip/turnip_extension'
9
+
10
+ module AllureTurnip
11
+ module Config
12
+ class << self
13
+ attr_accessor :output_dir
14
+ attr_accessor :clean_dir
15
+ attr_accessor :logging_level
16
+ attr_accessor :feature_with_filename
17
+
18
+ DEFAULT_OUTPUT_DIR = 'gen/allure-results'
19
+ DEFAULT_LOGGING_LEVEL = Logger::DEBUG
20
+ DEFAULT_FEATURE_WITH_FILENAME = false
21
+
22
+ def output_dir
23
+ @output_dir || DEFAULT_OUTPUT_DIR
24
+ end
25
+
26
+ def clean_dir?
27
+ @clean_dir.nil? ? true : @clean_dir
28
+ end
29
+
30
+ def logging_level
31
+ @logging_level || DEFAULT_LOGGING_LEVEL
32
+ end
33
+
34
+ def feature_with_filename?
35
+ @feature_with_filename || DEFAULT_FEATURE_WITH_FILENAME
36
+ end
37
+ end
38
+ end
39
+
40
+ class Context
41
+ attr_accessor :rspec
42
+
43
+ def rspec
44
+ @rspec
45
+ end
46
+ end
47
+
48
+ class << self
49
+ def context
50
+ @context ||= Context.new
51
+ end
52
+ end
53
+
54
+ class << self
55
+ def configure(&block)
56
+ yield Config
57
+ AllureRubyAdaptorApi.configure { |c|
58
+ c.output_dir = Config.output_dir
59
+ c.logging_level = Config.logging_level
60
+ }
61
+ end
62
+ end
63
+
64
+ end
@@ -0,0 +1,15 @@
1
+ module AllureTurnip
2
+ module Adaptor
3
+ def self.included(base)
4
+ AllureTurnip.context.rspec = base
5
+ base.send :include, AllureTurnip::DSL
6
+ if RSpec::Core::Formatters::Loader.formatters.keys.find_all { |f| f == AllureTurnip::Formatter }.empty?
7
+ RSpec::Core::Formatters.register AllureTurnip::Formatter, *AllureTurnip::Formatter::NOTIFICATIONS
8
+ RSpec.configuration.add_formatter(AllureTurnip::Formatter)
9
+ end
10
+ RSpec::Core::ExampleGroup.send :include, AllureTurnip::Hooks
11
+ RSpec::Core::Example.send :include, AllureTurnip::DSL::Example
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,73 @@
1
+ require 'digest'
2
+ require 'mimemagic'
3
+
4
+ module AllureTurnip
5
+ module DSL
6
+ module Example
7
+
8
+ def current_step
9
+ if defined? @@__current_step
10
+ @@__current_step
11
+ else
12
+ nil
13
+ end
14
+ end
15
+
16
+ def allure_step(step, &block)
17
+ begin
18
+ AllureRubyAdaptorApi::Builder.start_step(__suite, __test, step)
19
+ __with_step step, &block
20
+ AllureRubyAdaptorApi::Builder.stop_step(__suite, __test, step)
21
+ rescue Exception => e
22
+ AllureRubyAdaptorApi::Builder.stop_step(__suite, __test, step, :failed)
23
+ raise e
24
+ end
25
+ end
26
+
27
+ def attach_file(title, file, opts = {})
28
+ step = current_step
29
+ AllureRubyAdaptorApi::Builder.add_attachment __suite, __test, opts.merge(:title => title, :file => file, :step => step)
30
+ end
31
+
32
+ private
33
+
34
+ def __suite
35
+ if AllureTurnip::Config.feature_with_filename?
36
+ "#{File.split(metadata[:example_group][:parent_example_group][:file_path])[1]} -> #{metadata[:example_group][:parent_example_group][:description]}"
37
+ else
38
+ metadata[:example_group][:parent_example_group][:description]
39
+ end
40
+ end
41
+
42
+ def __test
43
+ metadata[:example_group][:full_description]
44
+ end
45
+
46
+ def __description(data)
47
+ data[:full_description] || data[:description]
48
+ end
49
+
50
+ def __mutex
51
+ @@__mutex ||= Mutex.new
52
+ end
53
+
54
+ def __with_step(step, &block)
55
+ begin
56
+ locked = __mutex.try_lock
57
+ if locked
58
+ @@__current_step = step
59
+ AllureTurnip.context.rspec.hooks.send :run, :before, :step, self
60
+ yield self
61
+ end
62
+ ensure
63
+ if locked
64
+ AllureTurnip.context.rspec.hooks.send :run, :after, :step, self
65
+ @@__current_step = nil
66
+ __mutex.unlock
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+
@@ -0,0 +1,143 @@
1
+ require 'rspec/core' unless defined?(RSpec::Core)
2
+ require 'rspec/core/formatters/base_formatter' unless defined?(RSpec::Core::Formatters::BaseFormatter)
3
+ require 'fileutils'
4
+
5
+ module AllureTurnip
6
+
7
+ class Formatter < RSpec::Core::Formatters::BaseFormatter
8
+
9
+ NOTIFICATIONS = [:example_group_started, :example_group_finished,
10
+ :example_failed, :example_passed, :example_pending, :start, :stop]
11
+ ALLOWED_LABELS = [:feature, :story, :severity, :language, :framework, :issue, :testId, :host, :thread]
12
+
13
+ def example_failed(notification)
14
+ return unless turnip?(notification)
15
+
16
+ ex = notification.example.execution_result.exception
17
+ status = ex.is_a?(RSpec::Expectations::ExpectationNotMetError) ? :failed : :broken
18
+ formatter = RSpec.configuration.backtrace_formatter
19
+ formatter.exclusion_patterns.push /lib\/allure_turnip/
20
+ backtrace = formatter.format_backtrace(ex.backtrace, notification.example.metadata)
21
+ ex.set_backtrace(backtrace)
22
+ stop_test(notification.example, :exception => ex, :status => status)
23
+ end
24
+
25
+ def example_group_finished(notification)
26
+ return unless turnip?(notification)
27
+
28
+ if notification.group.examples.empty? # Feature has no examples
29
+ AllureRubyAdaptorApi::Builder.stop_suite(suite(notification.group))
30
+ end
31
+ end
32
+
33
+ def example_group_started(notification)
34
+ return unless turnip?(notification)
35
+
36
+ if notification.group.examples.empty? # Feature has no examples
37
+ AllureRubyAdaptorApi::Builder.start_suite(suite(notification.group), labels(notification))
38
+ else # Scenario has examples
39
+ suite = suite(notification.group)
40
+ test = test(notification.group)
41
+ AllureRubyAdaptorApi::Builder.start_test(suite, test, labels(notification))
42
+ end
43
+ end
44
+
45
+ def example_passed(notification)
46
+ return unless turnip?(notification)
47
+
48
+ stop_test(notification.example)
49
+ end
50
+
51
+ def example_pending(notification)
52
+ return unless turnip?(notification)
53
+
54
+ stop_test(notification.example)
55
+ end
56
+
57
+ def start(example_count)
58
+ dir = Pathname.new(AllureTurnip::Config.output_dir)
59
+ if AllureTurnip::Config.clean_dir?
60
+ puts "Cleaning output directory '#{dir}'..."
61
+ FileUtils.rm_rf(dir)
62
+ end
63
+ FileUtils.mkdir_p(dir)
64
+ end
65
+
66
+ def stop(notify)
67
+ AllureRubyAdaptorApi::Builder.build!
68
+ end
69
+
70
+ private
71
+
72
+ def turnip?(notification)
73
+ metadata(notification)[:turnip]
74
+ end
75
+
76
+ def stop_test(example, opts = {})
77
+ res = example.execution_result
78
+ AllureRubyAdaptorApi::Builder.stop_test(
79
+ suite(example.example_group),
80
+ test(example.example_group),
81
+ {
82
+ :status => res.status,
83
+ :finished_at => res.finished_at,
84
+ :started_at => res.started_at
85
+ }.merge(opts)
86
+ )
87
+ end
88
+
89
+ def suite(group)
90
+ if AllureTurnip::Config.feature_with_filename?
91
+ "#{File.split(group.parent_groups.last.metadata[:file_path])[1]} -> #{group.parent_groups.last.description}"
92
+ else
93
+ group.parent_groups.last.description
94
+ end
95
+ end
96
+
97
+ def test(group)
98
+ group.metadata[:full_description]
99
+ end
100
+
101
+ def metadata(example_or_group)
102
+ group?(example_or_group) ?
103
+ example_or_group.group.metadata :
104
+ example_or_group.example.metadata
105
+ end
106
+
107
+ def group?(example_or_group)
108
+ (example_or_group.respond_to? :group)
109
+ end
110
+
111
+ def labels(example_or_group)
112
+ labels = ALLOWED_LABELS.map { |label| [label, metadata(example_or_group)[label]] }.
113
+ find_all { |value| !value[1].nil? }.
114
+ inject({}) { |res, value| res.merge(value[0] => value[1]) }
115
+ detect_feature_story(labels, example_or_group)
116
+ labels
117
+ end
118
+
119
+ def method_or_key(metadata, key)
120
+ metadata.respond_to?(key) ? metadata.send(key) : metadata[key]
121
+ end
122
+
123
+ def detect_feature_story(labels, example_or_group)
124
+ metadata = metadata(example_or_group)
125
+ is_group = group?(example_or_group)
126
+ parent = (method_or_key(metadata, :parent_example_group))
127
+ if labels[:feature] === true
128
+ description = (!is_group && parent) ? method_or_key(parent, :description) : method_or_key(metadata, :description)
129
+ labels[:feature] = description
130
+ if labels[:story] === true
131
+ if parent
132
+ grandparent = parent && method_or_key(parent, :parent_example_group)
133
+ labels[:feature] = (!is_group && grandparent) ? method_or_key(grandparent, :description) :
134
+ method_or_key(parent, :description)
135
+ end
136
+ labels[:story] = description
137
+ end
138
+ end
139
+ labels
140
+ end
141
+
142
+ end
143
+ end