Skip to content

Commit 4a603c0

Browse files
authored
Make cucumber CCK compliant (#1738)
* First interim working update * Update of all runtime dependencies * Remove pry from suite - use a local gemfile * Update to use latest cck * Remove another personalised gem * Add fix into message builder that now generates a new exception type object in the messages * Enable the structure for making the parameter-type message pass the v12 cck. However this is a WIP and will need further touching up * Add in a new param to last call for #attach which is the filename - Leave it as a silly default for now to test it passing through * Add in filename to #attach called from world * Pass in filename to each method chain * CCK should run locally too * Permit filename to be passed into legacy JSONFormatter * Add in filename to console formatter puts statement * Add filename to pretty formatter * When pretty formatter encounters something WITH a filename, show it accordingly, otherwise fall back to default behaviour * Also revert console formatter to old behaviour when no filename is encountered * Fix tests for user interface receiving nil arg * Remove silly default for filename in final consumer before create message object * WIP: Better spike / structure * Bump messages to 17.0 to enable transformer fetching * Fix envelope preparation for ParameterType message to be CCK conformant * Re-order required rubygems and required ruby versions * Add filename param doc for ProtoWorld * CCK 13 is released * Fix spacing of example feature * Bump CCK to v14 * Mark pending spec from CCK as currently untested whilst it is investigated * Remove redundant rake task code * Ensure cck tests aren't ran mixed in to regular tests * Fix failing tests for hook order that were using a previously defined version of * Remove pending guard * spec_helper fixes * Update changelog * Remove final trace of legacy cucumber 1.7 pending flags * Update changelog with ref to removed guards * Update RSpec skipped messages to make more sense * update changelog
1 parent e491902 commit 4a603c0

19 files changed

+89
-73
lines changed

.rspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1+
--require spec_helper
12
--color
2-
--tag "~cck"

CHANGELOG.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,27 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt
99
Please visit [cucumber/CONTRIBUTING.md](https://github.com/cucumber/cucumber/blob/master/CONTRIBUTING.md) for more info on how to contribute to Cucumber.
1010

1111
## [Unreleased]
12+
### Added
13+
- `ParameterType` message now contains a new (sourceReference), property
14+
(This contains a uri string and a `Location` message -> for where the ParameterType `transformer` is located) ([#1738](https://github.com/cucumber/cucumber-ruby/pull/1738) [luke-hill](https://github.com/luke-hill))
15+
1216
### Changed
1317
- First couple of passes of tidying up approximately 40% of the manual fix cops
1418
([#1739](https://github.com/cucumber/cucumber-ruby/pull/1739) [#1740](https://github.com/cucumber/cucumber-ruby/pull/1740) [#1741](https://github.com/cucumber/cucumber-ruby/pull/1741) [#1742](https://github.com/cucumber/cucumber-ruby/pull/1742) [luke-hill](https://github.com/luke-hill))
1519
- Removed a bunch of example files / sample projects from ancient projects no longer viable
16-
[#1740](https://github.com/cucumber/cucumber-ruby/pull/1740) [luke-hill](https://github.com/luke-hill))
20+
([#1740](https://github.com/cucumber/cucumber-ruby/pull/1740) [luke-hill](https://github.com/luke-hill))
21+
- When a `testStepResult` is of type `FAILED` we now pass in a new (Exception), message property
22+
([#1738](https://github.com/cucumber/cucumber-ruby/pull/1738) [luke-hill](https://github.com/luke-hill))
23+
- `#attach` now can take an optional filename parameter which will rename attachments like PDF's
24+
([#1738](https://github.com/cucumber/cucumber-ruby/pull/1738) [luke-hill](https://github.com/luke-hill))
25+
26+
### Fixed
27+
- Clear up a couple of tiny "nuances" that hide lots of issues when running local vs remote (Primarily CCK tests should always be runnable)
28+
([#1738](https://github.com/cucumber/cucumber-ruby/pull/1738) [luke-hill](https://github.com/luke-hill))
29+
30+
### Removed
31+
- Removed a variety of overrides / hacks for travis CI (No longer in use) ([#1738](https://github.com/cucumber/cucumber-ruby/pull/1738) [luke-hill](https://github.com/luke-hill))
32+
- Removed some legacy rspec pending flags present since cucumber 1.x ([#1738](https://github.com/cucumber/cucumber-ruby/pull/1738) [luke-hill](https://github.com/luke-hill))
1733

1834
## [9.0.2] - 2023-09-11
1935
### Changed

Rakefile

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,3 @@ default_tasks = %i[spec cucumber cck]
1919
default_tasks << :examples if ENV['CI']
2020

2121
task default: default_tasks
22-
23-
require 'rake/clean'
24-
CLEAN.include %w[**/*.{log,pyc,rbc,tgz} doc]

cucumber.gemspec

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,23 @@ Gem::Specification.new do |s|
2020
}
2121

2222
s.required_ruby_version = '>= 2.7'
23+
s.required_rubygems_version = '>= 3.0.1'
2324

2425
s.add_dependency 'builder', '~> 3.2', '>= 3.2.4'
2526
s.add_dependency 'cucumber-ci-environment', '~> 9.2', '>= 9.2.0'
26-
s.add_dependency 'cucumber-core', '~> 11.1', '>= 11.1.0'
27-
s.add_dependency 'cucumber-cucumber-expressions', '~> 16.1', '>= 16.1.2'
28-
s.add_dependency 'cucumber-gherkin', '>= 24', '< 26.2.1'
27+
s.add_dependency 'cucumber-core', '~> 12.0'
28+
s.add_dependency 'cucumber-cucumber-expressions', '~> 17.0'
29+
s.add_dependency 'cucumber-gherkin', '>= 24', '< 27'
2930
s.add_dependency 'cucumber-html-formatter', '~> 20.4', '>= 20.4.0'
3031
s.add_dependency 'cucumber-messages', '>= 19', '< 23'
3132
s.add_dependency 'diff-lcs', '~> 1.5', '>= 1.5.0'
3233
s.add_dependency 'mini_mime', '~> 1.1', '>= 1.1.5'
3334
s.add_dependency 'multi_test', '~> 1.1', '>= 1.1.0'
3435
s.add_dependency 'sys-uname', '~> 1.2', '>= 1.2.3'
3536

36-
s.add_development_dependency 'cucumber-compatibility-kit', '~> 10.0'
37+
s.add_development_dependency 'cucumber-compatibility-kit', '~> 14.0'
3738
# Only needed whilst we are testing the formatters. Can be removed once we remove tests for those
3839
s.add_development_dependency 'nokogiri', '~> 1.13', '>= 1.13.6'
39-
s.add_development_dependency 'pry', '~> 0.14', '>= 0.14.1'
4040
s.add_development_dependency 'rake', '~> 13.0', '>= 13.0.6'
4141
s.add_development_dependency 'rspec', '~> 3.12', '>= 3.12.0'
4242
s.add_development_dependency 'rubocop', '~> 1.56.4'
@@ -54,7 +54,6 @@ Gem::Specification.new do |s|
5454
s.add_development_dependency 'rack-test', '~> 2.1', '>= 2.1.0'
5555
s.add_development_dependency 'sinatra', '~> 3.1', '>= 3.1.0'
5656

57-
s.required_rubygems_version = '>= 3.0.1'
5857
s.files = Dir[
5958
'README.md',
6059
'LICENSE',

features/docs/writing_support_code/hooks/hook_order.feature

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,25 @@
1-
Feature: Hooks execute in defined order
2-
1+
Feature: Hooks execute in defined order
32
Background:
43
Given a file named "features/step_definitions/steps.rb" with:
54
"""
6-
Given /^background step$/ do; log(:background_step) end
7-
Given /^scenario step$/ do; log(:scenario_step) end
5+
Given('background step') { log(:background_step) }
6+
Given('scenario step') { log(:scenario_step) }
87
"""
98
And a file named "features/support/hooks.rb" with:
109
"""
1110
$EventOrder = []
1211
Around('@around') do |scenario,block|
13-
log :around_begin
12+
log(:around_begin)
1413
block.call
15-
log :around_end
14+
log(:around_end)
1615
end
1716
1817
Before('@before') do
19-
log :before
18+
log(:before)
2019
end
2120
2221
After('@after') do |scenario|
23-
log :after
22+
log(:after)
2423
end
2524
"""
2625
And a file named "features/around_hook_covers_background.feature" with:
@@ -46,17 +45,18 @@
4645
And log only formatter is declared
4746

4847
Scenario: Around hooks cover background steps
49-
When I run `cucumber features/around_hook_covers_background.feature --format LogOnlyFormatter`
48+
When I run `cucumber features/around_hook_covers_background.feature --format LogOnlyFormatter --publish-quiet`
5049
Then the output should contain:
5150
"""
5251
around_begin
5352
background_step
5453
scenario_step
5554
around_end
5655
"""
56+
And the exit status should be 0
5757

5858
Scenario: All hooks execute in expected order
59-
When I run `cucumber features/all_hook_order.feature --format LogOnlyFormatter`
59+
When I run `cucumber features/all_hook_order.feature --format LogOnlyFormatter --publish-quiet`
6060
Then the output should contain:
6161
"""
6262
around_begin
@@ -66,3 +66,4 @@
6666
after
6767
around_end
6868
"""
69+
And the exit status should be 0

features/lib/step_definitions/cucumber_steps.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
' @io = config.out_stream',
1616
' end',
1717
'',
18-
' def attach(src, media_type)',
19-
' @io.puts src',
18+
' def attach(src, media_type, _filename)',
19+
' @io.puts(src)',
2020
' end',
2121
'end'
2222
].join("\n"))

gem_tasks/examples.rake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
desc 'Run all examples'
44
task :examples do
55
Dir['examples/*'].each do |example_dir|
6-
next if !File.directory?(example_dir) || %w[examples/tcl].index(example_dir)
6+
next unless File.directory?(example_dir)
77

88
puts "Running #{example_dir}"
99
Dir.chdir(example_dir) do

gem_tasks/rspec.rake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ require 'rspec/core/rake_task'
55
desc 'Run RSpec'
66
RSpec::Core::RakeTask.new do |t|
77
t.verbose = true
8+
t.rspec_opts = '--tag ~cck'
89
end

lib/cucumber/formatter/console.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,17 @@ def do_print_passing_wip(passed_messages)
169169
end
170170
end
171171

172-
def attach(src, media_type)
172+
def attach(src, media_type, filename)
173173
return unless media_type == 'text/x.cucumber.log+plain'
174174
return unless @io
175175

176176
@io.puts
177-
@io.puts(format_string(src, :tag))
177+
if filename
178+
@io.puts("#{filename}: #{format_string(src, :tag)}")
179+
else
180+
@io.puts(format_string(src, :tag))
181+
end
182+
178183
@io.flush
179184
end
180185

lib/cucumber/formatter/json.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def on_test_run_finished(_event)
8585
@io.write(JSON.pretty_generate(@feature_hashes))
8686
end
8787

88-
def attach(src, mime_type)
88+
def attach(src, mime_type, _filename)
8989
if mime_type == 'text/x.cucumber.log+plain'
9090
test_step_output << src
9191
return

lib/cucumber/formatter/message_builder.rb

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,12 @@ def output_message
4242
raise 'To be implemented'
4343
end
4444

45-
def attach(src, media_type)
45+
def attach(src, media_type, filename)
4646
attachment_data = {
4747
test_step_id: @current_test_step_id,
4848
test_case_started_id: @current_test_case_started_id,
49-
media_type: media_type
49+
media_type: media_type,
50+
file_name: filename
5051
}
5152

5253
if media_type.start_with?('text/')
@@ -192,10 +193,13 @@ def on_test_step_finished(event)
192193

193194
result_message = result.to_message
194195
if result.failed? || result.pending?
196+
message_element = result.failed? ? result.exception : result
197+
195198
result_message = Cucumber::Messages::TestStepResult.new(
196199
status: result_message.status,
197200
duration: result_message.duration,
198-
message: create_error_message(result)
201+
message: create_error_message(message_element),
202+
exception: create_exception_object(result, message_element)
199203
)
200204
end
201205

@@ -211,12 +215,17 @@ def on_test_step_finished(event)
211215
output_envelope(message)
212216
end
213217

214-
def create_error_message(result)
215-
message_element = result.failed? ? result.exception : result
218+
def create_error_message(message_element)
216219
message = "#{message_element.message} (#{message_element.class})"
217220
([message] + message_element.backtrace).join("\n")
218221
end
219222

223+
def create_exception_object(result, message_element)
224+
return unless result.failed?
225+
226+
Cucumber::Messages::Exception.from_h({ type: message_element.class, message: message_element.message })
227+
end
228+
220229
def on_test_case_finished(event)
221230
message = Cucumber::Messages::Envelope.new(
222231
test_case_finished: Cucumber::Messages::TestCaseFinished.new(

lib/cucumber/formatter/pretty.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,14 @@ def on_test_run_finished(_event)
140140
print_summary
141141
end
142142

143-
def attach(src, media_type)
143+
def attach(src, media_type, filename)
144144
return unless media_type == 'text/x.cucumber.log+plain'
145145

146-
@test_step_output.push src
146+
if filename
147+
@test_step_output.push("#{filename}: #{src}")
148+
else
149+
@test_step_output.push(src)
150+
end
147151
end
148152

149153
private

lib/cucumber/glue/proto_world.rb

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
module Cucumber
99
module Glue
10-
# Defines the basic API methods availlable in all Cucumber step definitions.
10+
# Defines the basic API methods available in all Cucumber step definitions.
1111
#
1212
# You can, and probably should, extend this API with your own methods that
1313
# make sense in your domain. For more on that, see {Cucumber::Glue::Dsl#World}
@@ -86,14 +86,17 @@ def log(*messages)
8686
# @param file [string|io] the file to attach.
8787
# It can be a string containing the file content itself, the file path, or an IO ready to be read.
8888
# @param media_type [string] the media type.
89-
# If file is a valid path, media_type can be omitted, it will then be inferred from the file name.
90-
def attach(file, media_type = nil)
89+
# If file is a valid path, media_type can be omitted, it will then be inferred from the file name.
90+
# @param filename [string] the name of the file you wish to specify.
91+
# This is only needed in situations where you want to rename a PDF download e.t.c. - In most situations
92+
# you should not need to pass a filename
93+
def attach(file, media_type = nil, filename = nil)
9194
return super unless File.file?(file)
9295

9396
content = File.read(file, mode: 'rb')
9497
media_type = MiniMime.lookup_by_filename(file)&.content_type if media_type.nil?
9598

96-
super(content, media_type.to_s)
99+
super(content, media_type.to_s, filename)
97100
rescue StandardError
98101
super
99102
end
@@ -152,8 +155,8 @@ def add_modules!(world_modules, namespaced_world_modules)
152155
runtime.ask(question, timeout_seconds)
153156
end
154157

155-
define_method(:attach) do |file, media_type|
156-
runtime.attach(file, media_type)
158+
define_method(:attach) do |file, media_type, filename|
159+
runtime.attach(file, media_type, filename)
157160
end
158161

159162
# Prints the list of modules that are included in the World

lib/cucumber/glue/registry_and_more.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,16 +198,19 @@ def self.cli_snippet_type_options
198198
private
199199

200200
def parameter_type_envelope(parameter_type)
201-
# TODO: should me moved to Cucumber::Expression::ParameterType#to_envelope ?
201+
# TODO: should this be moved to Cucumber::Expression::ParameterType#to_envelope ??
202202
# Note: that would mean that cucumber-expression would depend on cucumber-messages
203-
204203
Cucumber::Messages::Envelope.new(
205204
parameter_type: Cucumber::Messages::ParameterType.new(
206205
id: @configuration.id_generator.new_id,
207206
name: parameter_type.name,
208207
regular_expressions: parameter_type.regexps.map(&:to_s),
209-
prefer_for_regular_expression_match: parameter_type.prefer_for_regexp_match?,
210-
use_for_snippets: parameter_type.use_for_snippets?
208+
prefer_for_regular_expression_match: parameter_type.prefer_for_regexp_match,
209+
use_for_snippets: parameter_type.use_for_snippets,
210+
source_reference: Cucumber::Messages::SourceReference.new(
211+
uri: parameter_type.transformer.source_location[0],
212+
location: Cucumber::Messages::Location.new(line: parameter_type.transformer.source_location[1])
213+
)
211214
)
212215
)
213216
end

lib/cucumber/runtime/user_interface.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ def ask(question, timeout_seconds)
4141
# be a path to a file, or if it's an image it may also be a Base64 encoded image.
4242
# The embedded data may or may not be ignored, depending on what kind of formatter(s) are active.
4343
#
44-
def attach(src, media_type)
45-
@visitor.attach(src, media_type)
44+
def attach(src, media_type, filename)
45+
@visitor.attach(src, media_type, filename)
4646
end
4747

4848
private

spec/cucumber/cli/configuration_spec.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ def reset_config
4545
end
4646

4747
context 'when using the --profile flag' do
48-
include RSpec::WorkInProgress
49-
5048
it 'expands args from profiles in the cucumber.yml file' do
5149
given_cucumber_yml_defined_as('bongo' => '--require from/yml')
5250
config.parse!(%w[--format progress --profile bongo])

spec/cucumber/cli/profile_loader_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def given_cucumber_yml_defined_as(hash_or_string)
1616
end
1717

1818
context 'when on a Windows OS' do
19-
before { skip('Only run these tests on non-Windows') unless Cucumber::WINDOWS }
19+
before { skip('These tests are only to be ran on Windows') unless Cucumber::WINDOWS }
2020

2121
it 'treats backslashes as literals in rerun.txt when on Windows (JRuby or MRI)' do
2222
given_cucumber_yml_defined_as('default' => '--format "pretty" features\sync_imap_mailbox.feature:16:22')
@@ -54,7 +54,7 @@ def given_cucumber_yml_defined_as(hash_or_string)
5454
end
5555

5656
context 'when on non-Windows OS' do
57-
before { skip('Only run these tests on non-Windows') if Cucumber::WINDOWS }
57+
before { skip('These tests are only to be ran on a "Non-Windows" OS') if Cucumber::WINDOWS }
5858

5959
it 'treats backslashes as literals in rerun.txt when on Windows (JRuby or MRI)' do
6060
given_cucumber_yml_defined_as('default' => '--format "pretty" features\sync_imap_mailbox.feature:16:22')

spec/cucumber/glue/step_definition_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,15 +198,15 @@ def step_match(text)
198198

199199
context 'allows log' do
200200
it 'calls "attach" with the correct media type' do
201-
expect(user_interface).to receive(:attach).with('wasup', 'text/x.cucumber.log+plain')
201+
expect(user_interface).to receive(:attach).with('wasup', 'text/x.cucumber.log+plain', nil)
202202
dsl.Given(/Loud/) do
203203
log 'wasup'
204204
end
205205
run_step 'Loud'
206206
end
207207

208208
it 'calls `to_s` if the message is not a String' do
209-
expect(user_interface).to receive(:attach).with('["Not", 1, "string"]', 'text/x.cucumber.log+plain')
209+
expect(user_interface).to receive(:attach).with('["Not", 1, "string"]', 'text/x.cucumber.log+plain', nil)
210210
dsl.Given(/Loud/) do
211211
log ['Not', 1, 'string']
212212
end

0 commit comments

Comments
 (0)