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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1f72a3ec6a6f5ceb0bbd3b399b91e81f060a8c25
4
- data.tar.gz: 69a4be70567b57dab0fb5b521037ea7ec106e4a2
3
+ metadata.gz: 446cce06cfc0d77430a6b6c7e3ce31b76325ca71
4
+ data.tar.gz: 9544582765bbb7025dfadb2a88bd3b8114e6ed45
5
5
  SHA512:
6
- metadata.gz: 0d9ac346adf2447c5679d8456b0cb142c810ea5e193a32adf6e7b3f37a0d361ad223045eba69d771e355b78611508b4fe517aaec20d3ce5edbbbf442f7e06dcc
7
- data.tar.gz: 1c9688451ce35651b0f36ea7b9c46d7a29d840f6e02c0d7ba60a313a99fc4d3cbcb7357cda1ff06d201fa0ffd968bfa176144c47f3903e1bf0a7d34543a59b94
6
+ metadata.gz: 6ab8153c6cdcd1090baca18e1d1ef3a35ee609b6459fcd7c0ada3b6828d0a44963b5af0de79268641b29e11901ea3cb3f68a2130325d6bdbe13f8123e36f3025
7
+ data.tar.gz: e7cb7a1c69c3b507eb65f068ee642a778cd6ba3c1d92c1c0f7944e0f3974c3334126ede5c758c2182d61822d1d237fbba9c66d9f37e28c0c361ab7620b1978e4
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Guard::Cucumber allows you to automatically run Cucumber features when files are modified.
4
4
 
5
- Tested on MRI Ruby 1.8.7, 1.9.2, 1.9.3, REE and the latest versions of JRuby & Rubinius.
5
+ Tested on MRI Ruby 1.9.3, 2.0.0, 2.1.0 and the latest versions of JRuby.
6
6
 
