test_launcher 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/README.md +101 -18
- data/Rakefile +6 -0
- data/bin/test_launcher +8 -35
- data/lib/test_launcher.rb +22 -0
- data/lib/test_launcher/cli/input_parser.rb +73 -0
- data/lib/test_launcher/frameworks.rb +32 -0
- data/lib/test_launcher/frameworks/base.rb +54 -0
- data/lib/test_launcher/frameworks/implementation/collection.rb +27 -0
- data/lib/test_launcher/{tests/minitest → frameworks/implementation}/consolidator.rb +30 -32
- data/lib/test_launcher/frameworks/implementation/locator.rb +74 -0
- data/lib/test_launcher/frameworks/implementation/test_case.rb +65 -0
- data/lib/test_launcher/frameworks/minitest.rb +67 -0
- data/lib/test_launcher/frameworks/rspec.rb +50 -0
- data/lib/test_launcher/rubymine.rb +26 -0
- data/lib/test_launcher/rubymine/launcher.rb +55 -0
- data/lib/test_launcher/search/git.rb +64 -0
- data/lib/test_launcher/shell/runner.rb +19 -22
- data/lib/test_launcher/version.rb +1 -1
- data/test/install +3 -0
- data/test/test_helper.rb +32 -17
- data/test/test_launcher/fixtures/minitest/test/class_1_test.rb +17 -0
- data/test/test_launcher/fixtures/minitest/test/class_2_test.rb +5 -0
- data/test/test_launcher/fixtures/minitest/test/different_root/bin/spring +1 -0
- data/test/test_launcher/fixtures/minitest/test/different_root/test/different_root_test.rb +2 -0
- data/test/test_launcher/fixtures/rspec/spec/class_1_spec.rb +16 -0
- data/test/test_launcher/fixtures/rspec/spec/class_2_spec.rb +6 -0
- data/test/test_launcher/fixtures/rspec/spec/different_root/spec/different_root_spec.rb +2 -0
- data/test/test_launcher/minitest_integration_test.rb +67 -0
- data/test/test_launcher/rspec_integration_test.rb +67 -0
- data/test/test_launcher/rubymine_test.rb +48 -0
- data/test_launcher.gemspec +2 -3
- metadata +39 -44
- data/bin/test_runner +0 -1
- data/lib/test_launcher/searchers/git_searcher.rb +0 -38
- data/lib/test_launcher/tests/minitest/finder.rb +0 -50
- data/lib/test_launcher/tests/minitest/wrappers/multiple_files.rb +0 -23
- data/lib/test_launcher/tests/minitest/wrappers/multiple_roots.rb +0 -23
- data/lib/test_launcher/tests/minitest/wrappers/single_file.rb +0 -29
- data/lib/test_launcher/tests/minitest/wrappers/single_root.rb +0 -27
- data/lib/test_launcher/tests/minitest/wrappers/single_test.rb +0 -37
- data/lib/test_launcher/utils/path.rb +0 -32
- data/lib/test_launcher/utils/pluralize.rb +0 -14
- data/test/test_launcher/searchers/git_searcher_test.rb +0 -50
- data/test/test_launcher/tests/minitest/consolidator_integration_test.rb +0 -191
- data/test/test_launcher/tests/minitest/finder_test.rb +0 -71
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5d53997bd88d7bff2231d598664f4a9d2c17534
|
4
|
+
data.tar.gz: 665cc8fafb6894917dd92c8c788e3312698df4a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 195db1420d9e19aeef576839f018f5a9596f5ef873401ae46e0a695a4fc52de4cf948092e714d627a367e9dcf8d91388c723a06067f9b01eeca9f3c91cce6168
|
7
|
+
data.tar.gz: a70dd282dcd28bab87961be98c848cb1d5b8a825d89b7befae3c67270f1331c17dd7a473ad6e265ea0875de9214f9db20fcef9a97c784acae0414c14aa45ad01
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
#Test Launcher -->
|
2
2
|
|
3
|
-
Test Launcher takes some input and tries to figure out what test you want to run. It makes running tests on the command line much easier. Test Launcher works with Minitest
|
3
|
+
Test Launcher takes some input and tries to figure out what test you want to run. It makes running tests on the command line much easier. Test Launcher works with Minitest. RSpec support is in its infancy. You should try it and let me know!
|
4
|
+
|
5
|
+
### Usage
|
4
6
|
|
5
7
|
Let's suppose you want to run the test `test_name` in your `blog_post_test.rb`.
|
6
8
|
|
@@ -13,7 +15,7 @@ ruby -I test test/models/blog_post_test.rb --name=test_blog_name_thing
|
|
13
15
|
But with Test Launcher, you can just type this:
|
14
16
|
|
15
17
|
```
|
16
|
-
|
18
|
+
test_launcher test_blog_name_thing
|
17
19
|
|
18
20
|
#=> ruby -I test test/models/blog_post_test.rb --name=test_blog_name_thing
|
19
21
|
```
|
@@ -21,7 +23,7 @@ t test_blog_name_thing
|
|
21
23
|
What if you want to run a whole file? Just go for it!
|
22
24
|
|
23
25
|
```
|
24
|
-
|
26
|
+
test_launcher blog_post_test
|
25
27
|
|
26
28
|
#=> ruby -I test test/models/blog_post_test.rb
|
27
29
|
```
|
@@ -29,7 +31,7 @@ t blog_post_test
|
|
29
31
|
What if you just have the class name for the test?
|
30
32
|
|
31
33
|
```
|
32
|
-
|
34
|
+
test_launcher BlogPostTest
|
33
35
|
|
34
36
|
#=> ruby -I test test/models/blog_post_test.rb
|
35
37
|
```
|
@@ -37,14 +39,43 @@ t BlogPostTest
|
|
37
39
|
But what if you aren't specific enough?
|
38
40
|
|
39
41
|
```
|
40
|
-
|
42
|
+
test_launcher test_blog_na
|
41
43
|
|
42
44
|
#=> Found 10 test methods in 3 files.
|
43
45
|
#=> Running most recently edited. Run with '--all' to run all the tests.
|
44
46
|
#=> ruby -I test test/models/blog_post_test.rb --name=test_blog_name_thing
|
45
47
|
```
|
46
48
|
|
47
|
-
|
49
|
+
What if you are very specific?
|
50
|
+
```
|
51
|
+
test_launcher /Users/username/code/my_repo/test/models/blog_post_test.rb
|
52
|
+
|
53
|
+
#=> ruby -I test test/models/blog_post_test.rb
|
54
|
+
```
|
55
|
+
|
56
|
+
### Inline Gems
|
57
|
+
|
58
|
+
Test Launcher will automatically move to the correct subdirectory in order to run the tests. For example, if `thing_test.rb` is within your inline_gem, you can run:
|
59
|
+
|
60
|
+
```
|
61
|
+
test_launcher thing_test
|
62
|
+
|
63
|
+
#=> cd /path/to/inline_gem && ruby -I test test/thing_test.rb
|
64
|
+
```
|
65
|
+
|
66
|
+
You don't have to run Test Launcher from the root of your project either. It will figure things out.
|
67
|
+
|
68
|
+
### Spring preloader
|
69
|
+
|
70
|
+
Test Launcher will check for the spring/testunit binstubs. If they are found in the app/gem/engine it will use spring:
|
71
|
+
|
72
|
+
```
|
73
|
+
test_launcher springified_test
|
74
|
+
|
75
|
+
#=> cd /path/to/app && spring testunit test/springified_test.rb
|
76
|
+
```
|
77
|
+
|
78
|
+
Test Launcher will not use spring if the `DISABLE_SPRING=1` environment variable is set.
|
48
79
|
|
49
80
|
#Installation
|
50
81
|
|
@@ -54,27 +85,33 @@ To install:
|
|
54
85
|
gem install test_launcher
|
55
86
|
```
|
56
87
|
|
88
|
+
Under the hood it uses git to search for files and to grep, so it will only work in git repositories.
|
89
|
+
|
90
|
+
|
57
91
|
#Setup
|
58
92
|
|
59
|
-
This gem installs one executable called `test_launcher`.
|
93
|
+
This gem installs one executable called `test_launcher`.
|
60
94
|
|
61
95
|
```
|
62
|
-
test_launcher
|
96
|
+
test_launcher test_name_to_find
|
63
97
|
```
|
64
98
|
|
65
99
|
For me, that's way too much to type, so I recommend adding an alias to your `.bash_profile` like so:
|
66
100
|
|
67
101
|
```
|
68
|
-
alias t=
|
102
|
+
alias t='test_launcher'
|
103
|
+
|
104
|
+
# If you are using RVM, use this: (see below for more details)
|
105
|
+
alias t='NOEXEC_DISABLE=1 test_launcher'
|
69
106
|
```
|
70
107
|
|
71
|
-
Now you can just type `t` instead of `test_launcher
|
108
|
+
Now you can just type `t` instead of `test_launcher`. Much nicer!
|
72
109
|
|
73
110
|
#Usage
|
74
111
|
|
75
112
|
Test Launcher searches for tests based on your input.
|
76
113
|
|
77
|
-
Suppose you type `
|
114
|
+
Suppose you type `test_launcher thing`. It will run tests using this priority preference:
|
78
115
|
|
79
116
|
1. A single, specific test method name or partial name
|
80
117
|
- `def test_the_thing`
|
@@ -88,20 +125,66 @@ Suppose you type `t thing`. It will run tests using this priority preference:
|
|
88
125
|
1. Any test file based on a generic search
|
89
126
|
- runs `stuff_test.rb` because it found the word `thing` inside of it
|
90
127
|
|
91
|
-
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
|
128
|
+
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!
|
92
129
|
|
93
|
-
#
|
130
|
+
# RubyMine Support
|
94
131
|
|
95
|
-
|
132
|
+
When working with inline gems/engines, RubyMine has a hard time figuring out what `test` folders to push into the load path for Minitest. RubyMine also does not understand that in a project with inline engines, some of them may use Spring and some may not. When working with inline gems/engines/apps in RubyMine, you end up having to 'Edit Configurations...' many times a day. This is a bummer.
|
96
133
|
|
97
|
-
Test Launcher
|
134
|
+
Test Launcher can be used from RubyMine to help alleviate these problems. Requiring the `test_launcher/rubymine` file in your run configurations will allow Test Launcher to fix RubyMine's test running to do what you want.
|
135
|
+
|
136
|
+
To use the RubyMine support:
|
98
137
|
|
138
|
+
1. Open your project
|
139
|
+
1. Click on Run -> 'Edit Configurations...'
|
140
|
+
1. If you have any run configurations listed under 'Test::Unit/Shoulda/Minitest', use the minus button to remove them.
|
141
|
+
1. Open the 'Defaults' and click on 'Test::Unit/Shoulda/Minitest'
|
142
|
+
1. Under 'Ruby Arguments' change:
|
99
143
|
|
100
144
|
```
|
101
|
-
|
145
|
+
-e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)`
|
146
|
+
```
|
147
|
+
|
148
|
+
Replace it with:
|
102
149
|
|
103
|
-
|
150
|
+
```
|
151
|
+
-r test_launcher/rubymine
|
104
152
|
```
|
105
153
|
|
106
|
-
|
154
|
+
1. Run a test. Test Launcher should report that it is hijacking the test and it will output the command that it has decided to use.
|
155
|
+
|
156
|
+
### Debugging Support
|
157
|
+
|
158
|
+
Using Test Launcher to hijack your RubyMine run configuration should allow you to debug any test as well without issue.
|
159
|
+
|
160
|
+
# Optimizing with RVM
|
161
|
+
|
162
|
+
By default, RVM installs a hook to remove the need to run `bundle exec`. When you run a gem command, it will search your bundle to see if that command is included in your bundle. If it is, it will run that version of the command. If it's not in your bundle, then it will fall back to the global gem. You can read more about it on [rubygems-bundler](https://github.com/rvm/rubygems-bundler).
|
163
|
+
|
164
|
+
Test Launcher is not installed in your bundle. This means that the time that Bundler spends resolving your Gemfile to check if there's a test\_launcher executable in your bundle is wasted. For most projects, the amount of time this takes is probably unnoticeable.
|
107
165
|
|
166
|
+
On projects with lots of dependencies, this wasted time can be significant.
|
167
|
+
|
168
|
+
For example, in a large project, we get a nice improvement:
|
169
|
+
|
170
|
+
```
|
171
|
+
$:time test_launcher something_that_no_test_says
|
172
|
+
#=> Could not find any tests.
|
173
|
+
|
174
|
+
#=> real 0m2.214s
|
175
|
+
#=> user 0m1.407s
|
176
|
+
#=> sys 0m1.062s
|
177
|
+
|
178
|
+
$:time NOEXEC_DISABLE=1 test_launcher something_that_no_test_might_say
|
179
|
+
#=> Could not find any tests.
|
180
|
+
|
181
|
+
#=> real 0m1.412s
|
182
|
+
#=> user 0m0.745s
|
183
|
+
#=> sys 0m0.945s
|
184
|
+
```
|
185
|
+
|
186
|
+
I suggest that if you are using RVM, you may as well make this your alias:
|
187
|
+
|
188
|
+
```
|
189
|
+
alias t='NOEXEC_DISABLE=1 test_launcher'
|
190
|
+
```
|
data/Rakefile
CHANGED
data/bin/test_launcher
CHANGED
@@ -1,39 +1,12 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require "
|
4
|
-
require "test_launcher
|
5
|
-
require "test_launcher/tests/minitest/finder"
|
6
|
-
require "test_launcher/tests/minitest/consolidator"
|
7
|
-
require "test_launcher/shell/runner"
|
3
|
+
require "test_launcher/cli/input_parser"
|
4
|
+
require "test_launcher"
|
8
5
|
|
9
|
-
|
6
|
+
input = TestLauncher::CLI::InputParser.new(ARGV)
|
10
7
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
def find(input)
|
17
|
-
if input == '--help'
|
18
|
-
`test_launcher --help find`
|
19
|
-
exit
|
20
|
-
end
|
21
|
-
|
22
|
-
shell = TestLauncher::Shell::Runner.new(
|
23
|
-
log_path: '/tmp/test_launcher.log',
|
24
|
-
working_directory: '.',
|
25
|
-
|
26
|
-
)
|
27
|
-
|
28
|
-
searcher = TestLauncher::Searchers::GitSearcher.new(shell)
|
29
|
-
search_results = TestLauncher::Tests::Minitest::Finder.find(input, searcher)
|
30
|
-
|
31
|
-
test_wrapper = TestLauncher::Tests::Minitest::Consolidator.consolidate(search_results, shell, options[:all])
|
32
|
-
|
33
|
-
shell.exec test_wrapper.to_command
|
34
|
-
end
|
35
|
-
|
36
|
-
default_task :find
|
37
|
-
end
|
38
|
-
|
39
|
-
CLI.start(ARGV)
|
8
|
+
TestLauncher.launch(
|
9
|
+
input.query,
|
10
|
+
run_all: input.options[:run_all],
|
11
|
+
framework: input.options[:framework]
|
12
|
+
)
|
data/lib/test_launcher.rb
CHANGED
@@ -1,4 +1,26 @@
|
|
1
1
|
require "test_launcher/version"
|
2
2
|
|
3
|
+
require "test_launcher/shell/runner"
|
4
|
+
require "test_launcher/search/git"
|
5
|
+
require "test_launcher/frameworks"
|
6
|
+
|
3
7
|
module TestLauncher
|
8
|
+
def self.launch(input, framework: "guess", run_all: false)
|
9
|
+
shell = Shell::Runner.new(log_path: '/tmp/test_launcher.log')
|
10
|
+
searcher = Searchers::Git.new(shell)
|
11
|
+
|
12
|
+
command = Frameworks.locate(
|
13
|
+
framework_name: framework,
|
14
|
+
shell: shell,
|
15
|
+
searcher: searcher,
|
16
|
+
input: input,
|
17
|
+
run_all: run_all
|
18
|
+
)
|
19
|
+
|
20
|
+
if command
|
21
|
+
shell.exec command
|
22
|
+
else
|
23
|
+
shell.warn "No tests found."
|
24
|
+
end
|
25
|
+
end
|
4
26
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require "test_launcher/version"
|
2
|
+
require "optparse"
|
3
|
+
|
4
|
+
module TestLauncher
|
5
|
+
module CLI
|
6
|
+
class InputParser
|
7
|
+
ParseError = Class.new(RuntimeError)
|
8
|
+
|
9
|
+
BANNER = <<-DESC
|
10
|
+
Find tests and run them by trying to match an individual test or the name of a test file(s).
|
11
|
+
|
12
|
+
See full README: https://github.com/petekinnecom/test_launcher
|
13
|
+
|
14
|
+
Usage: `test_launcher "search string" [--all]`
|
15
|
+
|
16
|
+
VERSION: #{TestLauncher::VERSION}
|
17
|
+
|
18
|
+
DESC
|
19
|
+
|
20
|
+
def initialize(args)
|
21
|
+
@query = args
|
22
|
+
@options = {}
|
23
|
+
option_parser.parse!(args)
|
24
|
+
rescue OptionParser::ParseError
|
25
|
+
puts "Invalid arguments"
|
26
|
+
puts "----"
|
27
|
+
puts option_parser
|
28
|
+
exit
|
29
|
+
end
|
30
|
+
|
31
|
+
def query
|
32
|
+
if @query.size == 0
|
33
|
+
puts option_parser
|
34
|
+
exit
|
35
|
+
elsif @query.size > 1
|
36
|
+
puts "Concatenating args to single string. (see https://github.com/petekinnecom/test_launcher)"
|
37
|
+
end
|
38
|
+
|
39
|
+
@query.join(" ")
|
40
|
+
end
|
41
|
+
|
42
|
+
def options
|
43
|
+
@options
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def option_parser
|
49
|
+
OptionParser.new do |opts|
|
50
|
+
opts.banner = BANNER
|
51
|
+
|
52
|
+
opts.on("-a", "--all", "Run all matching tests. Defaults to false.") do
|
53
|
+
options[:run_all] = true
|
54
|
+
end
|
55
|
+
|
56
|
+
opts.on("-h", "--help", "Prints this help") do
|
57
|
+
puts opts
|
58
|
+
exit
|
59
|
+
end
|
60
|
+
|
61
|
+
opts.on("-v", "--version", "Display the version info") do
|
62
|
+
puts TestLauncher::VERSION
|
63
|
+
exit
|
64
|
+
end
|
65
|
+
|
66
|
+
opts.on("-f", "--framework framework", "The testing framework being used. Valid options: ['minitest', 'rspec', 'guess']. Defaults to 'guess'") do |framework|
|
67
|
+
options[:framework] = framework
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "test_launcher/frameworks/base"
|
2
|
+
require "test_launcher/frameworks/minitest"
|
3
|
+
require "test_launcher/frameworks/rspec"
|
4
|
+
|
5
|
+
module TestLauncher
|
6
|
+
module Frameworks
|
7
|
+
def self.locate(framework_name:, input:, run_all:, shell:, searcher:)
|
8
|
+
frameworks = guess_frameworks(framework_name)
|
9
|
+
|
10
|
+
frameworks.each do |framework|
|
11
|
+
search_results = framework::Locator.new(input, searcher).prioritized_results
|
12
|
+
runner = framework::Runner.new
|
13
|
+
|
14
|
+
command = Implementation::Consolidator.consolidate(search_results, shell, runner, run_all)
|
15
|
+
|
16
|
+
return command if command
|
17
|
+
end
|
18
|
+
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.guess_frameworks(framework_name)
|
23
|
+
if framework_name == "rspec"
|
24
|
+
[RSpec]
|
25
|
+
elsif framework_name == "minitest"
|
26
|
+
[Minitest]
|
27
|
+
else
|
28
|
+
[Minitest, RSpec].select(&:active?)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require "test_launcher/frameworks/implementation/locator"
|
2
|
+
require "test_launcher/frameworks/implementation/test_case"
|
3
|
+
require "test_launcher/frameworks/implementation/consolidator"
|
4
|
+
|
5
|
+
module TestLauncher
|
6
|
+
module Frameworks
|
7
|
+
module Base
|
8
|
+
class Locator < Implementation::Locator
|
9
|
+
def file_name_regex
|
10
|
+
# for ruby to match on file names
|
11
|
+
raise NotImplementedError
|
12
|
+
end
|
13
|
+
|
14
|
+
def file_name_pattern
|
15
|
+
# for bash to match on file names
|
16
|
+
raise NotImplementedError
|
17
|
+
end
|
18
|
+
|
19
|
+
def regex_pattern
|
20
|
+
# to match on examples
|
21
|
+
raise NotImplementedError
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Runner
|
26
|
+
def single_example(test_case)
|
27
|
+
raise NotImplementedError
|
28
|
+
end
|
29
|
+
|
30
|
+
def one_or_more_files(test_cases)
|
31
|
+
raise NotImplementedError
|
32
|
+
end
|
33
|
+
|
34
|
+
def single_file(test_case)
|
35
|
+
one_or_more_files([test_case])
|
36
|
+
end
|
37
|
+
|
38
|
+
def multiple_files(collection)
|
39
|
+
collection
|
40
|
+
.group_by(&:app_root)
|
41
|
+
.map { |_root, test_cases| one_or_more_files(test_cases) }
|
42
|
+
.join("; cd -;\n\n")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class TestCase < Implementation::TestCase
|
47
|
+
def test_root_folder_name
|
48
|
+
# directory where tests are found
|
49
|
+
raise NotImplementedError
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|