test_launcher 1.5.2 → 2.0.0

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