7
7
  If you have any questions please join us on our [Google group](http://groups.google.com/group/guard-dev) or on `#guard` (irc.freenode.net).
8
8
 
@@ -131,7 +131,7 @@ Since guard-cucumber version 0.3.2, the default `:cli` options are:
131
131
  :cli => '--no-profile --color --format progress --strict'
132
132
  ```
133
133
 
134
- This default configuration has been chosen to avoid strange behavior when mixing configurations form
134
+ This default configuration has been chosen to avoid strange behavior when mixing configurations from
135
135
  the cucumber.yml default profile with the guard-cucumber `:cli` option.
136
136
 
137
137
  You can safely remove `config/cucumber.yml`, since all configuration is done in the `Guardfile`.
@@ -226,7 +226,7 @@ For questions please join us in our [Google group](http://groups.google.com/grou
226
226
 
227
227
  ## Author
228
228
 
229
- Developed by Michael Kessler, sponsored by [mksoft.ch](https://mksoft.ch).
229
+ Developed by Michael Kessler, sponsored by [FlinkFinger](http://www.flinkfinger.com).
230
230
 
231
231
  If you like Guard::Cucumber, you can watch the repository at [GitHub](https://github.com/netzpirat/guard-cucumber)
232
232
  and follow [@netzpirat](https://twitter.com/#!/netzpirat) on Twitter for project updates.
@@ -1,18 +1,16 @@
1
- require 'guard'
2
- require 'guard/guard'
3
- require 'cucumber'
4
- require 'guard/cucumber/version'
1
+ require "guard"
2
+ require "guard/plugin"
3
+ require "cucumber"
4
+ require "guard/cucumber/version"
5
5
 
6
6
  module Guard
7
-
8
7
  # The Cucumber guard that gets notifications about the following
9
8
  # Guard events: `start`, `stop`, `reload`, `run_all` and `run_on_change`.
10
9
  #
11
- class Cucumber < Guard
12
-
13
- autoload :Runner, 'guard/cucumber/runner'
14
- autoload :Inspector, 'guard/cucumber/inspector'
15
- autoload :Focuser, 'guard/cucumber/focuser'
10
+ class Cucumber < Plugin
11
+ autoload :Runner, "guard/cucumber/runner"
12
+ autoload :Inspector, "guard/cucumber/inspector"
13
+ autoload :Focuser, "guard/cucumber/focuser"
16
14
 
17
15
  attr_accessor :last_failed, :failed_path
18
16
 
@@ -21,25 +19,31 @@ module Guard
21
19
  # @param [Array<Guard::Watcher>] watchers the watchers in the Guard block
22
20
  # @param [Hash] options the options for the Guard
23
21
  # @option options [String] :cli any arbitrary Cucumber CLI arguments
24
- # @option options [Array<String>] :feature_sets a list of non-standard feature directory/ies
22
+ # @option options [Array<String>] :feature_sets a list of non-standard
23
+ # feature directory/ies
25
24
  # @option options [Boolean] :bundler use bundler or not
26
- # @option options [Array<String>] :rvm a list of rvm version to use for the test
25
+ # @option options [Array<String>] :rvm a list of rvm version to use for the
26
+ # test
27
27
  # @option options [Boolean] :notification show notifications
28
- # @option options [Boolean] :all_after_pass run all features after changed features pass
28
+ # @option options [Boolean] :all_after_pass run all features after changed
29
+ # features pass
29
30
  # @option options [Boolean] :all_on_start run all the features at startup
30
- # @option options [Boolean] :keep_failed Keep failed features until they pass
31
- # @option options [Boolean] :run_all run override any option when running all specs
32
- # @option options [Boolean] :change_format use a different cucumber format when running individual features
31
+ # @option options [Boolean] :keep_failed Keep failed features until they
32
+ # pass
33
+ # @option options [Boolean] :run_all run override any option when running
34
+ # all specs
35
+ # @option options [Boolean] :change_format use a different cucumber format
36
+ # when running individual features
33
37
  #
34
- def initialize(watchers = [], options = { })
35
- super
38
+ def initialize(options = {})
39
+ super(options)
36
40
 
37
41
  @options = {
38
- :all_after_pass => true,
39
- :all_on_start => true,
40
- :keep_failed => true,
41
- :cli => '--no-profile --color --format progress --strict',
42
- :feature_sets => ['features']
42
+ all_after_pass: true,
43
+ all_on_start: true,
44
+ keep_failed: true,
45
+ cli: "--no-profile --color --format progress --strict",
46
+ feature_sets: ["features"]
43
47
  }.update(options)
44
48
 
45
49
  @last_failed = false
@@ -59,7 +63,9 @@ module Guard
59
63
  # @raise [:task_has_failed] when stop has failed
60
64
  #
61
65
  def run_all
62
- passed = Runner.run(options[:feature_sets], options.merge(options[:run_all] || { }).merge(:message => 'Running all features'))
66
+ opts = options.merge(options[:run_all] || {})
67
+ opts.merge!(message: "Running all features")
68
+ passed = Runner.run(options[:feature_sets], opts)
63
69
 
64
70
  if passed
65
71
  @failed_paths = []
@@ -87,23 +93,17 @@ module Guard
87
93
  #
88
94
  def run_on_modifications(paths)
89
95
  paths += @failed_paths if @options[:keep_failed]
90
- paths = Inspector.clean(paths, options[:feature_sets])
91
- options = @options[:change_format] ? change_format(@options[:change_format]) : @options
92
- passed = Runner.run(paths, paths.include?('features') ? options.merge({ :message => 'Running all features' }) : options)
96
+ paths = Inspector.clean(paths, options[:feature_sets])
93
97
 
94
- if passed
95
- # clean failed paths memory
96
- @failed_paths -= paths if @options[:keep_failed]
97
- # run all the specs if the changed specs failed, like autotest
98
- run_all if @last_failed && @options[:all_after_pass]
99
- else
100
- # remember failed paths for the next change
101
- @failed_paths += read_failed_features if @options[:keep_failed]
102
- # track whether the changed feature failed for the next change
103
- @last_failed = true
98
+ options = @options
99
+ if @options[:change_format]
100
+ options = change_format(@options[:change_format])
104
101
  end
105
102
 
106
- throw :task_has_failed unless passed
103
+ msg = "Running all features"
104
+ options.merge!(message: msg) if paths.include?("features")
105
+
106
+ _run(paths, options)
107
107
  end
108
108
 
109
109
  private
@@ -116,9 +116,9 @@ module Guard
116
116
  def read_failed_features
117
117
  failed = []
118
118
 
119
- if File.exist?('rerun.txt')
120
- failed = File.open('rerun.txt') { |file| file.read.split(' ') }
121
- File.delete('rerun.txt')
119
+ if File.exist?("rerun.txt")
120
+ failed = File.open("rerun.txt") { |file| file.read.split(" ") }
121
+ File.delete("rerun.txt")
122
122
  end
123
123
 
124
124
  failed
@@ -130,14 +130,31 @@ module Guard
130
130
  # @return [Hash] the new options
131
131
  #
132
132
  def change_format(format)
133
- cli_parts = @options[:cli].split(' ')
133
+ cli_parts = @options[:cli].split(" ")
134
134
  cli_parts.each_with_index do |part, index|
135
- if part == '--format' && cli_parts[index + 2] != '--out'
135
+ if part == "--format" && cli_parts[index + 2] != "--out"
136
136
  cli_parts[index + 1] = format
137
137
  end
138
138
  end
139
- @options.merge(:cli => cli_parts.join(' '))
139
+ @options.merge(cli: cli_parts.join(" "))
140
140
  end
141
141
 
142
+ private
143
+
144
+ def _run(paths, options)
145
+ if Runner.run(paths, options)
146
+ # clean failed paths memory
147
+ @failed_paths -= paths if @options[:keep_failed]
148
+ # run all the specs if the changed specs failed, like autotest
149
+ run_all if @last_failed && @options[:all_after_pass]
150
+ return
151
+ end
152
+
153
+ # remember failed paths for the next change
154
+ @failed_paths += read_failed_features if @options[:keep_failed]
155
+ # track whether the changed feature failed for the next change
156
+ @last_failed = true
157
+ throw :task_has_failed
158
+ end
142
159
  end
143
160
  end
@@ -0,0 +1,143 @@
1
+ require 'guard'
2
+ require 'guard/guard'
3
+ require 'cucumber'
4
+ require 'guard/cucumber/version'
5
+
6
+ module Guard
7
+
8
+ # The Cucumber guard that gets notifications about the following
9
+ # Guard events: `start`, `stop`, `reload`, `run_all` and `run_on_change`.
10
+ #
11
+ class Cucumber < Guard
12
+
13
+ autoload :Runner, 'guard/cucumber/runner'
14
+ autoload :Inspector, 'guard/cucumber/inspector'
15
+ autoload :Focuser, 'guard/cucumber/focuser'
16
+
17
+ attr_accessor :last_failed, :failed_path
18
+
19
+ # Initialize Guard::Cucumber.
20
+ #
21
+ # @param [Array<Guard::Watcher>] watchers the watchers in the Guard block
22
+ # @param [Hash] options the options for the Guard
23
+ # @option options [String] :cli any arbitrary Cucumber CLI arguments
24
+ # @option options [Array<String>] :feature_sets a list of non-standard feature directory/ies
25
+ # @option options [Boolean] :bundler use bundler or not
26
+ # @option options [Array<String>] :rvm a list of rvm version to use for the test
27
+ # @option options [Boolean] :notification show notifications
28
+ # @option options [Boolean] :all_after_pass run all features after changed features pass
29
+ # @option options [Boolean] :all_on_start run all the features at startup
30
+ # @option options [Boolean] :keep_failed Keep failed features until they pass
31
+ # @option options [Boolean] :run_all run override any option when running all specs
32
+ # @option options [Boolean] :change_format use a different cucumber format when running individual features
33
+ #
34
+ def initialize(watchers = [], options = { })
35
+ super
36
+
37
+ @options = {
38
+ :all_after_pass => true,
39
+ :all_on_start => true,
40
+ :keep_failed => true,
41
+ :cli => '--no-profile --color --format progress --strict',
42
+ :feature_sets => ['features']
43
+ }.update(options)
44
+
45
+ @last_failed = false
46
+ @failed_paths = []
47
+ end
48
+
49
+ # Gets called once when Guard starts.
50
+ #
51
+ # @raise [:task_has_failed] when stop has failed
52
+ #
53
+ def start
54
+ run_all if @options[:all_on_start]
55
+ end
56
+
57
+ # Gets called when all specs should be run.
58
+ #
59
+ # @raise [:task_has_failed] when stop has failed
60
+ #
61
+ def run_all
62
+ passed = Runner.run(options[:feature_sets], options.merge(options[:run_all] || { }).merge(:message => 'Running all features'))
63
+
64
+ if passed
65
+ @failed_paths = []
66
+ else
67
+ @failed_paths = read_failed_features if @options[:keep_failed]
68
+ end
69
+
70
+ @last_failed = !passed
71
+
72
+ throw :task_has_failed unless passed
73
+ end
74
+
75
+ # Gets called when the Guard should reload itself.
76
+ #
77
+ # @raise [:task_has_failed] when stop has failed
78
+ #
79
+ def reload
80
+ @failed_paths = []
81
+ end
82
+
83
+ # Gets called when watched paths and files have changes.
84
+ #
85
+ # @param [Array<String>] paths the changed paths and files
86
+ # @raise [:task_has_failed] when stop has failed
87
+ #
88
+ def run_on_modifications(paths)
89
+ paths += @failed_paths if @options[:keep_failed]
90
+ paths = Inspector.clean(paths, options[:feature_sets])
91
+ options = @options[:change_format] ? change_format(@options[:change_format]) : @options
92
+ passed = Runner.run(paths, paths.include?('features') ? options.merge({ :message => 'Running all features' }) : options)
93
+
94
+ if passed
95
+ # clean failed paths memory
96
+ @failed_paths -= paths if @options[:keep_failed]
97
+ # run all the specs if the changed specs failed, like autotest
98
+ run_all if @last_failed && @options[:all_after_pass]
99
+ else
100
+ # remember failed paths for the next change
101
+ @failed_paths += read_failed_features if @options[:keep_failed]
102
+ # track whether the changed feature failed for the next change
103
+ @last_failed = true
104
+ end
105
+
106
+ throw :task_has_failed unless passed
107
+ end
108
+
109
+ private
110
+
111
+ # Read the failed features that from `rerun.txt`
112
+ #
113
+ # @see Guard::Cucumber::NotificationFormatter#write_rerun_features
114
+ # @return [Array<String>] the list of features
115
+ #
116
+ def read_failed_features
117
+ failed = []
118
+
119
+ if File.exist?('rerun.txt')
120
+ failed = File.open('rerun.txt') { |file| file.read.split(' ') }
121
+ File.delete('rerun.txt')
122
+ end
123
+
124
+ failed
125
+ end
126
+
127
+ # Change the `--format` cli option.
128
+ #
129
+ # @param [String] format the new format
130
+ # @return [Hash] the new options
131
+ #
132
+ def change_format(format)
133
+ cli_parts = @options[:cli].split(' ')
134
+ cli_parts.each_with_index do |part, index|
135
+ if part == '--format' && cli_parts[index + 2] != '--out'
136
+ cli_parts[index + 1] = format
137
+ end
138
+ end
139
+ @options.merge(:cli => cli_parts.join(' '))
140
+ end
141
+
142
+ end
143
+ end
@@ -1,6 +1,5 @@
1
1
  module Guard
2
2
  class Cucumber
3
-
4
3
  # The Cucumber focuser updates cucumber feature paths to
5
4
  # focus on sections tagged with a provided focus_tag.
6
5
  #
@@ -18,7 +17,6 @@ module Guard
18
17
  #
19
18
  module Focuser
20
19
  class << self
21
-
22
20
  # Focus the supplied paths using the provided focus tag.
23
21
  #
24
22
  # @param [Array<String>] paths the locations of the feature files
@@ -31,12 +29,12 @@ module Guard
31
29
  paths.inject([]) do |updated_paths, path|
32
30
  focused_line_numbers = scan_path_for_focus_tag(path, focus_tag)
33
31
 
34
- unless focused_line_numbers.empty?
32
+ if focused_line_numbers.empty?
33
+ updated_paths << path
34
+ else
35
35
  updated_paths << append_line_numbers_to_path(
36
36
  focused_line_numbers, path
37
37
  )
38
- else
39
- updated_paths << path
40
38
  end
41
39
 
42
40
  updated_paths
@@ -48,14 +46,15 @@ module Guard
48
46
  #
49
47
  # @param [String] path the file path to search
50
48
  # @param [String] focus_tag the focus tag to look for in each path
51
- # @return [Array<Integer>] the line numbers that include the focus tag in path
49
+ # @return [Array<Integer>] the line numbers that include the focus tag
50
+ # in path
52
51
  #
53
52
  def scan_path_for_focus_tag(path, focus_tag)
54
- return [] if File.directory?(path) || path.include?(':')
53
+ return [] if File.directory?(path) || path.include?(":")
55
54
 
56
55
  line_numbers = []
57
56
 
58
- File.open(path, 'r') do |file|
57
+ File.open(path, "r") do |file|
59
58
  while (line = file.gets)
60
59
  if line.include?(focus_tag)
61
60
  line_numbers << file.lineno
@@ -68,16 +67,18 @@ module Guard
68
67
 
69
68
  # Appends the line numbers to the path
70
69
  #
71
- # @param [Array<Integer>] line_numbers the line numbers to append to the path
72
- # @param [String] path the path that will receive the appended line numbers
73
- # @return [String] the string containing the path appended with the line number
70
+ # @param [Array<Integer>] line_numbers the line numbers to append to
71
+ # the path
72
+ # @param [String] path the path that will receive the appended line
73
+ # numbers
74
+ # @return [String] the string containing the path appended with the
75
+ # line number
74
76
  #
75
77
  def append_line_numbers_to_path(line_numbers, path)
76
- line_numbers.each { |num| path += ':' + num.to_s }
78
+ line_numbers.each { |num| path += ":" + num.to_s }
77
79
 
78
80
  path
79
81
  end
80
-
81
82
  end
82
83
  end
83
84
  end
@@ -0,0 +1,81 @@
1
+ module Guard
2
+ class Cucumber
3
+ # The Cucumber focuser updates cucumber feature paths to
4
+ # focus on sections tagged with a provided focus_tag.
5
+ #
6
+ # For example, if the `foo.feature` file has the provided focus tag
7
+ # `@bar` on line 8, then the path will be updated using the cucumber
8
+ # syntax for focusing on a section:
9
+ #
10
+ # foo.feature:8
11
+ #
12
+ # If '@bar' is found on lines 8 and 16, the path is updated as follows:
13
+ #
14
+ # foo.feature:8:16
15
+ #
16
+ # The path is not updated if it does not contain the focus tag.
17
+ #
18
+ module Focuser
19
+ class << self
20
+ # Focus the supplied paths using the provided focus tag.
21
+ #
22
+ # @param [Array<String>] paths the locations of the feature files
23
+ # @param [String] focus_tag the focus tag to look for in each path
24
+ # @return [Array<String>] the updated paths
25
+ #
26
+ def focus(paths, focus_tag)
27
+ return false if paths.empty?
28
+
29
+ paths.inject([]) do |updated_paths, path|
30
+ focused_line_numbers = scan_path_for_focus_tag(path, focus_tag)
31
+
32
+ unless focused_line_numbers.empty?
33
+ updated_paths << append_line_numbers_to_path(
34
+ focused_line_numbers, path
35
+ )
36
+ else
37
+ updated_paths << path
38
+ end
39
+
40
+ updated_paths
41
+ end
42
+ end
43
+
44
+ # Checks to see if the file at path contains the focus tag
45
+ # It will return an empty array if the path is a directory.
46
+ #
47
+ # @param [String] path the file path to search
48
+ # @param [String] focus_tag the focus tag to look for in each path
49
+ # @return [Array<Integer>] the line numbers that include the focus tag in path
50
+ #
51
+ def scan_path_for_focus_tag(path, focus_tag)
52
+ return [] if File.directory?(path) || path.include?(":")
53
+
54
+ line_numbers = []
55
+
56
+ File.open(path, "r") do |file|
57
+ while (line = file.gets)
58
+ if line.include?(focus_tag)
59
+ line_numbers << file.lineno
60
+ end
61
+ end
62
+ end
63
+
64
+ line_numbers
65
+ end
66
+
67
+ # Appends the line numbers to the path
68
+ #
69
+ # @param [Array<Integer>] line_numbers the line numbers to append to the path
70
+ # @param [String] path the path that will receive the appended line numbers
71
+ # @return [String] the string containing the path appended with the line number
72
+ #
73
+ def append_line_numbers_to_path(line_numbers, path)
74
+ line_numbers.each { |num| path += ":" + num.to_s }
75
+
76
+ path
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end