guard-cucumber 1.5.1 → 1.5.2
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 +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
|