test_run 0.0.1 → 0.0.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/.gitignore +1 -0
- data/bin/test_runner +38 -0
- data/lib/test_run/searchers/git_searcher.rb +38 -0
- data/lib/test_run/shell/color.rb +26 -0
- data/lib/test_run/shell/runner.rb +66 -0
- data/lib/test_run/tests/minitest/consolidator.rb +42 -0
- data/lib/test_run/tests/minitest/finder.rb +50 -0
- data/lib/test_run/tests/minitest/wrappers/multiple_files.rb +23 -0
- data/lib/test_run/tests/minitest/wrappers/multiple_roots.rb +28 -0
- data/lib/test_run/tests/minitest/wrappers/single_file.rb +33 -0
- data/lib/test_run/tests/minitest/wrappers/single_root.rb +33 -0
- data/lib/test_run/tests/minitest/wrappers/single_test.rb +42 -0
- data/lib/test_run/utils/path.rb +32 -0
- data/lib/test_run/version.rb +1 -1
- data/test_run-0.0.1.gem +0 -0
- data/test_run.gemspec +2 -2
- metadata +20 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a15a71d527a5bfc218b66b112fa17c190206b667
|
4
|
+
data.tar.gz: ae00269c6b9506995cb3c62106e0e2eea9a9513e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2550c215d5d98b04d1f1333acc3c79ebba130beaf92db8caa8eee08a5e94aa39105915eeb799bfddca7d9e6c4c56c8ad2faade2d85221cc3218bc9c3effaf3a9
|
7
|
+
data.tar.gz: 4758c47037e7588ec9dcbfbb55d863217f7bc15179fa29661e5130dbc053cc3e202af640bf5ad1f06109fa6dd36a511680956ab72c8fffd9489e1787d4beed88
|
data/.gitignore
CHANGED
data/bin/test_runner
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "thor"
|
4
|
+
require "test_run/tests/minitest/finder"
|
5
|
+
require "test_run/tests/minitest/consolidator"
|
6
|
+
require "test_run/shell/runner"
|
7
|
+
|
8
|
+
class CLI < Thor
|
9
|
+
|
10
|
+
desc "find", <<-DESC
|
11
|
+
Find tests and run them. By trying to match an individual test or the name of a test file(s).
|
12
|
+
DESC
|
13
|
+
|
14
|
+
def find(input)
|
15
|
+
if input == '--help'
|
16
|
+
puts "use 'test_runner --help find' to see the help"
|
17
|
+
exit
|
18
|
+
end
|
19
|
+
|
20
|
+
shell = TestRun::Shell::Runner.new(
|
21
|
+
log_path: '/tmp/test_run.log',
|
22
|
+
working_directory: '.',
|
23
|
+
|
24
|
+
)
|
25
|
+
|
26
|
+
find_results = TestRun::Tests::Minitest::Finder.find(input, shell, options)
|
27
|
+
|
28
|
+
test_wrapper = TestRun::Tests::Minitest::Consolidator.consolidate(find_results, shell)
|
29
|
+
|
30
|
+
if test_wrapper.should_run?
|
31
|
+
shell.exec test_wrapper.to_command
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
default_task :find
|
36
|
+
end
|
37
|
+
|
38
|
+
CLI.start(ARGV)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module TestRun
|
2
|
+
module Searchers
|
3
|
+
class GitSearcher < Struct.new(:shell)
|
4
|
+
|
5
|
+
def find_files(pattern)
|
6
|
+
shell.run("git ls-files '*#{pattern}*'")
|
7
|
+
end
|
8
|
+
|
9
|
+
def grep(regex, file_pattern: '*')
|
10
|
+
results = shell.run("git grep --untracked '#{regex}' -- '#{file_pattern}'")
|
11
|
+
results.map do |result|
|
12
|
+
interpret_grep_result(result)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def interpret_grep_result(grep_result)
|
19
|
+
splits = grep_result.split(/:/)
|
20
|
+
file = splits.shift.strip
|
21
|
+
# we rejoin on ':' because our
|
22
|
+
# code may have colons inside of it.
|
23
|
+
#
|
24
|
+
# example:
|
25
|
+
# path/to/file: run_method(a: A, b: B)
|
26
|
+
#
|
27
|
+
# so shift the first one out, then
|
28
|
+
# rejoin the rest
|
29
|
+
line = splits.join(':').strip
|
30
|
+
|
31
|
+
{
|
32
|
+
:file => file,
|
33
|
+
:line => line,
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module TestRun
|
2
|
+
module Shell
|
3
|
+
module Color
|
4
|
+
CODES = {
|
5
|
+
red: 31,
|
6
|
+
green: 32,
|
7
|
+
yellow: 33,
|
8
|
+
pink: 35,
|
9
|
+
}.freeze
|
10
|
+
|
11
|
+
CODES.each do |color, code|
|
12
|
+
self.send(:define_method, color) do |string|
|
13
|
+
colorize(string, code)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
# colorization
|
20
|
+
def colorize(string, color_code)
|
21
|
+
"\e[#{color_code}m#{string}\e[0m"
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require "test_run/shell/color"
|
2
|
+
require "test_run/utils/path"
|
3
|
+
|
4
|
+
module TestRun
|
5
|
+
module Shell
|
6
|
+
class Runner
|
7
|
+
include Color
|
8
|
+
|
9
|
+
CommandFailureError = Class.new(StandardError)
|
10
|
+
|
11
|
+
attr_accessor :working_directory, :log_path, :queue
|
12
|
+
private :working_directory, :log_path, :queue
|
13
|
+
|
14
|
+
def initialize(log_path:, working_directory:)
|
15
|
+
@working_directory = working_directory
|
16
|
+
@log_path = log_path
|
17
|
+
|
18
|
+
%x{echo "" > #{log_path}}
|
19
|
+
Dir.chdir(%x[ git rev-parse --show-toplevel ].chomp)
|
20
|
+
end
|
21
|
+
|
22
|
+
def run(cmd, dir: working_directory, &block)
|
23
|
+
command = "cd #{Utils::Path.relative_join(dir)} && #{cmd}"
|
24
|
+
handle_output_for(command)
|
25
|
+
|
26
|
+
shell_out(command).split("\n")
|
27
|
+
end
|
28
|
+
|
29
|
+
def exec(cmd)
|
30
|
+
notify cmd
|
31
|
+
Kernel.exec cmd
|
32
|
+
end
|
33
|
+
|
34
|
+
def warn(msg)
|
35
|
+
log msg.to_s
|
36
|
+
print "#{red(msg.to_s)}\n"
|
37
|
+
end
|
38
|
+
|
39
|
+
def notify(msg)
|
40
|
+
log msg.to_s
|
41
|
+
print "#{yellow(msg.to_s)}\n"
|
42
|
+
end
|
43
|
+
|
44
|
+
def confirm?(question)
|
45
|
+
warn "#{question} [Yn]"
|
46
|
+
answer = STDIN.gets.strip.downcase
|
47
|
+
return answer != 'n'
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def log(msg)
|
53
|
+
%x{echo "#{msg.to_s}" >> #{log_path}}
|
54
|
+
end
|
55
|
+
|
56
|
+
def handle_output_for(cmd)
|
57
|
+
log(cmd)
|
58
|
+
end
|
59
|
+
|
60
|
+
def shell_out(command)
|
61
|
+
%x{ set -o pipefail && #{command} 2>> #{log_path} | tee -a #{log_path} }.chomp
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "test_run/utils/path"
|
2
|
+
|
3
|
+
require "test_run/tests/minitest/wrappers/single_test"
|
4
|
+
require "test_run/tests/minitest/wrappers/single_file"
|
5
|
+
require "test_run/tests/minitest/wrappers/multiple_files"
|
6
|
+
|
7
|
+
module TestRun
|
8
|
+
module Tests
|
9
|
+
module Minitest
|
10
|
+
class Consolidator < Struct.new(:find_results, :shell)
|
11
|
+
|
12
|
+
def self.consolidate(*args)
|
13
|
+
new(*args).consolidate
|
14
|
+
end
|
15
|
+
|
16
|
+
def consolidate
|
17
|
+
if find_results.empty?
|
18
|
+
puts "no results"
|
19
|
+
exit
|
20
|
+
end
|
21
|
+
|
22
|
+
if one_result?
|
23
|
+
Wrappers::SingleTest.new(find_results.first)
|
24
|
+
elsif one_test_file?
|
25
|
+
Wrappers::SingleFile.new(find_results.first[:file])
|
26
|
+
else
|
27
|
+
Wrappers::MultipleFiles.wrap(find_results.map {|r| r[:file] }, shell)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def one_test_file?
|
32
|
+
find_results.group_by {|f| f[:file]}.size == 1
|
33
|
+
end
|
34
|
+
|
35
|
+
def one_result?
|
36
|
+
one_test_file? && find_results.first[:line]
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "test_run/searchers/git_searcher"
|
2
|
+
|
3
|
+
module TestRun
|
4
|
+
module Tests
|
5
|
+
module Minitest
|
6
|
+
class Finder < Struct.new(:query, :shell, :searcher, :options)
|
7
|
+
|
8
|
+
def self.find(query, shell, options)
|
9
|
+
searcher = Searchers::GitSearcher.new(shell)
|
10
|
+
new(query, shell, searcher, options).find
|
11
|
+
end
|
12
|
+
|
13
|
+
def find
|
14
|
+
return tests_found_by_absolute_path if query.match(/^\//)
|
15
|
+
|
16
|
+
return tests_found_by_name unless tests_found_by_name.empty?
|
17
|
+
|
18
|
+
return tests_found_by_file_name unless tests_found_by_file_name.empty?
|
19
|
+
|
20
|
+
return tests_found_by_full_regex unless tests_found_by_full_regex.empty?
|
21
|
+
|
22
|
+
[]
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def tests_found_by_absolute_path
|
28
|
+
[ {file: query} ]
|
29
|
+
end
|
30
|
+
|
31
|
+
def tests_found_by_name
|
32
|
+
@tests_found_by_name ||= full_regex_search("^\s*def .*#{query}.*")
|
33
|
+
end
|
34
|
+
|
35
|
+
def tests_found_by_file_name
|
36
|
+
@tests_found_by_file_name ||= searcher.find_files(query).select { |f| f.match(/_test\.rb/) }.map {|f| {file: f} }
|
37
|
+
end
|
38
|
+
|
39
|
+
def tests_found_by_full_regex
|
40
|
+
# we ignore the matched line since we don't know what to do with it
|
41
|
+
@tests_found_by_full_regex ||= full_regex_search(query).map {|t| {file: t[:file]} }
|
42
|
+
end
|
43
|
+
|
44
|
+
def full_regex_search(regex)
|
45
|
+
searcher.grep(regex, file_pattern: '*_test.rb')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "test_run/tests/minitest/wrappers/single_root"
|
2
|
+
require "test_run/tests/minitest/wrappers/multiple_roots"
|
3
|
+
|
4
|
+
module TestRun
|
5
|
+
module Tests
|
6
|
+
module Minitest
|
7
|
+
module Wrappers
|
8
|
+
module MultipleFiles
|
9
|
+
|
10
|
+
def self.wrap(files, shell)
|
11
|
+
wrapper = MultipleRoots.new(files, shell)
|
12
|
+
|
13
|
+
if wrapper.roots.size > 1
|
14
|
+
wrapper
|
15
|
+
else
|
16
|
+
wrapper.roots.first
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "test_run/utils/path"
|
2
|
+
|
3
|
+
module TestRun
|
4
|
+
module Tests
|
5
|
+
module Minitest
|
6
|
+
module Wrappers
|
7
|
+
class MultipleRoots
|
8
|
+
|
9
|
+
attr_reader :roots, :shell
|
10
|
+
|
11
|
+
def initialize(files, shell)
|
12
|
+
@shell = shell
|
13
|
+
@roots = files.map {|f| SingleFile.new(f)}.group_by {|f| f.app_root}.map {|root, _files| SingleRoot.new(_files, shell)}
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_command
|
17
|
+
roots.map(&:to_command).join("; cd -; \n\n")
|
18
|
+
end
|
19
|
+
|
20
|
+
def should_run?
|
21
|
+
shell.confirm?("Found #{roots.inject(0) {|sum, root| sum + root.files.size }} test files in #{roots.size} apps/engines. Run them all?")
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "test_run/utils/path"
|
2
|
+
|
3
|
+
module TestRun
|
4
|
+
module Tests
|
5
|
+
module Minitest
|
6
|
+
module Wrappers
|
7
|
+
class SingleFile < Struct.new(:file)
|
8
|
+
|
9
|
+
def to_command
|
10
|
+
%{cd #{File.join(app_root)} && ruby -I test #{File.join(relative_test_path)}}
|
11
|
+
end
|
12
|
+
|
13
|
+
def app_root
|
14
|
+
exploded_path = Utils::Path.split(file)
|
15
|
+
|
16
|
+
path = exploded_path[0...exploded_path.rindex("test")]
|
17
|
+
File.join(path)
|
18
|
+
end
|
19
|
+
|
20
|
+
def relative_test_path
|
21
|
+
exploded_path = Utils::Path.split(file)
|
22
|
+
path = exploded_path[exploded_path.rindex("test")..-1]
|
23
|
+
File.join(path)
|
24
|
+
end
|
25
|
+
|
26
|
+
def should_run?
|
27
|
+
true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "test_run/utils/path"
|
2
|
+
|
3
|
+
module TestRun
|
4
|
+
module Tests
|
5
|
+
module Minitest
|
6
|
+
module Wrappers
|
7
|
+
class SingleRoot
|
8
|
+
|
9
|
+
attr_reader :files, :shell
|
10
|
+
|
11
|
+
def initialize(files, shell)
|
12
|
+
@shell = shell
|
13
|
+
@files = files.map {|f| f.is_a?(SingleFile) ? f : SingleFile.new(f)}
|
14
|
+
end
|
15
|
+
|
16
|
+
def should_run?
|
17
|
+
# keep working here!
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_command
|
22
|
+
%{cd #{app_root} && ruby -I test -e 'ARGV.each { |file| require(Dir.pwd + "/" + file) }' #{files.map(&:relative_test_path).join(" ")}}
|
23
|
+
end
|
24
|
+
|
25
|
+
def app_root
|
26
|
+
files.first.app_root
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "test_run/utils/path"
|
2
|
+
|
3
|
+
module TestRun
|
4
|
+
module Tests
|
5
|
+
module Minitest
|
6
|
+
module Wrappers
|
7
|
+
class SingleTest
|
8
|
+
|
9
|
+
attr_reader :file, :name
|
10
|
+
private :file, :name
|
11
|
+
|
12
|
+
def initialize(file:, line:)
|
13
|
+
@file = file
|
14
|
+
@name = line[/\s*def\s+(.*)/, 1]
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_command
|
18
|
+
%{cd #{app_root} && ruby -I test #{relative_test_path} --name=/#{name}/}
|
19
|
+
end
|
20
|
+
|
21
|
+
def app_root
|
22
|
+
exploded_path = Utils::Path.split(file)
|
23
|
+
|
24
|
+
path = exploded_path[0...exploded_path.rindex("test")]
|
25
|
+
File.join(path)
|
26
|
+
end
|
27
|
+
|
28
|
+
def relative_test_path
|
29
|
+
exploded_path = Utils::Path.split(file)
|
30
|
+
path = exploded_path[exploded_path.rindex("test")..-1]
|
31
|
+
File.join(path)
|
32
|
+
end
|
33
|
+
|
34
|
+
def should_run?
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "pathname"
|
2
|
+
|
3
|
+
module TestRun
|
4
|
+
module Utils
|
5
|
+
module Path
|
6
|
+
|
7
|
+
def self.split(filename)
|
8
|
+
self.prepend_pwd(Pathname.new(filename).each_filename.to_a)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.path_for(filename)
|
12
|
+
self.split(File.split(file)[0])
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.join(*array)
|
16
|
+
File.join(*array)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.prepend_pwd(dirs)
|
20
|
+
if dirs[0] == "."
|
21
|
+
dirs
|
22
|
+
else
|
23
|
+
["."] + dirs
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.relative_join(array)
|
28
|
+
join(prepend_pwd(array))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/test_run/version.rb
CHANGED
data/test_run-0.0.1.gem
ADDED
Binary file
|
data/test_run.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = TestRun::VERSION
|
9
9
|
spec.authors = ["Pete Kinnecom"]
|
10
10
|
spec.email = ["pete.kinnecom@appfolio.com"]
|
11
|
-
spec.summary = %q{
|
12
|
-
spec.description = %q{
|
11
|
+
spec.summary = %q{Easily run tests}
|
12
|
+
spec.description = %q{no really}
|
13
13
|
spec.homepage = ""
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: test_run
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pete Kinnecom
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,10 +38,11 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
|
-
description:
|
41
|
+
description: no really
|
42
42
|
email:
|
43
43
|
- pete.kinnecom@appfolio.com
|
44
|
-
executables:
|
44
|
+
executables:
|
45
|
+
- test_runner
|
45
46
|
extensions: []
|
46
47
|
extra_rdoc_files: []
|
47
48
|
files:
|
@@ -50,8 +51,21 @@ files:
|
|
50
51
|
- LICENSE.txt
|
51
52
|
- README.md
|
52
53
|
- Rakefile
|
54
|
+
- bin/test_runner
|
53
55
|
- lib/test_run.rb
|
56
|
+
- lib/test_run/searchers/git_searcher.rb
|
57
|
+
- lib/test_run/shell/color.rb
|
58
|
+
- lib/test_run/shell/runner.rb
|
59
|
+
- lib/test_run/tests/minitest/consolidator.rb
|
60
|
+
- lib/test_run/tests/minitest/finder.rb
|
61
|
+
- lib/test_run/tests/minitest/wrappers/multiple_files.rb
|
62
|
+
- lib/test_run/tests/minitest/wrappers/multiple_roots.rb
|
63
|
+
- lib/test_run/tests/minitest/wrappers/single_file.rb
|
64
|
+
- lib/test_run/tests/minitest/wrappers/single_root.rb
|
65
|
+
- lib/test_run/tests/minitest/wrappers/single_test.rb
|
66
|
+
- lib/test_run/utils/path.rb
|
54
67
|
- lib/test_run/version.rb
|
68
|
+
- test_run-0.0.1.gem
|
55
69
|
- test_run.gemspec
|
56
70
|
homepage: ''
|
57
71
|
licenses:
|
@@ -73,8 +87,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
87
|
version: '0'
|
74
88
|
requirements: []
|
75
89
|
rubyforge_project:
|
76
|
-
rubygems_version: 2.
|
90
|
+
rubygems_version: 2.2.2
|
77
91
|
signing_key:
|
78
92
|
specification_version: 4
|
79
|
-
summary:
|
93
|
+
summary: Easily run tests
|
80
94
|
test_files: []
|