guard-cucumber 1.5.1 → 1.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/guard/cucumber.rb +3 -6
- data/lib/guard/cucumber/focuser.rb +1 -1
- data/lib/guard/cucumber/inspector.rb +2 -2
- data/lib/guard/cucumber/notification_formatter.rb +21 -23
- data/lib/guard/cucumber/runner.rb +26 -13
- data/lib/guard/cucumber/version.rb +1 -1
- metadata +49 -13
- data/lib/guard/cucumber.rb.orig +0 -143
- data/lib/guard/cucumber/focuser.rb.orig +0 -81
- data/lib/guard/cucumber/inspector.rb.orig +0 -77
- data/lib/guard/cucumber/notification_formatter.rb.orig +0 -124
- data/lib/guard/cucumber/runner.rb.orig +0 -86
- data/lib/guard/cucumber/templates/Guardfile.orig +0 -5
- data/lib/guard/cucumber/version.rb.orig +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0704aa52cb9a9fb9d66551e7c7e94228e4d1d6a7
|
4
|
+
data.tar.gz: 44ed558e01dd8a58cdec06592dd45c734de3f364
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: da8a3b2e69f13764c5cd7b90520a4fa6202dc7fbcd4dad90249c7cb15cb2fc98dc05d94dd11e5b3dda78871634433a856958e2fd8a5924a5dea67f9edd0c1b8e
|
7
|
+
data.tar.gz: 30961c25953da600d5902220da634f563c027fa82be7f06b403199b7b7c50dd3c4d6be17078a95daf1b66eb02c55b67d421f5b5e6f17befa4fa1c3af8058bbf0
|
data/lib/guard/cucumber.rb
CHANGED
@@ -1,17 +1,14 @@
|
|
1
|
-
require "guard"
|
2
|
-
require "guard/plugin"
|
3
1
|
require "cucumber"
|
4
2
|
require "guard/cucumber/version"
|
3
|
+
require "guard/cucumber/runner"
|
4
|
+
require "guard/cucumber/inspector"
|
5
|
+
require "guard/cucumber/focuser"
|
5
6
|
|
6
7
|
module Guard
|
7
8
|
# The Cucumber guard that gets notifications about the following
|
8
9
|
# Guard events: `start`, `stop`, `reload`, `run_all` and `run_on_change`.
|
9
10
|
#
|
10
11
|
class Cucumber < Plugin
|
11
|
-
autoload :Runner, "guard/cucumber/runner"
|
12
|
-
autoload :Inspector, "guard/cucumber/inspector"
|
13
|
-
autoload :Focuser, "guard/cucumber/focuser"
|
14
|
-
|
15
12
|
attr_accessor :last_failed, :failed_path
|
16
13
|
|
17
14
|
# Initialize Guard::Cucumber.
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Guard
|
2
|
-
class Cucumber
|
2
|
+
class Cucumber < Plugin
|
3
3
|
# The inspector verifies of the changed paths are valid
|
4
4
|
# for Guard::Cucumber.
|
5
5
|
#
|
@@ -54,7 +54,7 @@ module Guard
|
|
54
54
|
# @return [Array<String>] the valid files
|
55
55
|
#
|
56
56
|
def cucumber_files(feature_sets)
|
57
|
-
glob = "#{ feature_sets.join(
|
57
|
+
glob = "#{ feature_sets.join(',') }/**/*.feature"
|
58
58
|
@cucumber_files ||= Dir.glob(glob)
|
59
59
|
end
|
60
60
|
|
@@ -1,10 +1,8 @@
|
|
1
|
-
require "guard"
|
2
|
-
require "guard/notifier"
|
3
1
|
require "cucumber/formatter/console"
|
4
2
|
require "cucumber/formatter/io"
|
5
3
|
|
6
4
|
module Guard
|
7
|
-
class Cucumber
|
5
|
+
class Cucumber < Plugin
|
8
6
|
# The notification formatter is a Cucumber formatter that Guard::Cucumber
|
9
7
|
# passes to the Cucumber binary. It writes the `rerun.txt` file with the
|
10
8
|
# failed features
|
@@ -69,13 +67,14 @@ module Guard
|
|
69
67
|
# used
|
70
68
|
#
|
71
69
|
def step_name(_keyword, step_match, status, _src_indent, _bckgnd, _loc)
|
72
|
-
|
73
|
-
@rerun = true
|
74
|
-
step_name = step_match.format_args(lambda { |param| "*#{ param }*" })
|
70
|
+
return unless [:failed, :pending, :undefined].index(status)
|
75
71
|
|
76
|
-
|
77
|
-
|
78
|
-
|
72
|
+
#TODO: "NO COVERATE HERE!!"
|
73
|
+
@rerun = true
|
74
|
+
step_name = step_match.format_args(lambda { |param| "*#{ param }*" })
|
75
|
+
|
76
|
+
options = { title: @feature_name, image: icon_for(status) }
|
77
|
+
Guard::Compat::UI.notify(step_name, options)
|
79
78
|
end
|
80
79
|
|
81
80
|
private
|
@@ -84,20 +83,16 @@ module Guard
|
|
84
83
|
# result of the feature tests.
|
85
84
|
#
|
86
85
|
def notify_summary
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
len = step_mother.steps(status).length
|
95
|
-
messages << dump_count(len, "step", status.to_s)
|
96
|
-
end
|
97
|
-
end
|
86
|
+
statuses = [:failed, :skipped, :undefined, :pending, :passed]
|
87
|
+
statuses = statuses.reverse
|
88
|
+
statuses.select! { |status| step_mother.steps(status).any? }
|
89
|
+
|
90
|
+
messages = statuses.map { |status| status_to_message(status) }
|
91
|
+
|
92
|
+
icon = statuses.reverse.detect { |status| icon_for(status) }
|
98
93
|
|
99
94
|
msg = messages.reverse.join(", ")
|
100
|
-
|
95
|
+
Guard::Compat::UI.notify msg, title: "Cucumber Results", image: icon
|
101
96
|
end
|
102
97
|
|
103
98
|
# Writes the `rerun.txt` file containing all failed features.
|
@@ -121,10 +116,13 @@ module Guard
|
|
121
116
|
:pending
|
122
117
|
when :failed
|
123
118
|
:failed
|
124
|
-
else
|
125
|
-
nil
|
126
119
|
end
|
127
120
|
end
|
121
|
+
|
122
|
+
def status_to_message(status)
|
123
|
+
len = step_mother.steps(status).length
|
124
|
+
dump_count(len, "step", status.to_s)
|
125
|
+
end
|
128
126
|
end
|
129
127
|
end
|
130
128
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Guard
|
2
|
-
class Cucumber
|
2
|
+
class Cucumber < Plugin
|
3
3
|
# The Cucumber runner handles the execution of the cucumber binary.
|
4
4
|
#
|
5
5
|
module Runner
|
@@ -33,7 +33,7 @@ module Guard
|
|
33
33
|
paths = Focuser.focus(paths, options[:focus_on]) if options[:focus_on]
|
34
34
|
cmd = cucumber_command(paths, options)
|
35
35
|
|
36
|
-
UI.info message, reset: true
|
36
|
+
Compat::UI.info message, reset: true
|
37
37
|
|
38
38
|
system(cmd)
|
39
39
|
end
|
@@ -55,18 +55,12 @@ module Guard
|
|
55
55
|
#
|
56
56
|
def cucumber_command(paths, options)
|
57
57
|
cmd = []
|
58
|
-
cmd
|
59
|
-
|
60
|
-
|
61
|
-
end
|
62
|
-
|
63
|
-
cmd << "bundle exec" if bundler? && options[:bundler] != false
|
58
|
+
_add_cmd_prefix(cmd, options[:command_prefix])
|
59
|
+
_add_rvm_options(cmd, options[:rvm])
|
60
|
+
_add_bundler_options(cmd, options[:bundler])
|
64
61
|
cmd << cucumber_exec(options)
|
65
|
-
cmd
|
66
|
-
|
67
|
-
if options[:notification] != false
|
68
|
-
_add_notification(cmd, options)
|
69
|
-
end
|
62
|
+
_add_cli_options(cmd, options[:cli])
|
63
|
+
_add_notification(cmd, options)
|
70
64
|
|
71
65
|
(cmd + paths).join(" ")
|
72
66
|
end
|
@@ -99,6 +93,8 @@ module Guard
|
|
99
93
|
private
|
100
94
|
|
101
95
|
def _add_notification(cmd, options)
|
96
|
+
return unless options[:notification] != false
|
97
|
+
|
102
98
|
this_dir = File.dirname(__FILE__)
|
103
99
|
formatter_path = File.join(this_dir, "notification_formatter.rb")
|
104
100
|
notification_formatter_path = File.expand_path(formatter_path)
|
@@ -110,6 +106,23 @@ module Guard
|
|
110
106
|
"--require #{ path }"
|
111
107
|
end.join(" ")
|
112
108
|
end
|
109
|
+
|
110
|
+
def _add_rvm_options(cmd, rvm_args)
|
111
|
+
return unless rvm_args.is_a?(Array)
|
112
|
+
cmd << "rvm #{ rvm_args.join(',') } exec"
|
113
|
+
end
|
114
|
+
|
115
|
+
def _add_bundler_options(cmd, bundler)
|
116
|
+
cmd << "bundle exec" if bundler? && bundler != false
|
117
|
+
end
|
118
|
+
|
119
|
+
def _add_cli_options(cmd, cli)
|
120
|
+
cmd << cli if cli
|
121
|
+
end
|
122
|
+
|
123
|
+
def _add_cmd_prefix(cmd, prefix)
|
124
|
+
cmd << prefix if prefix
|
125
|
+
end
|
113
126
|
end
|
114
127
|
end
|
115
128
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: guard-cucumber
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Kessler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: guard
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 2.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: guard-compat
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: cucumber
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +66,34 @@ dependencies:
|
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '1.1'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.1'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.1'
|
55
97
|
description: Guard::Cucumber automatically run your features (much like autotest)
|
56
98
|
email:
|
57
99
|
- michi@flinkfinger.com
|
@@ -62,21 +104,15 @@ files:
|
|
62
104
|
- LICENSE
|
63
105
|
- README.md
|
64
106
|
- lib/guard/cucumber.rb
|
65
|
-
- lib/guard/cucumber.rb.orig
|
66
107
|
- lib/guard/cucumber/focuser.rb
|
67
|
-
- lib/guard/cucumber/focuser.rb.orig
|
68
108
|
- lib/guard/cucumber/inspector.rb
|
69
|
-
- lib/guard/cucumber/inspector.rb.orig
|
70
109
|
- lib/guard/cucumber/notification_formatter.rb
|
71
|
-
- lib/guard/cucumber/notification_formatter.rb.orig
|
72
110
|
- lib/guard/cucumber/runner.rb
|
73
|
-
- lib/guard/cucumber/runner.rb.orig
|
74
111
|
- lib/guard/cucumber/templates/Guardfile
|
75
|
-
- lib/guard/cucumber/templates/Guardfile.orig
|
76
112
|
- lib/guard/cucumber/version.rb
|
77
|
-
|
78
|
-
|
79
|
-
|
113
|
+
homepage: http://github.com/guard/guard-cucumber
|
114
|
+
licenses:
|
115
|
+
- MIT
|
80
116
|
metadata: {}
|
81
117
|
post_install_message:
|
82
118
|
rdoc_options: []
|
@@ -93,8 +129,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
129
|
- !ruby/object:Gem::Version
|
94
130
|
version: 1.3.6
|
95
131
|
requirements: []
|
96
|
-
rubyforge_project:
|
97
|
-
rubygems_version: 2.
|
132
|
+
rubyforge_project:
|
133
|
+
rubygems_version: 2.2.2
|
98
134
|
signing_key:
|
99
135
|
specification_version: 4
|
100
136
|
summary: Guard plugin for Cucumber
|
data/lib/guard/cucumber.rb.orig
DELETED
@@ -1,143 +0,0 @@
|
|
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,81 +0,0 @@
|
|
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
|
@@ -1,77 +0,0 @@
|
|
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,124 +0,0 @@
|
|
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,86 +0,0 @@
|
|
1
|
-
module Guard
|
2
|
-
class Cucumber
|
3
|
-
# The Cucumber runner handles the execution of the cucumber binary.
|
4
|
-
#
|
5
|
-
module Runner
|
6
|
-
class << self
|
7
|
-
# Run the supplied features.
|
8
|
-
#
|
9
|
-
# @param [Array<String>] paths the feature files or directories
|
10
|
-
# @param [Hash] options the options for the execution
|
11
|
-
# @option options [Array<String>] :feature_sets a list of non-standard feature directory/ies
|
12
|
-
# @option options [Boolean] :bundler use bundler or not
|
13
|
-
# @option options [Array<String>] :rvm a list of rvm version to use for the test
|
14
|
-
# @option options [Boolean] :notification show notifications
|
15
|
-
# @option options [String] :command_prefix allows adding an additional prefix to the cucumber command. Ideal for running xvfb-run for terminal only cucumber tests.
|
16
|
-
# @return [Boolean] the status of the execution
|
17
|
-
#
|
18
|
-
def run(paths, options = {})
|
19
|
-
return false if paths.empty?
|
20
|
-
|
21
|
-
message = options[:message] || (paths == ["features"] ? "Running all Cucumber features: #{ cucumber_command(paths, options) }" : "Running Cucumber features: #{ cucumber_command(paths, options) }")
|
22
|
-
paths = options[:focus_on] ? Focuser.focus(paths, options[:focus_on]) : paths
|
23
|
-
|
24
|
-
UI.info message, reset: true
|
25
|
-
|
26
|
-
system(cucumber_command(paths, options))
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
# Assembles the Cucumber command from the passed options.
|
32
|
-
#
|
33
|
-
# @param [Array<String>] paths the feature files or directories
|
34
|
-
# @param [Hash] options the options for the execution
|
35
|
-
# @option options [Boolean] :bundler use bundler or not
|
36
|
-
# @option options [Array<String>] :rvm a list of rvm version to use for the test
|
37
|
-
# @option options [Boolean] :notification show notifications
|
38
|
-
# @option options [String] :command_prefix allows adding an additional prefix to the cucumber command. Ideal for running xvfb-run for terminal only cucumber tests.
|
39
|
-
# @return [String] the Cucumber command
|
40
|
-
#
|
41
|
-
def cucumber_command(paths, options)
|
42
|
-
cmd = []
|
43
|
-
cmd << options[:command_prefix] if options[:command_prefix]
|
44
|
-
cmd << "rvm #{ options[:rvm].join(",") } exec" if options[:rvm].is_a?(Array)
|
45
|
-
cmd << "bundle exec" if bundler? && options[:bundler] != false
|
46
|
-
cmd << cucumber_exec(options)
|
47
|
-
cmd << options[:cli] if options[:cli]
|
48
|
-
|
49
|
-
if options[:notification] != false
|
50
|
-
notification_formatter_path = File.expand_path(File.join(File.dirname(__FILE__), "notification_formatter.rb"))
|
51
|
-
cmd << "--require #{ notification_formatter_path }"
|
52
|
-
cmd << "--format Guard::Cucumber::NotificationFormatter"
|
53
|
-
cmd << "--out #{ null_device }"
|
54
|
-
cmd << (options[:feature_sets] || ["features"]).map { |path| "--require #{ path }" }.join(" ")
|
55
|
-
end
|
56
|
-
|
57
|
-
(cmd + paths).join(" ")
|
58
|
-
end
|
59
|
-
|
60
|
-
# Simple test if binstubs prefix should be used.
|
61
|
-
#
|
62
|
-
# @return [String] Cucumber executable
|
63
|
-
#
|
64
|
-
def cucumber_exec(options = {})
|
65
|
-
options[:binstubs] == true ? "bin/cucumber" : "cucumber"
|
66
|
-
end
|
67
|
-
|
68
|
-
# Simple test if bundler should be used. it just checks for the `Gemfile`.
|
69
|
-
#
|
70
|
-
# @return [Boolean] bundler exists
|
71
|
-
#
|
72
|
-
def bundler?
|
73
|
-
@bundler ||= File.exist?("#{ Dir.pwd }/Gemfile")
|
74
|
-
end
|
75
|
-
|
76
|
-
# Returns a null device for all OS.
|
77
|
-
#
|
78
|
-
# @return [String] the name of the null device
|
79
|
-
#
|
80
|
-
def null_device
|
81
|
-
RUBY_PLATFORM.index("mswin") ? "NUL" : "/dev/null"
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|