guard-cucumber 1.4.1 → 1.5.1

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.
@@ -1,12 +1,10 @@
1
1
  module Guard
2
2
  class Cucumber
3
-
4
3
  # The inspector verifies of the changed paths are valid
5
4
  # for Guard::Cucumber.
6
5
  #
7
6
  module Inspector
8
7
  class << self
9
-
10
8
  # Clean the changed paths and return only valid
11
9
  # Cucumber features.
12
10
  #
@@ -14,10 +12,12 @@ module Guard
14
12
  # @param [Array<String>] feature_sets the feature sets
15
13
  # @return [Array<String>] the valid feature files
16
14
  #
17
- def clean(paths, feature_sets)
15
+ def clean(paths, sets)
18
16
  paths.uniq!
19
17
  paths.compact!
20
- paths = paths.select { |p| cucumber_file?(p, feature_sets) || cucumber_folder?(p, feature_sets) }
18
+ paths = paths.select do |p|
19
+ cucumber_file?(p, sets) || cucumber_folder?(p, sets)
20
+ end
21
21
  paths = paths.delete_if { |p| included_in_other_path?(p, paths) }
22
22
  clear_cucumber_files_list
23
23
  paths
@@ -32,7 +32,8 @@ module Guard
32
32
  # @return [Boolean] when the file is the feature folder
33
33
  #
34
34
  def cucumber_folder?(path, feature_sets)
