allure-rspec 0.8.0 → 2.15.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,186 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AllureRspec
4
+ # RSpec metadata parser
5
+ #
6
+ class RspecMetadataParser
7
+ include Utils
8
+
9
+ RSPEC_IGNORED_METADATA = %i[
10
+ absolute_file_path
11
+ block
12
+ described_class
13
+ description
14
+ description_args
15
+ example_group
16
+ execution_result
17
+ file_path
18
+ full_description
19
+ last_run_status
20
+ line_number
21
+ location
22
+ rerun_file_path
23
+ retry
24
+ retry_attempts
25
+ retry_exceptions
26
+ scoped_id
27
+ shared_group_inclusion_backtrace
28
+ type
29
+ ].freeze
30
+
31
+ # Metadata parser instance
32
+ #
33
+ # @param [RSpec::Core::Example] example
34
+ # @param [AllureRspec::RspecConfig] config <description>
35
+ def initialize(example, config)
36
+ @example = example
37
+ @config = config
38
+ end
39
+
40
+ # Get allure labels
41
+ # @return [Array<Allure::Label>]
42
+ def labels
43
+ [
44
+ framework_label,
45
+ package_label,
46
+ test_class_label,
47
+ severity,
48
+ *tag_labels,
49
+ *behavior_labels,
50
+ *suite_labels
51
+ ].select(&:value)
52
+ end
53
+
54
+ # Get attachable links
55
+ # @return [Array<Allure::Link>]
56
+ def links
57
+ matching_links(:tms) + matching_links(:issue)
58
+ end
59
+
60
+ # Get status details
61
+ # @return [Allure::StatusDetails]
62
+ def status_details
63
+ Allure::StatusDetails.new(
64
+ flaky: !metadata[:flaky].nil?,
65
+ muted: !metadata[:muted].nil?,
66
+ known: !metadata[:known].nil?
67
+ )
68
+ end
69
+
70
+ private
71
+
72
+ # @return [RSpec::Core::Example]
73
+ attr_reader :example
74
+
75
+ # @return [AllureRspec::RspecConfig]
76
+ attr_reader :config
77
+
78
+ # Example metadata
79
+ #
80
+ # @return [Hash]
81
+ def metadata
82
+ @metadata ||= example.metadata
83
+ end
84
+
85
+ # Get package label
86
+ # @return [Allure::Label]
87
+ def package_label
88
+ Allure::ResultUtils.package_label(Pathname.new(strip_relative(example.file_path)).parent.to_s)
89
+ end
90
+
91
+ # Get test class label
92
+ #
93
+ # @return [Allure::Label]
94
+ def test_class_label
95
+ Allure::ResultUtils.test_class_label(File.basename(example.file_path, ".rb"))
96
+ end
97
+
98
+ # Get framework label
99
+ # @return [Allure::Label]
100
+ def framework_label
101
+ Allure::ResultUtils.framework_label("rspec")
102
+ end
103
+
104
+ # Get severity
105
+ # @return [String]
106
+ def severity
107
+ Allure::ResultUtils.severity_label(metadata[config.severity_tag] || "normal")
108
+ end
109
+
110
+ # Get test suite labels
111
+ # @return [Array<Allure::Label>]
112
+ def suite_labels
113
+ SuiteLabels.new(example.example_group).fetch
114
+ end
115
+
116
+ # Get custom labels
117
+ # @return [Array<Allure::Label>]
118
+ def tag_labels
119
+ metadata
120
+ .reject { |k| RSPEC_IGNORED_METADATA.include?(k) || special_metadata_tag?(k) }
121
+ .map { |k, v| allure?(k) ? Allure::ResultUtils.tag_label(v) : Allure::ResultUtils.tag_label(k.to_s) }
122
+ end
123
+
124
+ # Get behavior labels
125
+ # @return [Array<Allure::Label>]
126
+ def behavior_labels
127
+ metadata = example.metadata
128
+ epic = metadata[config.epic_tag] || Pathname.new(strip_relative(example.file_path)).parent.to_s
129
+ feature = metadata[config.feature_tag] || example.example_group.description
130
+ story = metadata[config.story_tag]
131
+
132
+ [
133
+ Allure::ResultUtils.epic_label(epic),
134
+ Allure::ResultUtils.feature_label(feature),
135
+ Allure::ResultUtils.story_label(story)
136
+ ]
137
+ end
138
+
139
+ # tms and issue links
140
+ # @param [Symbol] type
141
+ # @return [Array<Allure::Link>]
142
+ def matching_links(type)
143
+ link_pattern = config.public_send("link_#{type}_pattern")
144
+ return [] unless link_pattern
145
+
146
+ metadata
147
+ .select { |key| __send__("#{type}?", key) }
148
+ .map { |key, value| Allure::ResultUtils.public_send("#{type}_link", key.to_s, value, link_pattern) }
149
+ end
150
+
151
+ # Special allure metadata tags
152
+ #
153
+ # @param [Symbol] key
154
+ # @return [boolean]
155
+ def special_metadata_tag?(key)
156
+ tms?(key) || issue?(key) || [
157
+ config.severity_tag,
158
+ config.epic_tag,
159
+ config.feature_tag,
160
+ config.story_tag,
161
+ *config.ignored_tags
162
+ ].include?(key)
163
+ end
164
+
165
+ # Does key match custom allure label
166
+ # @param [Symbol] key
167
+ # @return [boolean]
168
+ def allure?(key)
169
+ key.to_s.match?(/allure(_\d+)?/i)
170
+ end
171
+
172
+ # Does key match tms pattern
173
+ # @param [Symbol] key
174
+ # @return [boolean]
175
+ def tms?(key)
176
+ key.to_s.match?(/#{config.tms_tag}(_\d+)?/i)
177
+ end
178
+
179
+ # Does key match issue pattern
180
+ # @param [Symbol] key
181
+ # @return [boolean]
182
+ def issue?(key)
183
+ key.to_s.match?(/#{config.issue_tag}(_\d+)?/i)
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AllureRspec
4
+ # Suite label generator
5
+ #
6
+ class SuiteLabels
7
+ include Utils
8
+
9
+ def initialize(example_group)
10
+ @example_group = example_group
11
+ end
12
+
13
+ # Get test suite labels
14
+ # @return [Array<Allure::Label>]
15
+ def fetch
16
+ parents = example_group.parent_groups.map do |group|
17
+ group.description.empty? ? "Anonymous" : group.description
18
+ end
19
+
20
+ labels = []
21
+ labels << Allure::ResultUtils.suite_label(suite(parents))
22
+ labels << Allure::ResultUtils.parent_suite_label(parent_suite(parents)) if parent_suite(parents)
23
+ labels << Allure::ResultUtils.sub_suite_label(sub_suites(parents)) if sub_suites(parents)
24
+
25
+ labels
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :example_group
31
+
32
+ # @param [Array<String>] parents
33
+ # @return [String]
34
+ def suite(parents)
35
+ parents.length == 1 ? parents.last : parents[-2]
36
+ end
37
+
38
+ # @param [Array<String>] parents
39
+ # @return [String]
40
+ def parent_suite(parents)
41
+ parents.length > 1 ? parents.last : nil
42
+ end
43
+
44
+ # @param [Array<String>] parents
45
+ # @return [String]
46
+ def sub_suites(parents)
47
+ parents.length > 2 ? parents[0..-3].join(" > ") : nil
48
+ end
49
+ end
50
+ end
metadata CHANGED
@@ -1,101 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: allure-rspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 2.15.0
5
5
  platform: ruby
6
6
  authors:
7
- - Ilya Sadykov
7
+ - Andrejs Cunskis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-28 00:00:00.000000000 Z
11
+ date: 2021-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rspec
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '3.5'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '3.5'
27
- - !ruby/object:Gem::Dependency
28
- name: allure-ruby-adaptor-api
14
+ name: allure-ruby-commons
29
15
  requirement: !ruby/object:Gem::Requirement
30
16
  requirements:
31
17
  - - '='
32
18
  - !ruby/object:Gem::Version
33
- version: 0.7.0
19
+ version: 2.15.0
34
20
  type: :runtime
35
21
  prerelease: false
36
22
  version_requirements: !ruby/object:Gem::Requirement
37
23
  requirements:
38
24
  - - '='
39
25
  - !ruby/object:Gem::Version
40
- version: 0.7.0
26
+ version: 2.15.0
41
27
  - !ruby/object:Gem::Dependency
42
- name: bundler
28
+ name: rspec-core
43
29
  requirement: !ruby/object:Gem::Requirement
44
30
  requirements:
45
31
  - - ">="
46
32
  - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: rake
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
33
+ version: '3.8'
34
+ - - "<"
60
35
  - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
36
+ version: '4'
37
+ type: :runtime
63
38
  prerelease: false
64
39
  version_requirements: !ruby/object:Gem::Requirement
65
40
  requirements:
66
41
  - - ">="
67
42
  - !ruby/object:Gem::Version
68
- version: '0'
69
- description: Adaptor to use Allure framework along with the RSpec 2
70
- email:
71
- - smecsia@yandex-team.ru
43
+ version: '3.8'
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '4'
47
+ description: Cucumber adaptor to generate rich allure test reports
48
+ email: andrejs.cunskis@gmail.com
72
49
  executables: []
73
50
  extensions: []
74
51
  extra_rdoc_files: []
75
52
  files:
76
- - ".gitignore"
77
- - Gemfile
78
- - Gemfile.lock
79
53
  - README.md
80
- - allure-rspec.gemspec
81
54
  - lib/allure-rspec.rb
82
- - lib/allure-rspec/adaptor.rb
83
- - lib/allure-rspec/dsl.rb
84
- - lib/allure-rspec/formatter.rb
85
- - lib/allure-rspec/hooks.rb
86
- - lib/allure-rspec/version.rb
87
- - logo.png
88
- - spec/another_spec.rb
89
- - spec/extend_steps_spec.rb
90
- - spec/hooks_spec.rb
91
- - spec/issue51_spec.rb
92
- - spec/nometavalue_spec.rb
93
- - spec/shared_example_spec.rb
94
- - spec/spec_helper.rb
95
- homepage: http://allure.qatools.ru
55
+ - lib/allure_rspec/_utils.rb
56
+ - lib/allure_rspec/config.rb
57
+ - lib/allure_rspec/formatter.rb
58
+ - lib/allure_rspec/metadata_parser.rb
59
+ - lib/allure_rspec/suite_labels.rb
60
+ homepage: https://github.com/allure-framework/allure-ruby/tree/master/allure-rspec
96
61
  licenses:
97
62
  - Apache-2.0
98
- metadata: {}
63
+ metadata:
64
+ bug_tracker_uri: https://github.com/allure-framework/allure-ruby/issues
65
+ changelog_uri: https://github.com/allure-framework/allure-ruby/releases
66
+ documentation_uri: https://github.com/allure-framework/allure-ruby/blob/master/allure-rspec/README.md
67
+ source_code_uri: https://github.com/allure-framework/allure-ruby/tree/master/allure-rspec
68
+ wiki_uri: https://github.com/allure-framework/allure-ruby/wiki
99
69
  post_install_message:
100
70
  rdoc_options: []
101
71
  require_paths:
@@ -104,16 +74,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
104
74
  requirements:
105
75
  - - ">="
106
76
  - !ruby/object:Gem::Version
107
- version: '0'
77
+ version: 2.5.0
108
78
  required_rubygems_version: !ruby/object:Gem::Requirement
109
79
  requirements:
110
80
  - - ">="
111
81
  - !ruby/object:Gem::Version
112
82
  version: '0'
113
83
  requirements: []
114
- rubyforge_project:
115
- rubygems_version: 2.4.8
84
+ rubygems_version: 3.2.22
116
85
  signing_key:
117
86
  specification_version: 4
118
- summary: allure-rspec-0.8.0
87
+ summary: Allure rspec ruby adaptor
119
88
  test_files: []
data/.gitignore DELETED
@@ -1,15 +0,0 @@
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/Gemfile DELETED
@@ -1,3 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec
data/Gemfile.lock DELETED
@@ -1,49 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- allure-rspec (0.8.0)
5
- allure-ruby-adaptor-api (= 0.7.0)
6
- rspec (~> 3.5)
7
-
8
- GEM
9
- remote: https://rubygems.org/
10
- specs:
11
- allure-ruby-adaptor-api (0.7.0)
12
- mimemagic
13
- nokogiri (~> 1.7)
14
- uuid
15
- diff-lcs (1.2.5)
16
- macaddr (1.7.1)
17
- systemu (~> 2.6.2)
18
- mimemagic (0.3.2)
19
- mini_portile2 (2.1.0)
20
- nokogiri (1.7.0)
21
- mini_portile2 (~> 2.1.0)
22
- rake (10.4.2)
23
- rspec (3.5.0)
24
- rspec-core (~> 3.5.0)
25
- rspec-expectations (~> 3.5.0)
26
- rspec-mocks (~> 3.5.0)
27
- rspec-core (3.5.4)
28
- rspec-support (~> 3.5.0)
29
- rspec-expectations (3.5.0)
30
- diff-lcs (>= 1.2.0, < 2.0)
31
- rspec-support (~> 3.5.0)
32
- rspec-mocks (3.5.0)
33
- diff-lcs (>= 1.2.0, < 2.0)
34
- rspec-support (~> 3.5.0)
35
- rspec-support (3.5.0)
36
- systemu (2.6.5)
37
- uuid (2.3.8)
38
- macaddr (~> 1.0)
39
-
40
- PLATFORMS
41
- ruby
42
-
43
- DEPENDENCIES
44
- allure-rspec!
45
- bundler
46
- rake
47
-
48
- BUNDLED WITH
49
- 1.13.7
data/allure-rspec.gemspec DELETED
@@ -1,26 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
3
- require "allure-rspec/version"
4
-
5
- Gem::Specification.new do |s|
6
- s.name = 'allure-rspec'
7
- s.version = AllureRSpec::Version::STRING
8
- s.platform = Gem::Platform::RUBY
9
- s.authors = ['Ilya Sadykov']
10
- s.email = ['smecsia@yandex-team.ru']
11
- s.description = %q{Adaptor to use Allure framework along with the RSpec 2}
12
- s.summary = "allure-rspec-#{AllureRSpec::Version::STRING}"
13
- s.homepage = 'http://allure.qatools.ru'
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
-
24
- s.add_development_dependency 'bundler'
25
- s.add_development_dependency 'rake'
26
- end
@@ -1,15 +0,0 @@
1
- module AllureRSpec
2
- module Adaptor
3
- def self.included(base)
4
- AllureRSpec.context.rspec = base
5
- base.send :include, AllureRSpec::DSL
6
- if RSpec::Core::Formatters::Loader.formatters.keys.find_all { |f| f == AllureRSpec::Formatter }.empty?
7
- RSpec::Core::Formatters.register AllureRSpec::Formatter, *AllureRSpec::Formatter::NOTIFICATIONS
8
- RSpec.configuration.add_formatter(AllureRSpec::Formatter)
9
- end
10
- RSpec::Core::ExampleGroup.send :include, AllureRSpec::Hooks
11
- RSpec::Core::Example.send :include, AllureRSpec::DSL::Example
12
- end
13
- end
14
- end
15
-
@@ -1,61 +0,0 @@
1
- require 'digest'
2
- require 'mimemagic'
3
- module AllureRSpec
4
- module DSL
5
- module Example
6
-
7
- def current_step
8
- if defined? @@__current_step
9
- @@__current_step
10
- else
11
- nil
12
- end
13
- end
14
-
15
- def step(step, &block)
16
- suite = __description(metadata[:example_group])
17
- test = __description(metadata)
18
- begin
19
- AllureRubyAdaptorApi::Builder.start_step(suite, test, step)
20
- __with_step step, &block
21
- AllureRubyAdaptorApi::Builder.stop_step(suite, test, step)
22
- rescue Exception => e
23
- AllureRubyAdaptorApi::Builder.stop_step(suite, test, step, :failed)
24
- raise e
25
- end
26
- end
27
-
28
-
29
- def attach_file(title, file, opts = {})
30
- suite = __description(metadata[:example_group])
31
- test = __description(metadata)
32
- step = current_step
33
- AllureRubyAdaptorApi::Builder.add_attachment suite, test, opts.merge(:title => title, :file => file, :step => step)
34
- end
35
-
36
- private
37
-
38
- def __description(data)
39
- data[:full_description] || data[:description]
40
- end
41
-
42
- def __mutex
43
- @@__mutex ||= Mutex.new
44
- end
45
-
46
- def __with_step(step, &block)
47
- __mutex.synchronize do
48
- begin
49
- @@__current_step = step
50
- AllureRSpec.context.rspec.hooks.send :run, :before, :step, self
51
- yield self
52
- ensure
53
- AllureRSpec.context.rspec.hooks.send :run, :after, :step, self
54
- @@__current_step = nil
55
- end
56
- end
57
- end
58
- end
59
- end
60
- end
61
-
@@ -1,117 +0,0 @@
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 AllureRSpec
6
-
7
- class Formatter < RSpec::Core::Formatters::BaseFormatter
8
-
9
- NOTIFICATIONS = [:example_group_started, :example_group_finished, :example_started,
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
- res = notification.example.execution_result
15
- status = res.exception.is_a?(RSpec::Expectations::ExpectationNotMetError) ? :failed : :broken
16
- stop_test(notification.example, :exception => res.exception, :status => status)
17
- end
18
-
19
- def example_group_finished(notification)
20
- AllureRubyAdaptorApi::Builder.stop_suite(description(notification.group).to_s)
21
- end
22
-
23
- def example_group_started(notification)
24
- AllureRubyAdaptorApi::Builder.start_suite(description(notification.group).to_s, labels(notification))
25
- end
26
-
27
- def example_passed(notification)
28
- stop_test(notification.example)
29
- end
30
-
31
- def example_pending(notification)
32
- stop_test(notification.example)
33
- end
34
-
35
- def example_started(notification)
36
- suite = description(notification.example.example_group).to_s
37
- test = description(notification.example).to_s
38
- AllureRubyAdaptorApi::Builder.start_test(suite, test, labels(notification))
39
- end
40
-
41
- def start(example_count)
42
- dir = Pathname.new(AllureRSpec::Config.output_dir)
43
- if AllureRSpec::Config.clean_dir?
44
- puts "Cleaning output directory '#{dir}'..."
45
- FileUtils.rm_rf(dir)
46
- end
47
- FileUtils.mkdir_p(dir)
48
- end
49
-
50
- def stop(notify)
51
- AllureRubyAdaptorApi::Builder.build!
52
- end
53
-
54
- private
55
-
56
- def description(data, attr = :full_description)
57
- ((((data.respond_to?(attr)) ?
58
- data.send(attr) : data.metadata[attr]) ||
59
- description(data, :description)) || '').strip
60
- end
61
-
62
- def stop_test(example, opts = {})
63
- res = example.execution_result
64
- AllureRubyAdaptorApi::Builder.stop_test(
65
- description(example.example_group).to_s,
66
- (example.metadata[:description_args].size== 0) ? description(example.example_group) : description(example).to_s,
67
- {
68
- :status => res.status,
69
- :finished_at => res.finished_at,
70
- :started_at => res.started_at
71
- }.merge(opts)
72
- )
73
- end
74
-
75
- def metadata(example_or_group)
76
- group?(example_or_group) ?
77
- example_or_group.group.metadata :
78
- example_or_group.example.metadata
79
- end
80
-
81
- def group?(example_or_group)
82
- (example_or_group.respond_to? :group)
83
- end
84
-
85
- def labels(example_or_group)
86
- labels = ALLOWED_LABELS.map { |label| [label, metadata(example_or_group)[label]] }.
87
- find_all { |value| !value[1].nil? }.
88
- inject({}) { |res, value| res.merge(value[0] => value[1]) }
89
- detect_feature_story(labels, example_or_group)
90
- labels
91
- end
92
-
93
- def method_or_key(metadata, key)
94
- metadata.respond_to?(key) ? metadata.send(key) : metadata[key]
95
- end
96
-
97
- def detect_feature_story(labels, example_or_group)
98
- metadata = metadata(example_or_group)
99
- is_group = group?(example_or_group)
100
- parent = (method_or_key(metadata, :parent_example_group))
101
- if labels[:feature] === true
102
- description = (!is_group && parent) ? method_or_key(parent, :description) : method_or_key(metadata, :description)
103
- labels[:feature] = description
104
- if labels[:story] === true
105
- if parent
106
- grandparent = parent && method_or_key(parent, :parent_example_group)
107
- labels[:feature] = (!is_group && grandparent) ? method_or_key(grandparent, :description) :
108
- method_or_key(parent, :description)
109
- end
110
- labels[:story] = description
111
- end
112
- end
113
- labels
114
- end
115
-
116
- end
117
- end