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.
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