test_launcher 1.5.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +81 -37
- data/lib/test_launcher/cli.rb +1 -3
- data/lib/test_launcher/cli/input_parser.rb +10 -6
- data/lib/test_launcher/frameworks/base.rb +11 -0
- data/lib/test_launcher/frameworks/{elixir.rb → ex_unit.rb} +16 -20
- data/lib/test_launcher/frameworks/minitest.rb +29 -17
- data/lib/test_launcher/frameworks/rspec.rb +14 -7
- data/lib/test_launcher/queries.rb +47 -31
- data/lib/test_launcher/shell/runner.rb +2 -1
- data/lib/test_launcher/version.rb +1 -1
- data/test/test_helpers/integration_helper.rb +6 -13
- data/test/test_helpers/mocks.rb +1 -0
- data/test/test_helpers/mocks/searcher_mock.rb +3 -1
- data/test/test_launcher/ex_unit_integration_test.rb +392 -0
- data/test/test_launcher/fixtures/minitest/test/class_1_test.rb +4 -15
- data/test/test_launcher/fixtures/minitest/test/class_2_test.rb +7 -3
- data/test/test_launcher/frameworks/minitest/runner_test.rb +10 -10
- data/test/test_launcher/frameworks/minitest/searcher_test.rb +11 -10
- data/test/test_launcher/frameworks/rspec/runner_test.rb +5 -5
- data/test/test_launcher/frameworks/rspec/searcher_test.rb +4 -4
- data/test/test_launcher/minitest_integration_test.rb +533 -38
- data/test/test_launcher/queries/example_name_query_test.rb +5 -1
- data/test/test_launcher/queries/line_number_query_test.rb +7 -7
- data/test/test_launcher/queries/multi_term_query_test.rb +0 -12
- data/test/test_launcher/rspec_integration_test.rb +458 -35
- metadata +5 -5
- data/test/test_launcher/queries/specified_name_query_test.rb +0 -112
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ccdfde0aec34dd6c9644f3985b2fec6c8b80d65a
|
4
|
+
data.tar.gz: a580b9f1354854325582f98d02a42626065cca23
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 264cb91173593078f956c8a76e527494cd033a3d647d31d1527528eef1afb84d0273707004c55d0057bfdc7f15411384be3da46af1197d942fb05a8ee55b1be7
|
7
|
+
data.tar.gz: 509301a76e17513abaeb8952230a43844392f09ca0d7ae520b8909faedde428a485bf02c44ba40b17c5a9ee371f0890eae053bfd56ea1996d1fc7984aed02241
|
data/README.md
CHANGED
@@ -1,8 +1,25 @@
|
|
1
|
-
#Test Launcher -->
|
1
|
+
# Test Launcher -->
|
2
2
|
|
3
|
-
Test Launcher takes
|
3
|
+
Test Launcher takes a search query and tries to figure out what test you want to run. It makes running tests on the command line easy! Super bonus!
|
4
4
|
|
5
|
-
|
5
|
+
You might use Test Launcher for two reasons:
|
6
|
+
|
7
|
+
1. You run tests from the command line a lot.
|
8
|
+
2. You work in a ruby app that contains inline gems/engines with their own test suites.
|
9
|
+
|
10
|
+
It was built for Minitest, but it also has basic support for RSpec and ExUnit.
|
11
|
+
|
12
|
+
See the __Usages__ section below for some examples.
|
13
|
+
|
14
|
+
# Installation
|
15
|
+
|
16
|
+
To install:
|
17
|
+
|
18
|
+
```
|
19
|
+
gem install test_launcher
|
20
|
+
```
|
21
|
+
|
22
|
+
Under the hood, it uses git to determine your project root. If you're on an app that's not using git, let me know and I can remove that dependency.
|
6
23
|
|
7
24
|
### Usage
|
8
25
|
|
@@ -19,6 +36,7 @@ But with Test Launcher, you can just type this:
|
|
19
36
|
```
|
20
37
|
test_launcher test_blog_name_thing
|
21
38
|
|
39
|
+
#=> Found 1 example in 1 file
|
22
40
|
#=> ruby -I test test/models/blog_post_test.rb --name=test_blog_name_thing
|
23
41
|
```
|
24
42
|
|
@@ -30,6 +48,22 @@ test_launcher blog_post_test
|
|
30
48
|
#=> ruby -I test test/models/blog_post_test.rb
|
31
49
|
```
|
32
50
|
|
51
|
+
Maybe you'd like to run a whole folder?
|
52
|
+
|
53
|
+
```
|
54
|
+
test_launcher test/models --all
|
55
|
+
|
56
|
+
#=> ruby -I test -e 'ARGV.each {|f| require(f)}' test/models/blog_post_test.rb test/models/comment_test.rb
|
57
|
+
```
|
58
|
+
|
59
|
+
You can run specific test methods by line:
|
60
|
+
```
|
61
|
+
test_launcher blog_post_test.rb:13
|
62
|
+
|
63
|
+
#=> Found 1 example in 1 file
|
64
|
+
#=> ruby -I test test/models/blog_post_test.rb --name=test_blog_name_thing
|
65
|
+
```
|
66
|
+
|
33
67
|
What if you just have the class name for the test?
|
34
68
|
|
35
69
|
```
|
@@ -55,16 +89,27 @@ test_launcher /Users/username/code/my_repo/test/models/blog_post_test.rb
|
|
55
89
|
#=> ruby -I test test/models/blog_post_test.rb
|
56
90
|
```
|
57
91
|
|
58
|
-
|
92
|
+
Suppose you have multiple files you'd like to run:
|
59
93
|
```
|
60
94
|
test_launcher blog_post_test.rb comment_test.rb
|
61
95
|
|
62
96
|
#=> ruby -I test -e 'ARGV.each {|f| require(f)}' test/models/blog_post_test.rb test/models/comment_test.rb
|
63
97
|
```
|
64
98
|
|
99
|
+
Or maybe you'd like to run all test methods that match a regular expression:
|
100
|
+
|
101
|
+
```
|
102
|
+
test_launcher 'hello_\w*|goodbye_\w+'
|
103
|
+
|
104
|
+
#=> Found 2 methods in 2 files.
|
105
|
+
#=> bundle exec ruby -I test -e "ARGV.push('--name=/hello_\w*|goodbye_\w+/')" -r /src/test/file_1_test.rb -r /src/test/file_2_test.rb
|
106
|
+
```
|
107
|
+
|
65
108
|
### Inline Gems
|
66
109
|
|
67
|
-
|
110
|
+
If you work in an application that has inlined gems/engines, you've probably already experienced pain around running tests. IDEs and editor plugins have a hard time understanding how to run tests for inlined gems when you have opened the project from a parent folder. By looking for Gemfiles and gemspecs, Test Launcher can run your tests in the correct context. If you are using RubyMine in a project with inline gems, see the __RubyMine__ section below.
|
111
|
+
|
112
|
+
For example, if `thing_test.rb` is within your inline_gem, you can run:
|
68
113
|
|
69
114
|
```
|
70
115
|
test_launcher thing_test
|
@@ -72,7 +117,7 @@ test_launcher thing_test
|
|
72
117
|
#=> cd /path/to/inline_gem && ruby -I test test/thing_test.rb
|
73
118
|
```
|
74
119
|
|
75
|
-
You don't have to run Test Launcher from the root of your project either. It will figure things out
|
120
|
+
You don't have to run Test Launcher from the root of your project either. It will figure things out, even when using the `--all` flag!
|
76
121
|
|
77
122
|
### Spring preloader
|
78
123
|
|
@@ -86,6 +131,29 @@ test_launcher springified_test
|
|
86
131
|
|
87
132
|
Test Launcher will not use spring if the `DISABLE_SPRING=1` environment variable is set.
|
88
133
|
|
134
|
+
### Priorities
|
135
|
+
|
136
|
+
Test Launcher searches for tests based on your input.
|
137
|
+
|
138
|
+
Suppose you type `test_launcher thing`. It will run tests using this priority preference:
|
139
|
+
|
140
|
+
1. A single test file
|
141
|
+
- matches on `thing_test.rb`
|
142
|
+
|
143
|
+
1. A single, specific test method name or partial name
|
144
|
+
- `def test_the_thing`
|
145
|
+
|
146
|
+
1. Multiple test method names in the same file
|
147
|
+
- `def test_the_thing` and `def test_the_other_thing`
|
148
|
+
|
149
|
+
1. Any test file based on a generic search
|
150
|
+
- runs `stuff_test.rb` because it found the word `thing` inside of it
|
151
|
+
|
152
|
+
If your looks like it's specifying a line number (e.g. `file_test.rb:17`), that search will be preferred.
|
153
|
+
|
154
|
+
Any time it matches multiple files, it will default to running the most recently edited file. You can append `--all` if you want to run all matching tests, even if they are in different engines/gems!
|
155
|
+
|
156
|
+
|
89
157
|
### Running all tests you've changed:
|
90
158
|
|
91
159
|
This will find all uncommitted `*_test.rb` files and pass them to test_launcher to be run. Use this before you commit so you don't accidentally commit a test you've broken.
|
@@ -119,18 +187,7 @@ tdiff origin/master
|
|
119
187
|
|
120
188
|
Super fun!
|
121
189
|
|
122
|
-
|
123
|
-
|
124
|
-
To install:
|
125
|
-
|
126
|
-
```
|
127
|
-
gem install test_launcher
|
128
|
-
```
|
129
|
-
|
130
|
-
Under the hood it uses git to search for files and to grep, so it will only work in git repositories.
|
131
|
-
|
132
|
-
|
133
|
-
#Setup
|
190
|
+
### Setup
|
134
191
|
|
135
192
|
This gem installs one executable called `test_launcher`.
|
136
193
|
|
@@ -149,25 +206,6 @@ alias t='NOEXEC_DISABLE=1 test_launcher'
|
|
149
206
|
|
150
207
|
Now you can just type `t` instead of `test_launcher`. Much nicer!
|
151
208
|
|
152
|
-
#Usage
|
153
|
-
|
154
|
-
Test Launcher searches for tests based on your input.
|
155
|
-
|
156
|
-
Suppose you type `test_launcher thing`. It will run tests using this priority preference:
|
157
|
-
|
158
|
-
1. A single, specific test method name or partial name
|
159
|
-
- `def test_the_thing`
|
160
|
-
|
161
|
-
1. Multiple test method names in the same file
|
162
|
-
- `def test_the_thing` and `def test_the_other_thing`
|
163
|
-
|
164
|
-
1. A single test file
|
165
|
-
- matches on `thing_test.rb`
|
166
|
-
|
167
|
-
1. Any test file based on a generic search
|
168
|
-
- runs `stuff_test.rb` because it found the word `thing` inside of it
|
169
|
-
|
170
|
-
Any time it matches multiple files, it will default to running the most recently edited file. You can append `--all` if you want to run all matching tests, even if they are in different engines/gems!
|
171
209
|
|
172
210
|
# RubyMine Support
|
173
211
|
|
@@ -230,3 +268,9 @@ I suggest that if you are using RVM, you may as well make this your alias:
|
|
230
268
|
```
|
231
269
|
alias t='NOEXEC_DISABLE=1 test_launcher'
|
232
270
|
```
|
271
|
+
|
272
|
+
# What's going on in there?
|
273
|
+
|
274
|
+
Test Launcher began life as a bash script patching together `ag`, `awk`, `grep`, and all sorts of insanity. After looking up how to do an if/else in bash for the millionth time, I decided to rewrite it in Ruby.
|
275
|
+
|
276
|
+
Test Launcher was developed using "BDD" (Bug Driven Development). Because I use it so heavily, I'd pop over and hack something precisely at the moment I needed it (often breaking all sorts of other things). I've since added some tests, but I reserve the right to break anything at anytime if only for old times' sake.
|
data/lib/test_launcher/cli.rb
CHANGED
@@ -22,9 +22,7 @@ module TestLauncher
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
def self.launch(argv, env, shell: Shell::Runner.new(log_path: "/tmp/test_launcher.log"))
|
26
|
-
searcher = Search.searcher(shell)
|
27
|
-
|
25
|
+
def self.launch(argv, env, shell: Shell::Runner.new(log_path: "/tmp/test_launcher.log"), searcher: Search.searcher(shell))
|
28
26
|
requests = CLI::InputParser.new(
|
29
27
|
argv,
|
30
28
|
env
|
@@ -4,7 +4,7 @@ require "test_launcher/version"
|
|
4
4
|
|
5
5
|
require "test_launcher/frameworks/rspec"
|
6
6
|
require "test_launcher/frameworks/minitest"
|
7
|
-
require "test_launcher/frameworks/
|
7
|
+
require "test_launcher/frameworks/ex_unit"
|
8
8
|
require "test_launcher/cli/request"
|
9
9
|
|
10
10
|
module TestLauncher
|
@@ -46,10 +46,10 @@ VERSION: #{TestLauncher::VERSION}
|
|
46
46
|
[Frameworks::RSpec]
|
47
47
|
elsif @options[:framework] == "minitest"
|
48
48
|
[Frameworks::Minitest]
|
49
|
-
elsif @options[:framework] == "
|
50
|
-
[Frameworks::
|
49
|
+
elsif @options[:framework] == "ex_unit"
|
50
|
+
[Frameworks::ExUnit]
|
51
51
|
else
|
52
|
-
[Frameworks::Minitest, Frameworks::RSpec, Frameworks::
|
52
|
+
[Frameworks::Minitest, Frameworks::RSpec, Frameworks::ExUnit]
|
53
53
|
end
|
54
54
|
|
55
55
|
frameworks.map {|framework|
|
@@ -89,13 +89,17 @@ VERSION: #{TestLauncher::VERSION}
|
|
89
89
|
exit
|
90
90
|
end
|
91
91
|
|
92
|
-
opts.on("-f", "--framework framework", "The testing framework being used. Valid options: ['minitest', 'rspec', '
|
92
|
+
opts.on("-f", "--framework framework", "The testing framework being used. Valid options: ['minitest', 'rspec', 'ex_unit', 'guess']. Defaults to 'guess'") do |framework|
|
93
93
|
options[:framework] = framework
|
94
94
|
end
|
95
95
|
|
96
|
-
opts.on("-n", "--name name", "
|
96
|
+
opts.on("-n", "--name name", "Name of testcase/example to run. This will pass through to the selected framework without verifying that the example actually exists. This option really only exists to work with tooling that will automatically run your tests. You shouldn't have much need for this.") do |name|
|
97
97
|
options[:name] = name
|
98
98
|
end
|
99
|
+
|
100
|
+
opts.on("--example example", "alias of name") do |example|
|
101
|
+
options[:name] = example
|
102
|
+
end
|
99
103
|
end
|
100
104
|
end
|
101
105
|
end
|
@@ -38,6 +38,10 @@ module TestLauncher
|
|
38
38
|
end
|
39
39
|
|
40
40
|
class Runner
|
41
|
+
def by_line_number(test_case)
|
42
|
+
raise NotImplementedError
|
43
|
+
end
|
44
|
+
|
41
45
|
def single_example(test_case)
|
42
46
|
raise NotImplementedError
|
43
47
|
end
|
@@ -54,6 +58,13 @@ module TestLauncher
|
|
54
58
|
one_or_more_files([test_case])
|
55
59
|
end
|
56
60
|
|
61
|
+
def multiple_examples(collection)
|
62
|
+
collection
|
63
|
+
.group_by(&:app_root)
|
64
|
+
.map { |_root, test_cases| multiple_examples_same_root(test_cases) }
|
65
|
+
.join("; cd -;\n\n")
|
66
|
+
end
|
67
|
+
|
57
68
|
def multiple_files(collection)
|
58
69
|
collection
|
59
70
|
.group_by(&:app_root)
|
@@ -3,7 +3,7 @@ require "test_launcher/base_error"
|
|
3
3
|
|
4
4
|
module TestLauncher
|
5
5
|
module Frameworks
|
6
|
-
module
|
6
|
+
module ExUnit
|
7
7
|
def self.active?
|
8
8
|
# Do not do this outside of the shell.
|
9
9
|
! Dir.glob("**/test/**/*.exs").empty?
|
@@ -25,13 +25,11 @@ module TestLauncher
|
|
25
25
|
MultipleByLineMatches = Class.new(BaseError)
|
26
26
|
|
27
27
|
def by_line(file_pattern, line_number)
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
file: files.first,
|
34
|
-
line_number: line_number
|
28
|
+
test_files(file_pattern).map {|file|
|
29
|
+
{
|
30
|
+
file: file,
|
31
|
+
line_number: line_number
|
32
|
+
}
|
35
33
|
}
|
36
34
|
end
|
37
35
|
|
@@ -48,25 +46,23 @@ module TestLauncher
|
|
48
46
|
def example_name_regex(query="")
|
49
47
|
"^\s*test\s+\".*#{query}.*\"\s+do"
|
50
48
|
end
|
51
|
-
|
52
|
-
def multiple_files_error
|
53
|
-
MultipleByLineMatches.new(<<-MSG)
|
54
|
-
It looks like you are running a line number in a test file.
|
55
|
-
|
56
|
-
Multiple files have been found that match your query.
|
57
|
-
|
58
|
-
This case is not supported.
|
59
|
-
MSG
|
60
|
-
end
|
61
49
|
end
|
62
50
|
|
63
51
|
class Runner < Base::Runner
|
64
|
-
def
|
52
|
+
def by_line_number(test_case)
|
65
53
|
%{cd #{test_case.app_root} && mix test #{test_case.file}:#{test_case.line_number}}
|
66
54
|
end
|
67
55
|
|
56
|
+
def single_example(test_case)
|
57
|
+
by_line_number(test_case)
|
58
|
+
end
|
59
|
+
|
68
60
|
def multiple_examples_same_file(test_cases)
|
69
|
-
one_or_more_files(test_cases.
|
61
|
+
one_or_more_files(test_cases.uniq {|tc| tc.file})
|
62
|
+
end
|
63
|
+
|
64
|
+
def multiple_examples_same_root(test_cases)
|
65
|
+
one_or_more_files(test_cases.uniq {|tc| tc.file})
|
70
66
|
end
|
71
67
|
|
72
68
|
def one_or_more_files(test_cases)
|
@@ -27,7 +27,7 @@ module TestLauncher
|
|
27
27
|
|
28
28
|
def by_line(file_pattern, line_number)
|
29
29
|
files = test_files(file_pattern)
|
30
|
-
return unless files.any?
|
30
|
+
return [] unless files.any?
|
31
31
|
raise multiple_files_error if files.size > 1
|
32
32
|
#
|
33
33
|
file = files.first
|
@@ -39,16 +39,16 @@ module TestLauncher
|
|
39
39
|
.min_by {|r| line_number - r[:line_number]}
|
40
40
|
|
41
41
|
if best_result
|
42
|
-
{
|
42
|
+
[{
|
43
43
|
file: best_result[:file],
|
44
44
|
example_name: best_result[:line].match(/(test_\w+)/)[1],
|
45
45
|
line_number: best_result[:line_number]
|
46
|
-
}
|
46
|
+
}]
|
47
47
|
else
|
48
48
|
# line number outside of example. Run whole file
|
49
|
-
{
|
49
|
+
[{
|
50
50
|
file: grep_results.first[:file]
|
51
|
-
}
|
51
|
+
}]
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -72,26 +72,36 @@ module TestLauncher
|
|
72
72
|
|
73
73
|
def multiple_files_error
|
74
74
|
MultipleByLineMatches.new(<<-MSG)
|
75
|
-
|
75
|
+
It looks like you are running a line number in a test file.
|
76
76
|
|
77
|
-
|
77
|
+
Multiple files have been found that match your query.
|
78
78
|
|
79
|
-
|
79
|
+
This case is not supported for Minitest.
|
80
|
+
|
81
|
+
Open an issue on https://github.com/petekinnecom/test_launcher if this is something you have run into at least 3 times. :)
|
80
82
|
MSG
|
81
83
|
end
|
82
84
|
|
83
85
|
end
|
84
86
|
|
85
87
|
class Runner < Base::Runner
|
88
|
+
def by_line_number(test_case)
|
89
|
+
if test_case.example
|
90
|
+
single_example(test_case)
|
91
|
+
else
|
92
|
+
single_file(test_case)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
86
96
|
def single_example(test_case, name: test_case.example, exact_match: false)
|
87
|
-
|
97
|
+
name_arg =
|
88
98
|
if exact_match
|
89
|
-
name
|
99
|
+
Shellwords.escape(name)
|
90
100
|
else
|
91
101
|
"/#{Shellwords.escape(name)}/"
|
92
102
|
end
|
93
103
|
|
94
|
-
%{cd #{test_case.app_root} && #{test_case.
|
104
|
+
%{cd #{test_case.app_root} && #{test_case.example_runner} #{test_case.file} --name=#{name_arg}}
|
95
105
|
end
|
96
106
|
|
97
107
|
def multiple_examples_same_file(test_cases)
|
@@ -99,23 +109,25 @@ module TestLauncher
|
|
99
109
|
single_example(test_cases.first)
|
100
110
|
end
|
101
111
|
|
112
|
+
def multiple_examples_same_root(test_cases)
|
113
|
+
%{cd #{test_cases.first.app_root} && bundle exec ruby -I test -e "ARGV.push('--name=/#{test_cases.first.example}/')" #{test_cases.map {|tc| "-r #{tc.file}"}.uniq.join(" ")}}
|
114
|
+
end
|
115
|
+
|
102
116
|
def one_or_more_files(test_cases)
|
103
|
-
%{cd #{test_cases.first.app_root} && #{test_cases.first.
|
117
|
+
%{cd #{test_cases.first.app_root} && #{test_cases.first.file_runner} #{test_cases.map(&:file).uniq.join(" ")}}
|
104
118
|
end
|
105
119
|
end
|
106
120
|
|
107
121
|
class TestCase < Base::TestCase
|
108
|
-
def
|
122
|
+
def example_runner
|
109
123
|
if spring_enabled?
|
110
124
|
"bundle exec spring testunit"
|
111
|
-
elsif is_example?
|
112
|
-
"bundle exec ruby -I test"
|
113
125
|
else
|
114
|
-
"bundle exec ruby -I test
|
126
|
+
"bundle exec ruby -I test"
|
115
127
|
end
|
116
128
|
end
|
117
129
|
|
118
|
-
def
|
130
|
+
def file_runner
|
119
131
|
if spring_enabled?
|
120
132
|
"bundle exec spring testunit"
|
121
133
|
else
|
@@ -25,12 +25,12 @@ module TestLauncher
|
|
25
25
|
|
26
26
|
def by_line(file_pattern, line_number)
|
27
27
|
files = test_files(file_pattern)
|
28
|
-
return unless files.any?
|
29
|
-
raise multiple_files_error if files.size > 1
|
30
28
|
|
31
|
-
{
|
32
|
-
|
33
|
-
|
29
|
+
files.map {|file|
|
30
|
+
{
|
31
|
+
file: file,
|
32
|
+
line_number: line_number
|
33
|
+
}
|
34
34
|
}
|
35
35
|
end
|
36
36
|
|
@@ -50,8 +50,12 @@ module TestLauncher
|
|
50
50
|
end
|
51
51
|
|
52
52
|
class Runner < Base::Runner
|
53
|
+
def by_line_number(test_case)
|
54
|
+
%{cd #{test_case.app_root} && bundle exec rspec #{test_case.file}:#{test_case.line_number}}
|
55
|
+
end
|
56
|
+
|
53
57
|
def single_example(test_case, **_)
|
54
|
-
%{cd #{test_case.app_root} && rspec #{test_case.file} --example #{Shellwords.escape(test_case.example)}}
|
58
|
+
%{cd #{test_case.app_root} && bundle exec rspec #{test_case.file} --example #{Shellwords.escape(test_case.example)}}
|
55
59
|
end
|
56
60
|
|
57
61
|
def multiple_examples_same_file(test_cases)
|
@@ -59,9 +63,12 @@ module TestLauncher
|
|
59
63
|
single_example(test_case)
|
60
64
|
end
|
61
65
|
|
66
|
+
def multiple_examples_same_root(test_cases)
|
67
|
+
one_or_more_files(test_cases.uniq {|tc| tc.file})
|
68
|
+
end
|
62
69
|
|
63
70
|
def one_or_more_files(test_cases)
|
64
|
-
%{cd #{test_cases.first.app_root} && rspec #{test_cases.map(&:file).join(" ")}}
|
71
|
+
%{cd #{test_cases.first.app_root} && bundle exec rspec #{test_cases.map(&:file).join(" ")}}
|
65
72
|
end
|
66
73
|
end
|
67
74
|
|