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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bec50a9c524cc40a441ef84656924dde66c64180
4
- data.tar.gz: e169e16a035000ab3d166b321154aa0a48cf4b45
3
+ metadata.gz: a15a71d527a5bfc218b66b112fa17c190206b667
4
+ data.tar.gz: ae00269c6b9506995cb3c62106e0e2eea9a9513e
5
5
  SHA512:
6
- metadata.gz: ad89e33583acd9308650adda78584da91bcf2eb6d4d757afe549694627772f9e382b7f8a1dacb45e4b97db1f13bc6b299e8820692f693279005fd415df6019f2
7
- data.tar.gz: 8ff9dcd11e12cd9d18ce096deeaa64c479d3224ace21cb659dd6974400be0a77dad6250a2661c359773eee64aed2044d6733fb11321e30ad92ce057fe5c6530a
6
+ metadata.gz: 2550c215d5d98b04d1f1333acc3c79ebba130beaf92db8caa8eee08a5e94aa39105915eeb799bfddca7d9e6c4c56c8ad2faade2d85221cc3218bc9c3effaf3a9
7
+ data.tar.gz: 4758c47037e7588ec9dcbfbb55d863217f7bc15179fa29661e5130dbc053cc3e202af640bf5ad1f06109fa6dd36a511680956ab72c8fffd9489e1787d4beed88
data/.gitignore CHANGED
@@ -12,3 +12,4 @@
12
12
  *.o
13
13
  *.a
14
14
  mkmf.log
15
+ notes.txt
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
@@ -1,3 +1,3 @@
1
1
  module TestRun
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
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{Write a short summary. Required.}
12
- spec.description = %q{Write a longer description. Optional.}
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.1
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-27 00:00:00.000000000 Z
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: Write a longer description. Optional.
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.4.3
90
+ rubygems_version: 2.2.2
77
91
  signing_key:
78
92
  specification_version: 4
79
- summary: Write a short summary. Required.
93
+ summary: Easily run tests
80
94
  test_files: []