35
- path.match(/^\/?(#{ feature_sets.join('|') })/) && !path.match(/\..+$/)
35
+ sets = feature_sets.join("|")
36
+ path.match(/^\/?(#{ sets })/) && !path.match(/\..+$/)
36
37
  end
37
38
 
38
39
  # Tests if the file is valid.
@@ -42,7 +43,7 @@ module Guard
42
43
  # @return [Boolean] when the file valid
43
44
  #
44
45
  def cucumber_file?(path, feature_sets)
45
- cucumber_files(feature_sets).include?(path.split(':').first)
46
+ cucumber_files(feature_sets).include?(path.split(":").first)
46
47
  end
47
48
 
48
49
  # Scans the project and keeps a list of all
@@ -53,7 +54,8 @@ module Guard
53
54
  # @return [Array<String>] the valid files
54
55
  #
55
56
  def cucumber_files(feature_sets)
56
- @cucumber_files ||= Dir.glob("#{ feature_sets.join(',') }/**/*.feature")
57
+ glob = "#{ feature_sets.join(",") }/**/*.feature"
58
+ @cucumber_files ||= Dir.glob(glob)
57
59
  end
58
60
 
59
61
  # Clears the list of features in this project.
@@ -70,8 +72,16 @@ module Guard
70
72
  #
71
73
  def included_in_other_path?(path, paths)
72
74
  paths = paths.select { |p| p != path }
73
- massaged = path[0...(path.index(':') || path.size)]
74
- paths.any? { |p| (path.include?(p) && (path.gsub(p, '')).include?('/')) || massaged.include?(p) }
75
+ massaged = path[0...(path.index(":") || path.size)]
76
+ paths.any? { |p| _path_includes(path, p, massaged) }
77
+ end
78
+
79
+ private
80
+
81
+ def _path_includes(path, p, massaged)
82
+ includes = path.include?(p)
83
+ return true if includes && path.gsub(p, "").include?("/")
84
+ massaged.include?(p)
75
85
  end
76
86
  end
77
87
  end
@@ -0,0 +1,77 @@
1
+ module Guard
2
+ class Cucumber
3
+ # The inspector verifies of the changed paths are valid
4
+ # for Guard::Cucumber.
5
+ #
6
+ module Inspector
7
+ class << self
8
+ # Clean the changed paths and return only valid
9
+ # Cucumber features.
10
+ #
11
+ # @param [Array<String>] paths the changed paths
12
+ # @param [Array<String>] feature_sets the feature sets
13
+ # @return [Array<String>] the valid feature files
14
+ #
15
+ def clean(paths, feature_sets)
16
+ paths.uniq!
17
+ paths.compact!
18
+ paths = paths.select { |p| cucumber_file?(p, feature_sets) || cucumber_folder?(p, feature_sets) }
19
+ paths = paths.delete_if { |p| included_in_other_path?(p, paths) }
20
+ clear_cucumber_files_list
21
+ paths
22
+ end
23
+
24
+ private
25
+
26
+ # Tests if the file is the features folder.
27
+ #
28
+ # @param [String] path the file
29
+ # @param [Array<String>] feature_sets the feature sets
30
+ # @return [Boolean] when the file is the feature folder
31
+ #
32
+ def cucumber_folder?(path, feature_sets)
33
+ path.match(/^\/?(#{ feature_sets.join('|') })/) && !path.match(/\..+$/)
34
+ end
35
+
36
+ # Tests if the file is valid.
37
+ #
38
+ # @param [String] path the file
39
+ # @param [Array<String>] feature_sets the feature sets
40
+ # @return [Boolean] when the file valid
41
+ #
42
+ def cucumber_file?(path, feature_sets)
43
+ cucumber_files(feature_sets).include?(path.split(":").first)
44
+ end
45
+
46
+ # Scans the project and keeps a list of all
47
+ # feature files in the `features` directory.
48
+ #
49
+ # @see #clear_jasmine_specs
50
+ # @param [Array<String>] feature_sets the feature sets
51
+ # @return [Array<String>] the valid files
52
+ #
53
+ def cucumber_files(feature_sets)
54
+ @cucumber_files ||= Dir.glob("#{ feature_sets.join(",") }/**/*.feature")
55
+ end
56
+
57
+ # Clears the list of features in this project.
58
+ #
59
+ def clear_cucumber_files_list
60
+ @cucumber_files = nil
61
+ end
62
+
63
+ # Checks if the given path is already contained
64
+ # in the paths list.
65
+ #
66
+ # @param [Sting] path the path to test
67
+ # @param [Array<String>] paths the list of paths
68
+ #
69
+ def included_in_other_path?(path, paths)
70
+ paths = paths.select { |p| p != path }
71
+ massaged = path[0...(path.index(":") || path.size)]
72
+ paths.any? { |p| (path.include?(p) && (path.gsub(p, "")).include?("/")) || massaged.include?(p) }
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -1,13 +1,13 @@
1
- require 'guard'
2
- require 'guard/notifier'
3
- require 'cucumber/formatter/console'
4
- require 'cucumber/formatter/io'
1
+ require "guard"
2
+ require "guard/notifier"
3
+ require "cucumber/formatter/console"
4
+ require "cucumber/formatter/io"
5
5
 
6
6
  module Guard
7
7
  class Cucumber
8
-
9
8
  # The notification formatter is a Cucumber formatter that Guard::Cucumber
10
- # passes to the Cucumber binary. It writes the `rerun.txt` file with the failed features
9
+ # passes to the Cucumber binary. It writes the `rerun.txt` file with the
10
+ # failed features
11
11
  # an creates system notifications.
12
12
  #
13
13
  # @see https://github.com/cucumber/cucumber/wiki/Custom-Formatters
@@ -23,7 +23,7 @@ module Guard
23
23
  # @param [String, IO] path_or_io the path or IO to the feature file
24
24
  # @param [Hash] options the options
25
25
  #
26
- def initialize(step_mother, path_or_io, options)
26
+ def initialize(step_mother, _path_or_io, options)
27
27
  @options = options
28
28
  @file_names = []
29
29
  @step_mother = step_mother
@@ -33,7 +33,7 @@ module Guard
33
33
  #
34
34
  # @param [Array[Cucumber::Ast::Feature]] features the ran features
35
35
  #
36
- def after_features(features)
36
+ def after_features(_features)
37
37
  notify_summary
38
38
  write_rerun_features if !@file_names.empty?
39
39
  end
@@ -53,7 +53,7 @@ module Guard
53
53
  #
54
54
  def after_feature_element(feature_element)
55
55
  if @rerun
56
- @file_names << feature_element.file_colon_line
56
+ @file_names << feature_element.location.to_s
57
57
  @rerun = false
58
58
  end
59
59
  end
@@ -65,14 +65,16 @@ module Guard
65
65
  # @param [Symbol] status the status of the step
66
66
  # @param [Integer] source_indent the source indentation
67
67
  # @param [Cucumber::Ast::Background] background the feature background
68
- # @param [String] file name and line number describing where the step is used
68
+ # @param [String] file name and line number describing where the step is
69
+ # used
69
70
  #
70
- def step_name(keyword, step_match, status, source_indent, background, file_colon_line)
71
+ def step_name(_keyword, step_match, status, _src_indent, _bckgnd, _loc)
71
72
  if [:failed, :pending, :undefined].index(status)
72
73
  @rerun = true
73
74
  step_name = step_match.format_args(lambda { |param| "*#{ param }*" })
74
75
 
75
- ::Guard::Notifier.notify step_name, :title => @feature_name, :image => icon_for(status)
76
+ options = { title: @feature_name, image: icon_for(status) }
77
+ ::Guard::Notifier.notify(step_name, options)
76
78
  end
77
79
  end
78
80
 
@@ -84,22 +86,25 @@ module Guard
84
86
  def notify_summary
85
87
  icon, messages = nil, []
86
88
 
87
- [:failed, :skipped, :undefined, :pending, :passed].reverse.each do |status|
89
+ [:failed, :skipped, :undefined, :pending, :passed].reverse.
90
+ each do |status|
88
91
  if step_mother.steps(status).any?
89
92
  step_icon = icon_for(status)
90
93
  icon = step_icon if step_icon
91
- messages << dump_count(step_mother.steps(status).length, 'step', status.to_s)
94
+ len = step_mother.steps(status).length
95
+ messages << dump_count(len, "step", status.to_s)
92
96
  end
93
97
  end
94
98
 
95
- ::Guard::Notifier.notify messages.reverse.join(', '), :title => 'Cucumber Results', :image => icon
99
+ msg = messages.reverse.join(", ")
100
+ ::Guard::Notifier.notify msg, title: "Cucumber Results", image: icon
96
101
  end
97
102
 
98
103
  # Writes the `rerun.txt` file containing all failed features.
99
104
  #
100
105
  def write_rerun_features
101
- File.open('rerun.txt', 'w') do |f|
102
- f.puts @file_names.join(' ')
106
+ File.open("rerun.txt", "w") do |f|
107
+ f.puts @file_names.join(" ")
103
108
  end
104
109
  end
105
110
 
@@ -110,17 +115,16 @@ module Guard
110
115
  #
111
116
  def icon_for(status)
112
117
  case status
113
- when :passed
114
- :success
115
- when :pending, :undefined, :skipped
116
- :pending
117
- when :failed
118
- :failed
119
- else
120
- nil
118
+ when :passed
119
+ :success
120
+ when :pending, :undefined, :skipped
121
+ :pending
122
+ when :failed
123
+ :failed
124
+ else
125
+ nil
121
126
  end
122
127
  end
123
-
124
128
  end
125
129
  end
126
130
  end
@@ -0,0 +1,124 @@
1
+ require "guard"
2
+ require "guard/notifier"
3
+ require "cucumber/formatter/console"
4
+ require "cucumber/formatter/io"
5
+
6
+ module Guard
7
+ class Cucumber
8
+ # The notification formatter is a Cucumber formatter that Guard::Cucumber
9
+ # passes to the Cucumber binary. It writes the `rerun.txt` file with the failed features
10
+ # an creates system notifications.
11
+ #
12
+ # @see https://github.com/cucumber/cucumber/wiki/Custom-Formatters
13
+ #
14
+ class NotificationFormatter
15
+ include ::Cucumber::Formatter::Console
16
+
17
+ attr_reader :step_mother
18
+
19
+ # Initialize the formatter.
20
+ #
21
+ # @param [Cucumber::Runtime] step_mother the step mother
22
+ # @param [String, IO] path_or_io the path or IO to the feature file
23
+ # @param [Hash] options the options
24
+ #
25
+ def initialize(step_mother, _path_or_io, options)
26
+ @options = options
27
+ @file_names = []
28
+ @step_mother = step_mother
29
+ end
30
+
31
+ # Notification after all features have completed.
32
+ #
33
+ # @param [Array[Cucumber::Ast::Feature]] features the ran features
34
+ #
35
+ def after_features(_features)
36
+ notify_summary
37
+ write_rerun_features if !@file_names.empty?
38
+ end
39
+
40
+ # Before a feature gets run.
41
+ #
42
+ # @param [Cucumber::Ast::FeatureElement] feature_element
43
+ #
44
+ def before_feature_element(feature_element)
45
+ @rerun = false
46
+ @feature_name = feature_element.name
47
+ end
48
+
49
+ # After a feature gets run.
50
+ #
51
+ # @param [Cucumber::Ast::FeatureElement] feature_element
52
+ #
53
+ def after_feature_element(feature_element)
54
+ if @rerun
55
+ @file_names << feature_element.location.to_s
56
+ @rerun = false
57
+ end
58
+ end
59
+
60
+ # Gets called when a step is done.
61
+ #
62
+ # @param [String] keyword the keyword
63
+ # @param [Cucumber::StepMatch] step_match the step match
64
+ # @param [Symbol] status the status of the step
65
+ # @param [Integer] source_indent the source indentation
66
+ # @param [Cucumber::Ast::Background] background the feature background
67
+ # @param [String] file name and line number describing where the step is used
68
+ #
69
+ def step_name(_keyword, step_match, status, _source_indent, _background, _location)
70
+ if [:failed, :pending, :undefined].index(status)
71
+ @rerun = true
72
+ step_name = step_match.format_args(lambda { |param| "*#{ param }*" })
73
+
74
+ ::Guard::Notifier.notify step_name, title: @feature_name, image: icon_for(status)
75
+ end
76
+ end
77
+
78
+ private
79
+
80
+ # Notify the user with a system notification about the
81
+ # result of the feature tests.
82
+ #
83
+ def notify_summary
84
+ icon, messages = nil, []
85
+
86
+ [:failed, :skipped, :undefined, :pending, :passed].reverse.each do |status|
87
+ if step_mother.steps(status).any?
88
+ step_icon = icon_for(status)
89
+ icon = step_icon if step_icon
90
+ messages << dump_count(step_mother.steps(status).length, "step", status.to_s)
91
+ end
92
+ end
93
+
94
+ ::Guard::Notifier.notify messages.reverse.join(", "), title: "Cucumber Results", image: icon
95
+ end
96
+
97
+ # Writes the `rerun.txt` file containing all failed features.
98
+ #
99
+ def write_rerun_features
100
+ File.open("rerun.txt", "w") do |f|
101
+ f.puts @file_names.join(" ")
102
+ end
103
+ end
104
+
105
+ # Gives the icon name to use for the status.
106
+ #
107
+ # @param [Symbol] status the cucumber status
108
+ # @return [Symbol] the Guard notification symbol
109
+ #
110
+ def icon_for(status)
111
+ case status
112
+ when :passed
113
+ :success
114
+ when :pending, :undefined, :skipped
115
+ :pending
116
+ when :failed
117
+ :failed
118
+ else
119
+ nil
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -1,31 +1,41 @@
1
1
  module Guard
2
2
  class Cucumber
3
-
4
3
  # The Cucumber runner handles the execution of the cucumber binary.
5
4
  #
6
5
  module Runner
7
6
  class << self
8
-
9
7
  # Run the supplied features.
10
8
  #
11
9
  # @param [Array<String>] paths the feature files or directories
12
10
  # @param [Hash] options the options for the execution
13
- # @option options [Array<String>] :feature_sets a list of non-standard feature directory/ies
11
+ # @option options [Array<String>] :feature_sets a list of non-standard
12
+ # feature directory/ies
14
13
  # @option options [Boolean] :bundler use bundler or not
15
- # @option options [Array<String>] :rvm a list of rvm version to use for the test
14
+ # @option options [Array<String>] :rvm a list of rvm version to use for
15
+ # the test
16
16
  # @option options [Boolean] :notification show notifications
17
- # @option options [String] :command_prefix allows adding an additional prefix to the cucumber command. Ideal for running xvfb-run for terminal only cucumber tests.
17
+ # @option options [String] :command_prefix allows adding an additional
18
+ # prefix to the cucumber command. Ideal for running xvfb-run for
19
+ # terminal only cucumber tests.
18
20
  # @return [Boolean] the status of the execution
19
21
  #
20
- def run(paths, options = { })
22
+ def run(paths, options = {})
21
23
  return false if paths.empty?
22
24
 
23
- message = options[:message] || (paths == ['features'] ? "Running all Cucumber features: #{ cucumber_command(paths, options) }" : "Running Cucumber features: #{ cucumber_command(paths, options) }")
24
- paths = options[:focus_on] ? Focuser.focus(paths, options[:focus_on]) : paths
25
+ cmd = cucumber_command(paths, options)
26
+
27
+ msg1 = "Running all Cucumber features: #{cmd}"
28
+ msg2 = "Running Cucumber features: #{cmd}"
29
+ msg = (paths == ["features"] ? msg1 : msg2)
25
30
 
26
- UI.info message, :reset => true
31
+ message = options[:message] || msg
27
32
 
28
- system(cucumber_command(paths, options))
33
+ paths = Focuser.focus(paths, options[:focus_on]) if options[:focus_on]
34
+ cmd = cucumber_command(paths, options)
35
+
36
+ UI.info message, reset: true
37
+
38
+ system(cmd)
29
39
  end
30
40
 
31
41
  private
@@ -35,28 +45,30 @@ module Guard
35
45
  # @param [Array<String>] paths the feature files or directories
36
46
  # @param [Hash] options the options for the execution
37
47
  # @option options [Boolean] :bundler use bundler or not
38
- # @option options [Array<String>] :rvm a list of rvm version to use for the test
48
+ # @option options [Array<String>] :rvm a list of rvm version to use for
49
+ # the test
39
50
  # @option options [Boolean] :notification show notifications
40
- # @option options [String] :command_prefix allows adding an additional prefix to the cucumber command. Ideal for running xvfb-run for terminal only cucumber tests.
51
+ # @option options [String] :command_prefix allows adding an additional
52
+ # prefix to the cucumber command. Ideal for running xvfb-run for
53
+ # terminal only cucumber tests.
41
54
  # @return [String] the Cucumber command
42
55
  #
43
56
  def cucumber_command(paths, options)
44
57
  cmd = []
45
58
  cmd << options[:command_prefix] if options[:command_prefix]
46
- cmd << "rvm #{ options[:rvm].join(',') } exec" if options[:rvm].is_a?(Array)
47
- cmd << 'bundle exec' if bundler? && options[:bundler] != false
59
+ if options[:rvm].is_a?(Array)
60
+ cmd << "rvm #{ options[:rvm].join(",") } exec"
61
+ end
62
+
63
+ cmd << "bundle exec" if bundler? && options[:bundler] != false
48
64
  cmd << cucumber_exec(options)
49
65
  cmd << options[:cli] if options[:cli]
50
66
 
51
67
  if options[:notification] != false
52
- notification_formatter_path = File.expand_path(File.join(File.dirname(__FILE__), 'notification_formatter.rb'))
53
- cmd << "--require #{ notification_formatter_path }"
54
- cmd << '--format Guard::Cucumber::NotificationFormatter'
55
- cmd << "--out #{ null_device }"
56
- cmd << (options[:feature_sets] || ['features']).map {|path| "--require #{ path }"}.join(' ')
68
+ _add_notification(cmd, options)
57
69
  end
58
70
 
59
- (cmd + paths).join(' ')
71
+ (cmd + paths).join(" ")
60
72
  end
61
73
 
62
74
  # Simple test if binstubs prefix should be used.
@@ -64,10 +76,11 @@ module Guard
64
76
  # @return [String] Cucumber executable
65
77
  #
66
78
  def cucumber_exec(options = {})
67
- options[:binstubs] == true ? 'bin/cucumber' : 'cucumber'
79
+ options[:binstubs] == true ? "bin/cucumber" : "cucumber"
68
80
  end
69
81
 
70
- # Simple test if bundler should be used. it just checks for the `Gemfile`.
82
+ # Simple test if bundler should be used. it just checks for the
83
+ # `Gemfile`.
71
84
  #
72
85
  # @return [Boolean] bundler exists
73
86
  #
@@ -80,9 +93,23 @@ module Guard
80
93
  # @return [String] the name of the null device
81
94
  #
82
95
  def null_device
83
- RUBY_PLATFORM.index('mswin') ? 'NUL' : '/dev/null'
96
+ RUBY_PLATFORM.index("mswin") ? "NUL" : "/dev/null"
84
97
  end
85
98
 
99
+ private
100
+
101
+ def _add_notification(cmd, options)
102
+ this_dir = File.dirname(__FILE__)
103
+ formatter_path = File.join(this_dir, "notification_formatter.rb")
104
+ notification_formatter_path = File.expand_path(formatter_path)
105
+
106
+ cmd << "--require #{ notification_formatter_path }"
107
+ cmd << "--format Guard::Cucumber::NotificationFormatter"
108
+ cmd << "--out #{ null_device }"
109
+ cmd << (options[:feature_sets] || ["features"]).map do |path|
110
+ "--require #{ path }"
111
+ end.join(" ")
112
+ end
86
113
  end
87
114
  end
88
115
  end