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