test_launcher 0.0.3

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bbd6981a7b53e9af503b959d87bd3dc21bc312a0
4
+ data.tar.gz: 1c2978d49096d3af9cc704c30d83eb1c554cff48
5
+ SHA512:
6
+ metadata.gz: 30a4da05547da73f41746d1a839052493938964094700ea009a9ff37c3506a8d1e9ec348a4cbe6c62fba22ff4587e0bea2fc7b8e9714dff7b7f99468e2ce4a24
7
+ data.tar.gz: 6d3fb76d08ef634a12108f74643e86f58e88b601b493e07f7ce72b2ef029a1fcb6562b8ffc5c162af223aa6f693fb49ca7523d1261c951defd923ba821b9490d
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ notes.txt
16
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in test_launcher.gemspec
4
+ gemspec
5
+
6
+ gem "minitest"
7
+ gem "mocha"
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Pete Kinnecom
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,31 @@
1
+ # TestLauncher
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'test_launcher'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install test_launcher
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/test_launcher/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "thor"
4
+ require "test_launcher/searchers/git_searcher"
5
+ require "test_launcher/tests/minitest/finder"
6
+ require "test_launcher/tests/minitest/consolidator"
7
+ require "test_launcher/shell/runner"
8
+
9
+ class CLI < Thor
10
+
11
+ desc "find", <<-DESC
12
+ Find tests and run them. By trying to match an individual test or the name of a test file(s).
13
+ DESC
14
+ option :all, type: :boolean, desc: %{Run all tests found!}, default: false
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)
@@ -0,0 +1 @@
1
+ puts "`test_runner` no longer exists. Please use `test_launcher` instead (update any aliases you may have)"
@@ -0,0 +1,4 @@
1
+ require "test_launcher/version"
2
+
3
+ module TestLauncher
4
+ end
@@ -0,0 +1,38 @@
1
+ module TestLauncher
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 TestLauncher
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_launcher/shell/color"
2
+ require "test_launcher/utils/path"
3
+
4
+ module TestLauncher
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,85 @@
1
+ require "test_launcher/utils/path"
2
+
3
+ require "test_launcher/tests/minitest/wrappers/single_test"
4
+ require "test_launcher/tests/minitest/wrappers/single_file"
5
+ require "test_launcher/tests/minitest/wrappers/multiple_files"
6
+ require "test_launcher/utils/pluralize"
7
+
8
+ module TestLauncher
9
+ module Tests
10
+ module Minitest
11
+ class Consolidator < Struct.new(:search_results, :shell, :run_all)
12
+ include Utils::Pluralize
13
+
14
+ def self.consolidate(*args)
15
+ new(*args).consolidate
16
+ end
17
+
18
+ def consolidate
19
+ if search_results.empty?
20
+ shell.warn "Could not find any tests."
21
+ exit
22
+ end
23
+
24
+ if methods_found? && one_result?
25
+ shell.notify "Found #{methods_count_phrase} in #{file_count_phrase}."
26
+ Wrappers::SingleTest.new(search_results.first)
27
+ elsif methods_found? && same_file?
28
+ shell.notify "Multiple test methods match in 1 file."
29
+ Wrappers::SingleFile.new(search_results.first[:file])
30
+ elsif methods_found? && run_last_edited?
31
+ shell.notify "Found #{methods_count_phrase} in #{file_count_phrase}."
32
+ shell.notify "Running most recently edited. Run with '--all' to run all the tests."
33
+ Wrappers::SingleTest.new(last_edited)
34
+ elsif files_found? && same_file?
35
+ shell.notify "Found #{file_count_phrase}."
36
+ Wrappers::SingleFile.new(search_results.first[:file])
37
+ elsif files_found? && run_last_edited?
38
+ shell.notify "Found #{file_count_phrase}."
39
+ shell.notify "Running most recently edited. Run with '--all' to run all the tests."
40
+ Wrappers::SingleFile.new(last_edited[:file])
41
+ else
42
+ shell.notify "Found #{file_count_phrase}."
43
+ Wrappers::MultipleFiles.wrap(search_results.map {|r| r[:file] }, shell)
44
+ end
45
+ end
46
+
47
+ def same_file?
48
+ file_count == 1
49
+ end
50
+
51
+ def one_result?
52
+ same_file? && search_results.first[:line]
53
+ end
54
+
55
+ def methods_found?
56
+ !! search_results.first[:line]
57
+ end
58
+
59
+ def files_found?
60
+ ! methods_found?
61
+ end
62
+
63
+ def run_last_edited?
64
+ ! run_all
65
+ end
66
+
67
+ def last_edited
68
+ search_results.sort_by {|r| File.mtime(r[:file])}.last
69
+ end
70
+
71
+ def file_count
72
+ search_results.group_by {|f| f[:file]}.size
73
+ end
74
+
75
+ def methods_count_phrase
76
+ pluralize(search_results.size, "test method")
77
+ end
78
+
79
+ def file_count_phrase
80
+ pluralize(file_count, "file")
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,50 @@
1
+ require "test_launcher/searchers/git_searcher"
2
+
3
+ module TestLauncher
4
+ module Tests
5
+ module Minitest
6
+ class Finder < Struct.new(:query, :searcher)
7
+
8
+ def self.find(query, searcher)
9
+ new(query, searcher).find
10
+ end
11
+
12
+ def find
13
+ return tests_found_by_absolute_path if query.match(/^\//)
14
+
15
+ return tests_found_by_name unless tests_found_by_name.empty?
16
+
17
+ return tests_found_by_file_name unless tests_found_by_file_name.empty?
18
+
19
+ return tests_found_by_full_regex unless tests_found_by_full_regex.empty?
20
+
21
+ []
22
+ end
23
+
24
+ private
25
+
26
+ def tests_found_by_absolute_path
27
+ relative_file_path = query.sub(Dir.pwd, '').sub(/^\//, '')
28
+ [ {file: relative_file_path} ]
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_launcher/tests/minitest/wrappers/single_root"
2
+ require "test_launcher/tests/minitest/wrappers/multiple_roots"
3
+
4
+ module TestLauncher
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,23 @@
1
+ require "test_launcher/utils/path"
2
+
3
+ module TestLauncher
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
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,29 @@
1
+ require "test_launcher/utils/path"
2
+
3
+ module TestLauncher
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
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ require "test_launcher/utils/path"
2
+
3
+ module TestLauncher
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 to_command
17
+ %{cd #{app_root} && ruby -I test -e 'ARGV.each { |file| require(Dir.pwd + "/" + file) }' #{files.map(&:relative_test_path).join(" ")}}
18
+ end
19
+
20
+ def app_root
21
+ files.first.app_root
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,37 @@
1
+ require "test_launcher/utils/path"
2
+
3
+ module TestLauncher
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
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,32 @@
1
+ require "pathname"
2
+
3
+ module TestLauncher
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
@@ -0,0 +1,14 @@
1
+ module TestLauncher
2
+ module Utils
3
+ module Pluralize
4
+ def pluralize(count, singular)
5
+ phrase = "#{count} #{singular}"
6
+ if count == 1
7
+ phrase
8
+ else
9
+ "#{phrase}s"
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module TestLauncher
2
+ VERSION = "0.0.3"
3
+ end
@@ -0,0 +1,45 @@
1
+ $LOAD_PATH.unshift(File.join(File.split(File.dirname(__FILE__))[0], 'lib'))
2
+ require "minitest/autorun"
3
+ require "mocha/mini_test"
4
+
5
+ class TestCase < Minitest::Test
6
+ class DummyShell
7
+
8
+ def method_missing(method, *args)
9
+ instance_variable_set(:"@#{method}", [args])
10
+
11
+ self.class.send(:define_method, method) do |*a|
12
+ if ! instance_variable_get(:"@#{method}")
13
+ instance_variable_set(:"@#{method}", [a])
14
+ end
15
+ end
16
+ end
17
+
18
+ def recall(method)
19
+ instance_variable_get(:"@#{method}")
20
+ end
21
+ end
22
+
23
+ def assert_notified(string)
24
+ unless dummy_shell.recall(:notify).flatten.include?(string)
25
+ flunk <<-FLUNK
26
+ could not find: "#{string}"
27
+ shell.notify called with:
28
+ #{dummy_shell.recall(:notify)}
29
+ FLUNK
30
+ end
31
+ end
32
+
33
+ def assert_paragraphs_equal(expected, actual)
34
+ expecteds = expected.split("\n").map {|l| l.to_s.strip}
35
+ actuals = actual.split("\n").map {|l| l.to_s.strip}
36
+
37
+ assert_equal expecteds, actuals
38
+ end
39
+
40
+ private
41
+
42
+ def dummy_shell
43
+ @dummy_shell ||= DummyShell.new
44
+ end
45
+ end
@@ -0,0 +1,50 @@
1
+ require "test_helper"
2
+ require "test_launcher/searchers/git_searcher"
3
+
4
+ module TestLauncher
5
+ module Searchers
6
+ class MockShell
7
+ def run(cmd)
8
+ if cmd == "git ls-files '*file_pattern*'"
9
+ [
10
+ "file/path/one.rb",
11
+ "another_file/path/two.rb",
12
+ ]
13
+ elsif cmd == "git grep --untracked 'regex' -- 'file_pattern'"
14
+ [
15
+ "file/path/one.rb: some_lines(of_code)",
16
+ "another_file/path/two.rb: Class::Thing::Stuff.new",
17
+ ]
18
+ else
19
+ raise ArgumentError.new("unmocked command")
20
+ end
21
+ end
22
+ end
23
+
24
+ class GitSearcherTest < TestCase
25
+
26
+ def test_find_files
27
+ searcher = GitSearcher.new(MockShell.new)
28
+
29
+ assert_equal ["file/path/one.rb", "another_file/path/two.rb"], searcher.find_files("file_pattern")
30
+ end
31
+
32
+ def test_grep
33
+ searcher = GitSearcher.new(MockShell.new)
34
+
35
+ expected = [
36
+ {
37
+ file: "file/path/one.rb",
38
+ line: "some_lines(of_code)",
39
+ },
40
+ {
41
+ file: "another_file/path/two.rb",
42
+ line: "Class::Thing::Stuff.new",
43
+ }
44
+ ]
45
+
46
+ assert_equal expected, searcher.grep("regex", file_pattern: "file_pattern")
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,191 @@
1
+ require "test_helper"
2
+ require "test_launcher/tests/minitest/consolidator"
3
+
4
+ module TestLauncher
5
+ module Tests
6
+ module Minitest
7
+ class ConsolidatorIntegrationTest < TestCase
8
+
9
+ def test_single_test_method__no_sub_dir
10
+ search_results = [
11
+ {
12
+ file: "test/dir/file_test.rb",
13
+ line: "def test_launcher",
14
+ },
15
+ ]
16
+
17
+ consolidator = Consolidator.new(search_results, dummy_shell, false)
18
+ assert_equal "cd . && ruby -I test test/dir/file_test.rb --name=/test_launcher/", consolidator.consolidate.to_command
19
+ assert_notified "Found 1 test method in 1 file."
20
+ end
21
+
22
+ def test_single_test_method__with_sub_dir
23
+ search_results = [
24
+ {
25
+ file: "engines/lawnmower/test/dir/file_test.rb",
26
+ line: "def test_launcher",
27
+ }
28
+ ]
29
+
30
+ consolidator = Consolidator.new(search_results, dummy_shell, false)
31
+ assert_equal "cd ./engines/lawnmower && ruby -I test test/dir/file_test.rb --name=/test_launcher/", consolidator.consolidate.to_command
32
+ assert_notified "Found 1 test method in 1 file."
33
+ end
34
+
35
+ def test_multiple_test_methods_in_same_file
36
+ search_results = [
37
+ {
38
+ file: "test/dir/file_test.rb",
39
+ line: "def test_launcher",
40
+ },
41
+ {
42
+ file: "test/dir/file_test.rb",
43
+ line: "def test_launcher_again",
44
+ },
45
+ {
46
+ file: "test/dir/file_test.rb",
47
+ line: "def test_launcher_some_more",
48
+ },
49
+ ]
50
+
51
+ consolidator = Consolidator.new(search_results, dummy_shell, false)
52
+
53
+ assert_equal "cd . && ruby -I test test/dir/file_test.rb --name=/test_launcher/", consolidator.consolidate.to_command
54
+ assert_notified "Found 3 test methods in 1 file."
55
+ end
56
+
57
+ def test_multiple_test_methods_in_different_files__last_edited
58
+ search_results = [
59
+ {
60
+ file: "test/dir/file_test.rb",
61
+ line: "def test_launcher",
62
+ },
63
+ {
64
+ file: "test/other_dir/different_test.rb",
65
+ line: "def test_launcher",
66
+ },
67
+ ]
68
+
69
+ consolidator = Consolidator.new(search_results, dummy_shell, false)
70
+
71
+ File.expects(:mtime).with("test/dir/file_test.rb").returns(Time.new(2014, 01, 01))
72
+ File.expects(:mtime).with("test/other_dir/different_test.rb").returns(Time.new(2013, 01, 01))
73
+
74
+ assert_equal "cd . && ruby -I test test/dir/file_test.rb --name=/test_launcher/", consolidator.consolidate.to_command
75
+ assert_notified "Found 2 test methods in 2 files."
76
+ end
77
+
78
+ def test_multiple_test_methods_in_different_files__run_all__same_root
79
+ search_results = [
80
+ {
81
+ file: "test/dir/file_test.rb",
82
+ line: "def test_launcher",
83
+ },
84
+ {
85
+ file: "test/other_dir/different_test.rb",
86
+ line: "def test_launcher",
87
+ },
88
+ ]
89
+
90
+ consolidator = Consolidator.new(search_results, dummy_shell, true)
91
+
92
+ assert_equal %{cd . && ruby -I test -e 'ARGV.each { |file| require(Dir.pwd + "/" + file) }' test/dir/file_test.rb test/other_dir/different_test.rb}, consolidator.consolidate.to_command
93
+ assert_notified "Found 2 files."
94
+ end
95
+
96
+ def test_multiple_test_methods_in_different_files__run_all__different_roots
97
+ search_results = [
98
+ {
99
+ file: "engine1/test/dir/file_test.rb",
100
+ line: "def test_launcher",
101
+ },
102
+ {
103
+ file: "engine2/root2/test/other_dir/different_test.rb",
104
+ line: "def test_launcher",
105
+ },
106
+ ]
107
+
108
+ consolidator = Consolidator.new(search_results, dummy_shell, true)
109
+ expected = <<-SHELL
110
+ cd ./engine1 && ruby -I test -e 'ARGV.each { |file| require(Dir.pwd + \"/\" + file) }' test/dir/file_test.rb; cd -;
111
+
112
+ cd ./engine2/root2 && ruby -I test -e 'ARGV.each { |file| require(Dir.pwd + \"/\" + file) }' test/other_dir/different_test.rb
113
+ SHELL
114
+
115
+ assert_paragraphs_equal expected, consolidator.consolidate.to_command
116
+ assert_notified "Found 2 files."
117
+ end
118
+
119
+ def test_one_file_found
120
+ search_results = [
121
+ {
122
+ file: "engine1/test/dir/file_test.rb",
123
+ },
124
+ ]
125
+
126
+ consolidator = Consolidator.new(search_results, dummy_shell, true)
127
+
128
+ assert_equal "cd ./engine1 && ruby -I test test/dir/file_test.rb", consolidator.consolidate.to_command
129
+ assert_notified "Found 1 file."
130
+ end
131
+
132
+ def test_multiple_files__last_edited
133
+ search_results = [
134
+ {
135
+ file: "test/dir/file_test.rb",
136
+ },
137
+ {
138
+ file: "test/other_dir/different_test.rb",
139
+ },
140
+ ]
141
+
142
+ consolidator = Consolidator.new(search_results, dummy_shell, false)
143
+
144
+ File.expects(:mtime).with("test/dir/file_test.rb").returns(Time.new(2014, 01, 01))
145
+ File.expects(:mtime).with("test/other_dir/different_test.rb").returns(Time.new(2013, 01, 01))
146
+
147
+ assert_equal "cd . && ruby -I test test/dir/file_test.rb", consolidator.consolidate.to_command
148
+ assert_notified "Found 2 files."
149
+ end
150
+
151
+ def test_multiple_files__run_all__same_root
152
+ search_results = [
153
+ {
154
+ file: "engine1/test/dir/file_test.rb",
155
+ },
156
+ {
157
+ file: "engine1/test/other_dir/different_test.rb",
158
+ },
159
+ ]
160
+
161
+ consolidator = Consolidator.new(search_results, dummy_shell, true)
162
+ expected = %{cd ./engine1 && ruby -I test -e 'ARGV.each { |file| require(Dir.pwd + \"/\" + file) }' test/dir/file_test.rb test/other_dir/different_test.rb}
163
+
164
+ assert_equal expected, consolidator.consolidate.to_command
165
+ assert_notified "Found 2 files."
166
+ end
167
+
168
+ def test_multiple_files__run_all__different_roots
169
+ search_results = [
170
+ {
171
+ file: "engine1/test/dir/file_test.rb",
172
+ },
173
+ {
174
+ file: "engine2/root2/test/other_dir/different_test.rb",
175
+ },
176
+ ]
177
+
178
+ consolidator = Consolidator.new(search_results, dummy_shell, true)
179
+ expected = <<-SHELL
180
+ cd ./engine1 && ruby -I test -e 'ARGV.each { |file| require(Dir.pwd + \"/\" + file) }' test/dir/file_test.rb; cd -;
181
+
182
+ cd ./engine2/root2 && ruby -I test -e 'ARGV.each { |file| require(Dir.pwd + \"/\" + file) }' test/other_dir/different_test.rb
183
+ SHELL
184
+
185
+ assert_paragraphs_equal expected, consolidator.consolidate.to_command
186
+ assert_notified "Found 2 files."
187
+ end
188
+ end
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,71 @@
1
+ require "test_helper"
2
+ require "test_launcher/tests/minitest/finder"
3
+
4
+ module TestLauncher
5
+ module Tests
6
+ module Minitest
7
+ class FinderTest < TestCase
8
+
9
+ def test_find__absolute_path
10
+ Dir.expects(:pwd).returns("/absolute/path/root")
11
+ results = Finder.find("/absolute/path/root/test/dir/file_test.rb", "searcher_stub")
12
+ assert_equal [{file: "test/dir/file_test.rb"}], results
13
+ end
14
+
15
+ def test_find__found_by_name
16
+ expected = [{file: "test/file.rb", line: "def test_name"}]
17
+ searcher_mock = mock do
18
+ stubs(:grep).with("^\s*def .*test_name.*", file_pattern: "*_test.rb").returns(expected)
19
+ end
20
+
21
+ assert_equal expected, Finder.find("test_name", searcher_mock)
22
+ end
23
+
24
+ def test_find__found_by_file_name
25
+ searcher_mock = mock do
26
+ stubs(:grep).returns([])
27
+ stubs(:find_files).with("file_query").returns([
28
+ "dir/test/non_test_file_query.rb",
29
+ "dir/thing/file_query_test.rb",
30
+ "other_dir/other_thing/other_file_query_test.rb",
31
+ ])
32
+ end
33
+
34
+ expected = [
35
+ { file: "dir/thing/file_query_test.rb" },
36
+ { file: "other_dir/other_thing/other_file_query_test.rb" },
37
+ ]
38
+
39
+ assert_equal expected, Finder.find("file_query", searcher_mock)
40
+ end
41
+
42
+ def test_find__found_by_full_regex
43
+ searcher_mock = mock do
44
+ stubs(:grep).returns([])
45
+ stubs(:find_files).returns([])
46
+
47
+ stubs(:grep).with("full_regex_search", file_pattern: "*_test.rb").returns([
48
+ { file: "path/to/file_test.rb", line: "random_match"},
49
+ { file: "path/to/other_file_test.rb", line: "random_match_2"}
50
+ ])
51
+ end
52
+
53
+ expected = [
54
+ {file: "path/to/file_test.rb"},
55
+ {file: "path/to/other_file_test.rb"}
56
+ ]
57
+ assert_equal expected, Finder.find("full_regex_search", searcher_mock)
58
+ end
59
+
60
+ def test_find__nothing_found
61
+ searcher_mock = mock do
62
+ stubs(:grep).returns([])
63
+ stubs(:find_files).returns([])
64
+ end
65
+
66
+ assert_equal [], Finder.find("query", searcher_mock)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'test_launcher/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "test_launcher"
8
+ spec.version = TestLauncher::VERSION
9
+ spec.authors = ["Pete Kinnecom"]
10
+ spec.email = ["pete.kinnecom@appfolio.com"]
11
+ spec.summary = %q{Easily run tests}
12
+ spec.description = %q{no really}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: test_launcher
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Pete Kinnecom
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: no really
42
+ email:
43
+ - pete.kinnecom@appfolio.com
44
+ executables:
45
+ - test_launcher
46
+ - test_runner
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - ".gitignore"
51
+ - Gemfile
52
+ - LICENSE.txt
53
+ - README.md
54
+ - Rakefile
55
+ - bin/test_launcher
56
+ - bin/test_runner
57
+ - lib/test_launcher.rb
58
+ - lib/test_launcher/searchers/git_searcher.rb
59
+ - lib/test_launcher/shell/color.rb
60
+ - lib/test_launcher/shell/runner.rb
61
+ - lib/test_launcher/tests/minitest/consolidator.rb
62
+ - lib/test_launcher/tests/minitest/finder.rb
63
+ - lib/test_launcher/tests/minitest/wrappers/multiple_files.rb
64
+ - lib/test_launcher/tests/minitest/wrappers/multiple_roots.rb
65
+ - lib/test_launcher/tests/minitest/wrappers/single_file.rb
66
+ - lib/test_launcher/tests/minitest/wrappers/single_root.rb
67
+ - lib/test_launcher/tests/minitest/wrappers/single_test.rb
68
+ - lib/test_launcher/utils/path.rb
69
+ - lib/test_launcher/utils/pluralize.rb
70
+ - lib/test_launcher/version.rb
71
+ - test/test_helper.rb
72
+ - test/test_launcher/searchers/git_searcher_test.rb
73
+ - test/test_launcher/tests/minitest/consolidator_integration_test.rb
74
+ - test/test_launcher/tests/minitest/finder_test.rb
75
+ - test_launcher.gemspec
76
+ homepage: ''
77
+ licenses:
78
+ - MIT
79
+ metadata: {}
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project:
96
+ rubygems_version: 2.4.3
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: Easily run tests
100
+ test_files:
101
+ - test/test_helper.rb
102
+ - test/test_launcher/searchers/git_searcher_test.rb
103
+ - test/test_launcher/tests/minitest/consolidator_integration_test.rb
104
+ - test/test_launcher/tests/minitest/finder_test.rb
105
+ has_rdoc: