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.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +81 -37
  3. data/lib/test_launcher/cli.rb +1 -3
  4. data/lib/test_launcher/cli/input_parser.rb +10 -6
  5. data/lib/test_launcher/frameworks/base.rb +11 -0
  6. data/lib/test_launcher/frameworks/{elixir.rb → ex_unit.rb} +16 -20
  7. data/lib/test_launcher/frameworks/minitest.rb +29 -17
  8. data/lib/test_launcher/frameworks/rspec.rb +14 -7
  9. data/lib/test_launcher/queries.rb +47 -31
  10. data/lib/test_launcher/shell/runner.rb +2 -1
  11. data/lib/test_launcher/version.rb +1 -1
  12. data/test/test_helpers/integration_helper.rb +6 -13
  13. data/test/test_helpers/mocks.rb +1 -0
  14. data/test/test_helpers/mocks/searcher_mock.rb +3 -1
  15. data/test/test_launcher/ex_unit_integration_test.rb +392 -0
  16. data/test/test_launcher/fixtures/minitest/test/class_1_test.rb +4 -15
  17. data/test/test_launcher/fixtures/minitest/test/class_2_test.rb +7 -3
  18. data/test/test_launcher/frameworks/minitest/runner_test.rb +10 -10
  19. data/test/test_launcher/frameworks/minitest/searcher_test.rb +11 -10
  20. data/test/test_launcher/frameworks/rspec/runner_test.rb +5 -5
  21. data/test/test_launcher/frameworks/rspec/searcher_test.rb +4 -4
  22. data/test/test_launcher/minitest_integration_test.rb +533 -38
  23. data/test/test_launcher/queries/example_name_query_test.rb +5 -1
  24. data/test/test_launcher/queries/line_number_query_test.rb +7 -7
  25. data/test/test_launcher/queries/multi_term_query_test.rb +0 -12
  26. data/test/test_launcher/rspec_integration_test.rb +458 -35
  27. metadata +5 -5
  28. data/test/test_launcher/queries/specified_name_query_test.rb +0 -112
@@ -110,30 +110,28 @@ module TestLauncher
110
110
 
111
111
  class SpecifiedNameQuery < BaseQuery
112
112
  def command
113
- return unless file
114
-
115
- shell.notify("Found matching test.")
116
- runner.single_example(test_case)
117
- end
118
-
119
- def test_case
120
- request.test_case(
121
- file: file,
122
- example: request.example_name,
123
- request: request,
124
- )
125
- end
126
-
127
- def file
128
- if potential_files.size == 0
129
- shell.warn("Could not locate file: #{request.search_string}")
130
- elsif potential_files.size > 1
131
- shell.warn("Too many files matched: #{request.search_string}")
113
+ if test_cases.empty?
114
+ shell.warn("Could not identify file: #{request.search_string}")
115
+ elsif test_cases.size == 1
116
+ shell.notify("Found 1 example in 1 file.")
117
+ runner.single_example(test_cases.first)
132
118
  else
133
- potential_files.first
119
+ shell.notify "Found #{pluralize(test_cases.size, "example")} in #{pluralize(file_count, "file")}."
120
+ shell.notify "Running most recently edited. Run with '--all' to run all the tests."
121
+ runner.single_example(most_recently_edited_test_case)
134
122
  end
135
123
  end
136
124
 
125
+ def test_cases
126
+ @test_cases ||= potential_files.map {|file|
127
+ request.test_case(
128
+ file: file,
129
+ example: request.example_name,
130
+ request: request,
131
+ )
132
+ }
133
+ end
134
+
137
135
  def potential_files
138
136
  @potential_files ||= searcher.test_files(request.search_string)
139
137
  end
@@ -218,7 +216,7 @@ module TestLauncher
218
216
  runner.multiple_examples_same_file(test_cases) # it will regex with the query
219
217
  elsif request.run_all?
220
218
  shell.notify "Found #{pluralize(test_cases.size, "example")} in #{pluralize(file_count, "file")}."
221
- runner.multiple_files(test_cases)
219
+ runner.multiple_examples(test_cases)
222
220
  else
223
221
  shell.notify "Found #{pluralize(test_cases.size, "example")} in #{pluralize(file_count, "file")}."
224
222
  shell.notify "Running most recently edited. Run with '--all' to run all the tests."
@@ -285,20 +283,38 @@ module TestLauncher
285
283
  LINE_SPLIT_REGEX = /\A(?<file>.*):(?<line_number>\d+)\Z/
286
284
 
287
285
  def command
288
- match = request.search_string.match(LINE_SPLIT_REGEX)
289
- return unless match
286
+ return unless search_results.any?
290
287
 
291
- search_result = searcher.by_line(match[:file], match[:line_number].to_i)
292
- return unless search_result
293
-
294
- if search_result[:line_number]
295
- shell.notify("Found 1 example on line #{search_result[:line_number]}.")
296
- runner.single_example(request.test_case(file: search_result[:file], line_number: search_result[:line_number], example: search_result[:example_name], request: request))
288
+ if one_file?
289
+ shell.notify "Found #{pluralize(file_count, "file")}."
290
+ runner.by_line_number(test_cases.first)
297
291
  else
298
- shell.notify("Found file, but line is not inside an example.")
299
- runner.single_file(request.test_case(file: search_result[:file], request: request))
292
+ shell.notify "Found #{pluralize(file_count, "file")}."
293
+ shell.notify "Cannot run all tests with --all because test frameworks don't accept multiple file/lines combos."
294
+ runner.by_line_number(most_recently_edited_test_case)
300
295
  end
296
+ end
301
297
 
298
+ def test_cases
299
+ @test_cases ||= search_results.map {|sr|
300
+ request.test_case(
301
+ file: sr[:file],
302
+ line_number: sr[:line_number],
303
+ example: sr[:example_name],
304
+ request: request
305
+ )
306
+ }
307
+ end
308
+
309
+ def search_results
310
+ @search_results ||= begin
311
+ match = request.search_string.match(LINE_SPLIT_REGEX)
312
+ if match
313
+ searcher.by_line(match[:file], match[:line_number].to_i)
314
+ else
315
+ []
316
+ end
317
+ end
302
318
  end
303
319
  end
304
320
 
@@ -1,5 +1,6 @@
1
1
  require "test_launcher/shell/color"
2
2
  require "bundler"
3
+ require "shellwords"
3
4
 
4
5
  module TestLauncher
5
6
  module Shell
@@ -52,7 +53,7 @@ module TestLauncher
52
53
  private
53
54
 
54
55
  def log(msg)
55
- %x{echo "#{msg}" >> #{log_path}}
56
+ %x{echo #{Shellwords.escape(msg)} >> #{log_path}}
56
57
  end
57
58
 
58
59
  def shell_out(command)
@@ -1,3 +1,3 @@
1
1
  module TestLauncher
2
- VERSION = "1.5.2"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -8,30 +8,23 @@ module TestLauncher
8
8
  module IntegrationHelper
9
9
  include DefaultMocks
10
10
 
11
- class IntegrationShell < Shell::Runner
11
+ class IntegrationShell < MockShell
12
12
  def exec(string)
13
- raise "Cannot exec twice!" if defined?(@exec)
13
+ raise "Cannot exec twice!" if @exec
14
14
  @exec = string
15
15
  end
16
16
 
17
17
  def recall_exec
18
18
  @exec
19
19
  end
20
+
21
+ def reset
22
+ @exec = nil
23
+ end
20
24
  end
21
25
 
22
26
  private
23
27
 
24
- def system_path(relative_dir)
25
- File.join(Dir.pwd, relative_dir)
26
- end
27
-
28
- def launch(search_string, run_all: false, framework:, name: nil)
29
- argv = [search_string, "--framework", framework]
30
- argv << "--all" if run_all
31
- argv.concat(["--name", name]) if name
32
- env = {}
33
- CLI.launch(argv, env, shell: shell_mock)
34
- end
35
28
 
36
29
  def shell_mock
37
30
  @shell_mock ||= IntegrationShell.new
@@ -40,6 +40,7 @@ module TestLauncher
40
40
  impl(:single_file) { "single_file_return" }
41
41
  impl(:multiple_files) { "multiple_files_return" }
42
42
  impl(:single_example) { "single_example_return" }
43
+ impl(:by_line_number) { "by_line_number_return" }
43
44
  end
44
45
 
45
46
  require "test_launcher/frameworks/base"
@@ -17,7 +17,7 @@ module TestLauncher
17
17
  end
18
18
 
19
19
  def to_file_mock
20
- FileMock.new(@path, @lines, @time)
20
+ FileMock.new(@path, @lines, @mtime)
21
21
  end
22
22
  end
23
23
 
@@ -27,6 +27,8 @@ module TestLauncher
27
27
  @path = path
28
28
  @lines = lines
29
29
  File.stubs(:mtime).with(path).returns(mtime)
30
+ File.stubs(:exist?).returns(false)
31
+ File.stubs(:exist?).with(path).returns(true)
30
32
  end
31
33
 
32
34
  def grep(regex)
@@ -0,0 +1,392 @@
1
+ require "test_helper"
2
+ require "test_helpers/integration_helper"
3
+
4
+ module TestLauncher
5
+ class ExUnitIntegrationTest < TestCase
6
+ include IntegrationHelper
7
+
8
+ def launch(query, env: {}, searcher:)
9
+ query += " --framework ex_unit "
10
+ shell_mock.reset
11
+ CLI.launch(query.split(" "), env, shell: shell_mock, searcher: searcher)
12
+ end
13
+
14
+ def test__by_example__single_method
15
+ searcher = MemorySearcher.new do |searcher|
16
+ searcher.mock_file do |f|
17
+ f.path "/src/test/file_1_test.exs"
18
+ f.contents <<-RB
19
+ defmodule MyApp.File1Test do
20
+ test "test_name" do
21
+ end
22
+ end
23
+ RB
24
+ end
25
+ end
26
+
27
+ launch("test_name", searcher: searcher)
28
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs:2", shell_mock.recall_exec
29
+
30
+ launch("n", searcher: searcher)
31
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs:2", shell_mock.recall_exec
32
+ end
33
+
34
+ def test__by_example__multiple_methods__same_file
35
+ searcher = MemorySearcher.new do |searcher|
36
+ searcher.mock_file do |f|
37
+ f.path "/src/test/file_1_test.exs"
38
+ f.contents <<-RB
39
+ defmodule File1Test do
40
+ test "test_name_1" do
41
+ end
42
+
43
+ test "test_name_2" do
44
+ end
45
+ end
46
+ RB
47
+ end
48
+ end
49
+
50
+ launch("name_", searcher: searcher)
51
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs", shell_mock.recall_exec
52
+ end
53
+
54
+ def test__by_example__multiple_methods__different_files
55
+ searcher = MemorySearcher.new do |searcher|
56
+ searcher.mock_file do |f|
57
+ f.path "/src/test/file_1_test.exs"
58
+ f.mtime Time.new(2014, 01, 01, 00, 00, 00)
59
+ f.contents <<-RB
60
+ test "test_name_1" do
61
+ test "test_name_2" do
62
+ RB
63
+ end
64
+
65
+ searcher.mock_file do |f|
66
+ f.path "/src/test/file_2_test.exs"
67
+ f.mtime Time.new(2015, 01, 01, 00, 00, 00)
68
+ f.contents <<-RB
69
+ test "test_name_1" do
70
+ test "test_name_2" do
71
+ RB
72
+ end
73
+
74
+ searcher.mock_file do |f|
75
+ f.path "/src/test/file_3_test.exs"
76
+ f.mtime Time.new(2013, 01, 01, 00, 00, 00)
77
+ f.contents <<-RB
78
+ test "test_name_2" do
79
+ RB
80
+ end
81
+ end
82
+
83
+ launch("name_1", searcher: searcher)
84
+ assert_equal "cd /src && mix test /src/test/file_2_test.exs:1", shell_mock.recall_exec
85
+
86
+ launch("name_2", searcher: searcher)
87
+ assert_equal "cd /src && mix test /src/test/file_2_test.exs:2", shell_mock.recall_exec
88
+
89
+ launch("name_1 --all", searcher: searcher)
90
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs /src/test/file_2_test.exs", shell_mock.recall_exec
91
+
92
+ launch("name_2 --all", searcher: searcher)
93
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs /src/test/file_2_test.exs /src/test/file_3_test.exs", shell_mock.recall_exec
94
+ end
95
+
96
+ def test__by_filename
97
+ searcher = MemorySearcher.new do |searcher|
98
+ searcher.mock_file do |f|
99
+ f.path "/src/test/file_1_test.exs"
100
+ f.contents ""
101
+ end
102
+ end
103
+
104
+ launch("file_1", searcher: searcher)
105
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs", shell_mock.recall_exec
106
+
107
+ launch("file_1_test.exs", searcher: searcher)
108
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs", shell_mock.recall_exec
109
+
110
+ launch("/file_1", searcher: searcher)
111
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs", shell_mock.recall_exec
112
+
113
+ launch(".exs", searcher: searcher)
114
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs", shell_mock.recall_exec
115
+
116
+ launch("/src/test/file_1", searcher: searcher)
117
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs", shell_mock.recall_exec
118
+
119
+ launch("src/test/file_1", searcher: searcher)
120
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs", shell_mock.recall_exec
121
+
122
+ launch("st/file_1", searcher: searcher)
123
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs", shell_mock.recall_exec
124
+ end
125
+
126
+ def test__by_filename__multiple_files_found
127
+ searcher = MemorySearcher.new do |searcher|
128
+ searcher.mock_file do |f|
129
+ f.path "/src/test/file_1_test.exs"
130
+ f.mtime Time.new(2013, 01, 01, 00, 00, 00)
131
+ end
132
+
133
+ searcher.mock_file do |f|
134
+ f.path "/src/test/file_2_test.exs"
135
+ f.mtime Time.new(2015, 01, 01, 00, 00, 00)
136
+ end
137
+
138
+ searcher.mock_file do |f|
139
+ f.path "/src/test/file_3_test.exs"
140
+ f.mtime Time.new(2014, 01, 01, 00, 00, 00)
141
+ end
142
+
143
+ searcher.mock_file do |f|
144
+ f.path "/src/test/other_test.exs"
145
+ end
146
+ end
147
+
148
+ launch("file_1", searcher: searcher)
149
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs", shell_mock.recall_exec
150
+
151
+ launch("file", searcher: searcher)
152
+ assert_equal "cd /src && mix test /src/test/file_2_test.exs", shell_mock.recall_exec
153
+
154
+ launch("file --all", searcher: searcher)
155
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs /src/test/file_2_test.exs /src/test/file_3_test.exs", shell_mock.recall_exec
156
+ end
157
+
158
+ def test__by_filename__preferred_over_regex_and_test_name_matches
159
+ searcher = MemorySearcher.new do |searcher|
160
+ searcher.mock_file do |f|
161
+ f.path "/src/test/file_1_test.exs"
162
+ f.contents <<-RB
163
+ test "test_name" do
164
+ RB
165
+ end
166
+
167
+ searcher.mock_file do |f|
168
+ f.path "/src/test/name_test.exs"
169
+ end
170
+
171
+ searcher.mock_file do |f|
172
+ f.path "/src/test/other_test.exs"
173
+ f.contents <<-RB
174
+ regex will match name_test
175
+ RB
176
+ end
177
+ end
178
+
179
+ launch("name_test", searcher: searcher)
180
+ assert_equal "cd /src && mix test /src/test/name_test.exs", shell_mock.recall_exec
181
+ end
182
+
183
+ def test__by_multiple_filenames__multiple_files_found
184
+ searcher = MemorySearcher.new do |searcher|
185
+ searcher.mock_file do |f|
186
+ f.path "/src/test/file_1_test.exs"
187
+ f.mtime Time.new(2013, 01, 01, 00, 00, 00)
188
+ f.contents ""
189
+ end
190
+
191
+ searcher.mock_file do |f|
192
+ f.path "/src/test/file_2_test.exs"
193
+ f.mtime Time.new(2015, 01, 01, 00, 00, 00)
194
+ f.contents ""
195
+ end
196
+
197
+ searcher.mock_file do |f|
198
+ f.path "/src/test/file_3_test.exs"
199
+ f.mtime Time.new(2014, 01, 01, 00, 00, 00)
200
+ f.contents ""
201
+ end
202
+
203
+ searcher.mock_file do |f|
204
+ f.path "/src/test/other_test.exs"
205
+ f.contents ""
206
+ end
207
+ end
208
+
209
+ launch("file_1 file_2", searcher: searcher)
210
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs /src/test/file_2_test.exs", shell_mock.recall_exec
211
+
212
+ launch("file_1 file", searcher: searcher)
213
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs /src/test/file_2_test.exs /src/test/file_3_test.exs", shell_mock.recall_exec
214
+
215
+ # If multiple queries are submitted but not all of them match,
216
+ # then what should we do? For now, we assume that it's only
217
+ # considered a match if each query term matches at least one
218
+ # or more files.
219
+ launch("file_1 gibberish", searcher: searcher)
220
+ assert_equal nil, shell_mock.recall_exec
221
+ end
222
+
223
+ def test__by_regex__one_match
224
+ searcher = MemorySearcher.new do |searcher|
225
+ searcher.mock_file do |f|
226
+ f.path "/src/test/file_1_test.exs"
227
+ f.mtime Time.new(2013, 01, 01, 00, 00, 00)
228
+ f.contents <<-RB
229
+ regex match 1
230
+ regex match 2
231
+ regex match 3
232
+ RB
233
+ end
234
+
235
+ searcher.mock_file do |f|
236
+ f.path "/src/test/file_2_test.exs"
237
+ f.mtime Time.new(2015, 01, 01, 00, 00, 00)
238
+ f.contents <<-RB
239
+ regex match 1
240
+ regex match 2
241
+ RB
242
+ end
243
+
244
+ searcher.mock_file do |f|
245
+ f.path "/src/test/file_3_test.exs"
246
+ f.mtime Time.new(2014, 01, 01, 00, 00, 00)
247
+ f.contents <<-RB
248
+ regex match 1
249
+ regex match 3
250
+ RB
251
+ end
252
+ end
253
+
254
+ launch("regex match 1", searcher: searcher)
255
+ assert_equal "cd /src && mix test /src/test/file_2_test.exs", shell_mock.recall_exec
256
+
257
+ launch("regex match 3", searcher: searcher)
258
+ assert_equal "cd /src && mix test /src/test/file_3_test.exs", shell_mock.recall_exec
259
+
260
+ launch("regex match", searcher: searcher)
261
+ assert_equal "cd /src && mix test /src/test/file_2_test.exs", shell_mock.recall_exec
262
+
263
+ launch("regex match --all", searcher: searcher)
264
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs /src/test/file_2_test.exs /src/test/file_3_test.exs", shell_mock.recall_exec
265
+ end
266
+
267
+ def test__by_example__handles_regex_for_example_name
268
+ searcher = MemorySearcher.new do |searcher|
269
+ searcher.mock_file do |f|
270
+ f.path "/src/test/file_1_test.exs"
271
+ f.mtime Time.new(2013, 01, 01, 00, 00, 00)
272
+ f.contents <<-RB
273
+ test "test_name_1" do
274
+ RB
275
+ end
276
+
277
+ searcher.mock_file do |f|
278
+ f.path "/src/test/file_2_test.exs"
279
+ f.mtime Time.new(2015, 01, 01, 00, 00, 00)
280
+ f.contents <<-RB
281
+ test "test_name_2" do
282
+ RB
283
+ end
284
+ end
285
+
286
+ launch("test_name_1x?", searcher: searcher)
287
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs:1", shell_mock.recall_exec
288
+
289
+ launch("test_name_2|test_name_1", searcher: searcher)
290
+ assert_equal "cd /src && mix test /src/test/file_2_test.exs:1", shell_mock.recall_exec
291
+
292
+ launch('test_name_\d', searcher: searcher)
293
+ assert_equal "cd /src && mix test /src/test/file_2_test.exs:1", shell_mock.recall_exec
294
+
295
+ launch('test_name_\d --all', searcher: searcher)
296
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs /src/test/file_2_test.exs", shell_mock.recall_exec
297
+ end
298
+
299
+ def test__not_found
300
+ searcher = MemorySearcher.new do |searcher|
301
+ searcher.mock_file do |f|
302
+ f.path "/src/test/file_1_test.exs"
303
+ f.mtime Time.new(2013, 01, 01, 00, 00, 00)
304
+ f.contents <<-RB
305
+ some stuff
306
+ RB
307
+ end
308
+ end
309
+
310
+ launch("gibberish", searcher: searcher)
311
+ assert_equal nil, shell_mock.recall_exec
312
+ end
313
+
314
+ def test__different_roots
315
+ searcher = MemorySearcher.new do |searcher|
316
+ searcher.mock_file do |f|
317
+ f.path "/src/test/file_1_test.exs"
318
+ f.mtime Time.new(2013, 01, 01, 00, 00, 00)
319
+ f.contents <<-RB
320
+ test "test_name_1" do
321
+ RB
322
+ end
323
+
324
+ searcher.mock_file do |f|
325
+ f.path "/src/test/file_2_test.exs"
326
+ f.mtime Time.new(2015, 01, 01, 00, 00, 00)
327
+ f.contents <<-RB
328
+ test "test_name_2" do
329
+ RB
330
+ end
331
+
332
+ searcher.mock_file do |f|
333
+ f.path "/src/inline/project/test/file_1_test.exs"
334
+ f.mtime Time.new(2014, 01, 01, 00, 00, 00)
335
+ f.contents <<-RB
336
+ test "test_name_1" do
337
+ RB
338
+ end
339
+ end
340
+
341
+ launch("test_name_1", searcher: searcher)
342
+ assert_equal "cd /src/inline/project && mix test /src/inline/project/test/file_1_test.exs:1", shell_mock.recall_exec
343
+
344
+ launch("test_name_1 --all", searcher: searcher)
345
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs; cd -;\n\ncd /src/inline/project && mix test /src/inline/project/test/file_1_test.exs", shell_mock.recall_exec
346
+
347
+ launch("file --all", searcher: searcher)
348
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs /src/test/file_2_test.exs; cd -;\n\ncd /src/inline/project && mix test /src/inline/project/test/file_1_test.exs", shell_mock.recall_exec
349
+
350
+ launch("file_1", searcher: searcher)
351
+ assert_equal "cd /src/inline/project && mix test /src/inline/project/test/file_1_test.exs", shell_mock.recall_exec
352
+
353
+ launch("file_1 --all", searcher: searcher)
354
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs; cd -;\n\ncd /src/inline/project && mix test /src/inline/project/test/file_1_test.exs", shell_mock.recall_exec
355
+ end
356
+
357
+ def test__by_line_number__just_passes_through_to_ex_unit
358
+ searcher = MemorySearcher.new do |searcher|
359
+ searcher.mock_file do |f|
360
+ f.path "/src/test/file_1_test.exs"
361
+ f.mtime Time.new(2013, 01, 01, 00, 00, 00)
362
+ f.contents ""
363
+ end
364
+ end
365
+
366
+ launch("file_1_test.exs:1", searcher: searcher)
367
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs:1", shell_mock.recall_exec
368
+
369
+ launch("file_1_test.exs:273", searcher: searcher)
370
+ assert_equal "cd /src && mix test /src/test/file_1_test.exs:273", shell_mock.recall_exec
371
+ end
372
+
373
+ def test__by_line_number__multiple_files
374
+ searcher = MemorySearcher.new do |searcher|
375
+ searcher.mock_file do |f|
376
+ f.path "/src/test/file_1_test.exs"
377
+ f.mtime Time.new(2013, 01, 01, 00, 00, 00)
378
+ f.contents ""
379
+ end
380
+
381
+ searcher.mock_file do |f|
382
+ f.path "/src/inline/project/test/file_1_test.exs"
383
+ f.mtime Time.new(2014, 01, 01, 00, 00, 00)
384
+ f.contents ""
385
+ end
386
+ end
387
+
388
+ launch("file_1_test.exs:1", searcher: searcher)
389
+ assert_equal "cd /src/inline/project && mix test /src/inline/project/test/file_1_test.exs:1", shell_mock.recall_exec
390
+ end
391
+ end
392
+ end