diff options
author | Philip Hands <phil@hands.com> | 2016-03-14 15:36:16 +0100 |
---|---|---|
committer | Holger Levsen <holger@layer-acht.org> | 2016-04-28 21:52:10 +0200 |
commit | da080c472fc415b0ce918f4dd4a1ab143bb1bca4 (patch) | |
tree | bf63179f32f0eda0c2d5796e3e31c18c3c1185cf /features/support/extra_hooks.rb | |
parent | 26a9e8ec2bcae03db4d663d87b44d8708d64fdc2 (diff) | |
download | jenkins.debian.net-da080c472fc415b0ce918f4dd4a1ab143bb1bca4.tar.xz |
rough attempt to grab the good cucumber bits from recent tails
Diffstat (limited to 'features/support/extra_hooks.rb')
-rw-r--r-- | features/support/extra_hooks.rb | 144 |
1 files changed, 132 insertions, 12 deletions
diff --git a/features/support/extra_hooks.rb b/features/support/extra_hooks.rb index a8addb35..16196a55 100644 --- a/features/support/extra_hooks.rb +++ b/features/support/extra_hooks.rb @@ -1,8 +1,28 @@ -require 'cucumber/formatter/pretty' +# Make the code below work with cucumber >= 2.0. Once we stop +# supporting <2.0 we should probably do this differently, but this way +# we can easily support both at the same time. +begin + if not(Cucumber::Core::Ast::Feature.instance_methods.include?(:accept_hook?)) + require 'gherkin/tag_expression' + class Cucumber::Core::Ast::Feature + # Code inspired by Cucumber::Core::Test::Case.match_tags?() in + # cucumber-ruby-core 1.1.3, lib/cucumber/core/test/case.rb:~59. + def accept_hook?(hook) + tag_expr = Gherkin::TagExpression.new(hook.tag_expressions.flatten) + tags = @tags.map do |t| + Gherkin::Formatter::Model::Tag.new(t.name, t.line) + end + tag_expr.evaluate(tags) + end + end + end +rescue NameError => e + raise e if e.to_s != "uninitialized constant Cucumber::Core" +end -# Sort of inspired by Cucumber::RbSupport::RbHook, but really we just -# want an object with a 'tag_expressions' attribute to make -# accept_hook?() (used below) happy. +# Sort of inspired by Cucumber::RbSupport::RbHook (from cucumber +# < 2.0) but really we just want an object with a 'tag_expressions' +# attribute to make accept_hook?() (used below) happy. class SimpleHook attr_reader :tag_expressions @@ -26,20 +46,120 @@ def AfterFeature(*tag_expressions, &block) $after_feature_hooks << SimpleHook.new(tag_expressions, block) end -module ExtraHooks - class Pretty < Cucumber::Formatter::Pretty +require 'cucumber/formatter/console' +if not($at_exit_print_artifacts_dir_patching_done) + module Cucumber::Formatter::Console + if method_defined?(:print_stats) + alias old_print_stats print_stats + end + def print_stats(*args) + if Dir.exists?(ARTIFACTS_DIR) and Dir.entries(ARTIFACTS_DIR).size > 2 + @io.puts "Artifacts directory: #{ARTIFACTS_DIR}" + @io.puts + end + if self.class.method_defined?(:old_print_stats) + old_print_stats(*args) + end + end + end + $at_exit_print_artifacts_dir_patching_done = true +end + +def info_log(message = "", options = {}) + options[:color] = :clear + # This trick allows us to use a module's (~private) method on a + # one-off basis. + cucumber_console = Class.new.extend(Cucumber::Formatter::Console) + puts cucumber_console.format_string(message, options[:color]) +end + +def debug_log(message, options = {}) + $debug_log_fns.each { |fn| fn.call(message, options) } if $debug_log_fns +end + +require 'cucumber/formatter/pretty' +# Backport part of commit af940a8 from the cucumber-ruby repo. This +# fixes the "out hook output" for the Pretty formatter so stuff +# written via `puts` after a Scenario has run its last step will be +# written, instead of delayed to the next Feature/Scenario (if any) or +# dropped completely (if not). +# XXX: This can be removed once we stop supporting Debian Jessie +# around when Debian Stretch is released. +if Gem::Version.new(Cucumber::VERSION) < Gem::Version.new('2.0.0.beta.4') + module Cucumber + module Formatter + class Pretty + def after_feature_element(feature_element) + print_messages + @io.puts + @io.flush + end + end + end + end +end + +module ExtraFormatters + # This is a null formatter in the sense that it doesn't ever output + # anything. We only use it do hook into the correct events so we can + # add our extra hooks. + class ExtraHooks + def initialize(*args) + # We do not care about any of the arguments. + end + def before_feature(feature) - for hook in $before_feature_hooks do - hook.invoke(feature) if feature.accept_hook?(hook) + if $before_feature_hooks + $before_feature_hooks.each do |hook| + hook.invoke(feature) if feature.accept_hook?(hook) + end end - super if defined?(super) end def after_feature(feature) - for hook in $after_feature_hooks do - hook.invoke(feature) if feature.accept_hook?(hook) + if $after_feature_hooks + $after_feature_hooks.reverse.each do |hook| + hook.invoke(feature) if feature.accept_hook?(hook) + end end - super if defined?(super) end end + + # The pretty formatter with debug logging mixed into its output. + class PrettyDebug < Cucumber::Formatter::Pretty + def initialize(*args) + super(*args) + $debug_log_fns ||= [] + $debug_log_fns << self.method(:debug_log) + end + + def debug_log(message, options) + options[:color] ||= :blue + @io.puts(format_string(message, options[:color])) + @io.flush + end + end + +end + +module Cucumber + module Cli + class Options + BUILTIN_FORMATS['pretty_debug'] = + [ + 'ExtraFormatters::PrettyDebug', + 'Prints the feature with debugging information - in colours.' + ] + BUILTIN_FORMATS['debug'] = BUILTIN_FORMATS['pretty_debug'] + end + end +end + +AfterConfiguration do |config| + # Cucumber may read this file multiple times, and hence run this + # AfterConfiguration hook multiple times. We only want our + # ExtraHooks formatter to be loaded once, otherwise the hooks would + # be run miltiple times. + extra_hooks = ['ExtraFormatters::ExtraHooks', '/dev/null'] + config.formats << extra_hooks if not(config.formats.include?(extra_hooks)) end |