guard-cucumber 1.4.1 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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