test_diff 0.3.4 → 0.4.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.
- checksums.yaml +5 -13
- data/.gitignore +3 -0
- data/.rspec +1 -0
- data/.rubocop.yml +11 -0
- data/.travis.yml +6 -6
- data/Gemfile +2 -0
- data/README.md +28 -9
- data/Rakefile +1 -1
- data/exe/test_diff +6 -10
- data/lib/test_diff/build_coverage.rb +2 -96
- data/lib/test_diff/build_coverage_diff.rb +5 -94
- data/lib/test_diff/config.rb +17 -0
- data/lib/test_diff/coverage_runner.rb +99 -0
- data/lib/test_diff/logging.rb +15 -0
- data/lib/test_diff/runable_tests.rb +1 -1
- data/lib/test_diff/storage.rb +1 -1
- data/lib/test_diff/timing_tracker.rb +65 -0
- data/lib/test_diff/track_build.rb +4 -2
- data/lib/test_diff/version.rb +1 -1
- data/lib/test_diff/version_control/git.rb +13 -3
- data/lib/test_diff.rb +3 -0
- data/test_diff.gemspec +2 -3
- metadata +23 -47
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
YzQ3MDBiZjU0MmJmYjJjZTEzN2Y2ZmM5MTZkMmE3NWVkYzlkYjVlMQ==
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b2845ea1c63b2789b148f21d7fb8e5875a3f4d5edab7102e75c092bb702c2ea4
|
4
|
+
data.tar.gz: 93108298f071e199b09d691984b2f32b95c4192a223110a5bd5d653c2f53c6dd
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
YmJlNTgwOTljOTg2ZjBkNjY3MDE3M2Y2NGVkZjk2YTg3ZjQ0ZTFhNTA5YjUy
|
11
|
-
MGJiYzJmYTlmNTdlZWE4ZjJmZmIwOWM1ZjQ4NGU4YTc2MTZhMzI=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
ZWY3NjBjMDBmNzMxZmFkYzk2ZTM3NDE0YTU2MTMyNjE2MGQ4MTJhMmY3ODNm
|
14
|
-
NDY2OTc5YjA1Yzg0NTA3OTQwZDYyMzk2OTJmMmMxNTM4YjdhMDQ3NzkwOWZm
|
15
|
-
ODkyY2FlY2U0YWQwM2ZlNDMwZDMxYTZlMzk3NjUyMWU2ZDcyMWE=
|
6
|
+
metadata.gz: eb42e85e6ae5d834de54d7e046b188947941d8faf5713dff13054704da6afe96b7c17644ec47bacc1cea31b4c6a67f695baa276c59f4cce4f015a9e4f59ca81d
|
7
|
+
data.tar.gz: ef2ca1b3e0e04edf546d995844a0ac9ecfb61f741651f063e6d1e7e0cb568637a0ee1b7b2abe84a6404af3ac0c4722d626658a3489b91fc7b53c6683e83953a1
|
data/.gitignore
CHANGED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,36 +1,55 @@
|
|
1
1
|
# TestDiff
|
2
2
|
[](https://travis-ci.org/grantspeelman/test_diff)
|
3
3
|
|
4
|
-
Gem that attempts to find the tests that are required to run for the changes you have made
|
4
|
+
Gem that attempts to find the tests that are required to run for the changes you have made.
|
5
|
+
|
6
|
+
## Project requirements
|
7
|
+
|
8
|
+
* RSpec 2+
|
9
|
+
* project tracked with git
|
5
10
|
|
6
11
|
## Installation
|
7
12
|
|
8
13
|
Add this line to your application's Gemfile:
|
9
14
|
|
10
15
|
```ruby
|
11
|
-
gem 'test_diff'
|
16
|
+
gem 'test_diff', group: :test
|
12
17
|
```
|
13
18
|
|
14
19
|
And then execute:
|
15
20
|
|
16
21
|
$ bundle
|
17
22
|
|
18
|
-
|
23
|
+
## Rails Setup
|
24
|
+
|
25
|
+
Suggest to disabled `eager_load` in `config/environments/test.rb` based on `ENV['TEST_DIFF_COVERAGE']`
|
26
|
+
EG:
|
19
27
|
|
20
|
-
|
28
|
+
```ruby
|
29
|
+
config.eager_load = ENV['TEST_DIFF_COVERAGE'].blank?
|
30
|
+
```
|
31
|
+
|
32
|
+
Also make sure to disable `simple_cov` if you use it when `ENV['TEST_DIFF_COVERAGE']` is set
|
33
|
+
EG:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
unless ENV['TEST_DIFF_COVERAGE']
|
37
|
+
require 'simplecov'
|
38
|
+
SimpleCov.start 'rails'
|
39
|
+
end
|
40
|
+
```
|
21
41
|
|
22
42
|
## Usage
|
23
43
|
|
24
44
|
Building the test coverage index
|
25
45
|
|
26
|
-
$
|
27
|
-
$
|
28
|
-
$ git add test_diff_coverage
|
29
|
-
$ git commit
|
46
|
+
$ test_diff build_coverage spec spec/spec_helper.rb
|
47
|
+
$ # part here to upload test_diff_coverage to a shared space, ie aws
|
30
48
|
|
31
49
|
Running a test difference
|
32
50
|
|
33
|
-
$
|
51
|
+
$ # part here to download test_diff_coverage from shared space, ie aws
|
52
|
+
$ test_diff rspec
|
34
53
|
|
35
54
|
## Development
|
36
55
|
|
data/Rakefile
CHANGED
data/exe/test_diff
CHANGED
@@ -9,27 +9,23 @@ class TestDiffBuilder < Thor
|
|
9
9
|
desc 'build_coverage spec', 'runs the specs and generates reverse_coverage'
|
10
10
|
def build_coverage(spec_folder = 'spec', pre_load = nil, continue = nil)
|
11
11
|
TestDiff::BuildCoverage.new(spec_folder, pre_load, continue).run
|
12
|
+
track_build
|
12
13
|
end
|
13
14
|
|
14
15
|
desc 'track build', 'track this HEAD as the last test diff index'
|
15
|
-
def track_build(sha1 = nil)
|
16
|
-
TestDiff::TrackBuild.new(sha1).run
|
16
|
+
def track_build(git_dir = nil, sha1 = nil)
|
17
|
+
TestDiff::TrackBuild.new(sha1, git_dir).run
|
17
18
|
end
|
18
19
|
|
19
|
-
desc '
|
20
|
-
def
|
21
|
-
TestDiff::Config.test_runner = TestDiff::TestRunner::Spec.new
|
22
|
-
TestDiff::RunDiff.new(spec_folder, groups_of, group).run
|
23
|
-
end
|
24
|
-
|
25
|
-
desc 'run_rspec_diff spec', 'runs the specs difference between the branches'
|
26
|
-
def run_rspec_diff(spec_folder = 'spec', groups_of = nil, group = '0')
|
20
|
+
desc 'rspec', 'runs the specs difference between the branches'
|
21
|
+
def rspec(spec_folder = 'spec', groups_of = nil, group = '0')
|
27
22
|
TestDiff::RunDiff.new(spec_folder, groups_of, group).run
|
28
23
|
end
|
29
24
|
|
30
25
|
desc 'build_coverage_diff spec', 'runs the specs difference between the branches'
|
31
26
|
def build_coverage_diff(spec_folder = 'spec', pre_load = nil, continue = nil)
|
32
27
|
TestDiff::BuildCoverageDiff.new(spec_folder, pre_load, continue).run
|
28
|
+
track_build
|
33
29
|
end
|
34
30
|
end
|
35
31
|
|
@@ -2,110 +2,16 @@
|
|
2
2
|
module TestDiff
|
3
3
|
# class used to build the coverage file
|
4
4
|
class BuildCoverage
|
5
|
-
attr_reader :spec_folder, :pre_load
|
6
|
-
|
7
5
|
def initialize(spec_folder, pre_load, continue)
|
8
6
|
@spec_folder = spec_folder
|
9
7
|
@pre_load = pre_load
|
10
8
|
@batch_queue = Queue.new
|
11
|
-
@storage = Storage.new
|
12
9
|
@continue = continue
|
13
|
-
RunableTests.add_all(spec_folder, @batch_queue, continue)
|
14
10
|
end
|
15
11
|
|
16
12
|
def run
|
17
|
-
|
18
|
-
|
19
|
-
require_pre_load
|
20
|
-
run_batch
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def require_pre_load
|
26
|
-
return unless pre_load
|
27
|
-
puts "pre_loading #{pre_load}"
|
28
|
-
require File.expand_path(pre_load)
|
29
|
-
end
|
30
|
-
|
31
|
-
def run_batch
|
32
|
-
puts "Running #{@batch_queue.size} tests"
|
33
|
-
timing_thread = start_timing_thread(Time.now, @batch_queue.size)
|
34
|
-
start
|
35
|
-
timing_thread.join
|
36
|
-
puts 'Test done, compacting db'
|
37
|
-
@storage.compact if @storage.respond_to?(:compact)
|
38
|
-
end
|
39
|
-
|
40
|
-
def start_timing_thread(start_time, original_size)
|
41
|
-
Thread.new do
|
42
|
-
until @batch_queue.empty?
|
43
|
-
last_size = @batch_queue.size
|
44
|
-
completed = original_size - last_size
|
45
|
-
if completed > 0
|
46
|
-
time_per_spec = (Time.now - start_time).to_f / completed.to_f
|
47
|
-
est_time_left = time_per_spec * last_size
|
48
|
-
puts "specs left #{last_size}, est time_left: #{est_time_left.to_i}"
|
49
|
-
end
|
50
|
-
sleep(60)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def start
|
56
|
-
until @batch_queue.empty?
|
57
|
-
pid = start_process_fork(@batch_queue.pop(true))
|
58
|
-
pid, status = Process.waitpid2(pid)
|
59
|
-
fail 'Test Failed' unless status.success?
|
60
|
-
end
|
61
|
-
Coverage.result # disable coverage
|
62
|
-
end
|
63
|
-
|
64
|
-
def start_process_fork(main_spec_file)
|
65
|
-
Process.fork do
|
66
|
-
puts "running #{main_spec_file}"
|
67
|
-
ActiveRecord::Base.connection.reconnect! if defined?(ActiveRecord::Base)
|
68
|
-
Time.zone_default = (Time.zone = 'UTC') if Time.respond_to?(:zone_default) && Time.zone_default.nil?
|
69
|
-
run_test(main_spec_file)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def run_test(main_spec_file)
|
74
|
-
s = Time.now
|
75
|
-
result = run_tests(main_spec_file)
|
76
|
-
if result
|
77
|
-
save_coverage_data(main_spec_file, Time.now - s)
|
78
|
-
else
|
79
|
-
Coverage.result # disable coverage
|
80
|
-
exit!(false) unless @continue
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def run_tests(main_spec_file)
|
85
|
-
if defined?(::RSpec::Core::Runner)
|
86
|
-
::RSpec::Core::Runner.run([main_spec_file], $stderr, $stdout) == 0
|
87
|
-
else
|
88
|
-
options ||= begin
|
89
|
-
parser = ::Spec::Runner::OptionParser.new($stderr, $stdout)
|
90
|
-
parser.order!(['-b', main_spec_file])
|
91
|
-
parser.options
|
92
|
-
end
|
93
|
-
Spec::Runner.use options
|
94
|
-
options.run_examples
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def save_coverage_data(main_spec_file, execution_time)
|
99
|
-
data = { '__execution_time__' => execution_time }
|
100
|
-
Coverage.result.each do |file_name, stats|
|
101
|
-
relative_file_name = file_name.gsub("#{FileUtils.pwd}/", '')
|
102
|
-
if file_name.include?(FileUtils.pwd)
|
103
|
-
data[relative_file_name] = stats.join(',')
|
104
|
-
end
|
105
|
-
end
|
106
|
-
YAML::ENGINE.yamler = 'psych'
|
107
|
-
@storage.set(main_spec_file, data)
|
108
|
-
@storage.flush if @storage.respond_to?(:flush)
|
13
|
+
RunableTests.add_all(spec_folder, @batch_queue, continue)
|
14
|
+
CoverageRunner.run(@batch_queue, @pre_load, @continue)
|
109
15
|
end
|
110
16
|
end
|
111
17
|
end
|
@@ -2,108 +2,19 @@
|
|
2
2
|
module TestDiff
|
3
3
|
# class used to build the coverage file
|
4
4
|
class BuildCoverageDiff
|
5
|
-
attr_reader :spec_folder, :pre_load, :sha1
|
6
|
-
|
7
5
|
def initialize(spec_folder, pre_load, continue)
|
8
6
|
@spec_folder = spec_folder
|
9
7
|
@sha1 = File.read('test_diff_coverage/sha')
|
10
|
-
@tests_to_run = []
|
11
|
-
@storage = Storage.new
|
12
8
|
@pre_load = pre_load
|
13
9
|
@continue = continue
|
14
10
|
end
|
15
11
|
|
16
12
|
def run
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
require_pre_load
|
23
|
-
run_batch
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def require_pre_load
|
29
|
-
return unless pre_load
|
30
|
-
puts "pre_loading #{pre_load}"
|
31
|
-
require File.expand_path(pre_load)
|
32
|
-
end
|
33
|
-
|
34
|
-
def run_batch
|
35
|
-
puts "Running #{@tests_to_run.size} tests"
|
36
|
-
start
|
37
|
-
puts 'Test done, compacting db'
|
38
|
-
@storage.compact if @storage.respond_to?(:compact)
|
39
|
-
end
|
40
|
-
|
41
|
-
def start
|
42
|
-
until @tests_to_run.empty?
|
43
|
-
pid = start_process_fork(@tests_to_run.pop.filename)
|
44
|
-
pid, status = Process.waitpid2(pid)
|
45
|
-
fail 'Test Failed' unless status.success?
|
46
|
-
end
|
47
|
-
Coverage.result # disable coverage
|
48
|
-
end
|
49
|
-
|
50
|
-
def start_process_fork(main_spec_file)
|
51
|
-
Process.fork do
|
52
|
-
puts "running #{main_spec_file}"
|
53
|
-
ActiveRecord::Base.connection.reconnect! if defined?(ActiveRecord::Base)
|
54
|
-
Time.zone_default = (Time.zone = 'UTC') if Time.respond_to?(:zone_default) && Time.zone_default.nil?
|
55
|
-
run_test(main_spec_file)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def run_test(main_spec_file)
|
60
|
-
s = Time.now
|
61
|
-
result = run_tests(main_spec_file)
|
62
|
-
if result
|
63
|
-
save_coverage_data(main_spec_file, Time.now - s)
|
64
|
-
else
|
65
|
-
Coverage.result # disable coverage
|
66
|
-
exit!(false) unless @continue
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def run_tests(main_spec_file)
|
71
|
-
if defined?(::RSpec::Core::Runner)
|
72
|
-
::RSpec::Core::Runner.run([main_spec_file], $stderr, $stdout) == 0
|
73
|
-
else
|
74
|
-
options ||= begin
|
75
|
-
parser = ::Spec::Runner::OptionParser.new($stderr, $stdout)
|
76
|
-
parser.order!(['-b', main_spec_file])
|
77
|
-
parser.options
|
78
|
-
end
|
79
|
-
Spec::Runner.use options
|
80
|
-
options.run_examples
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def save_coverage_data(main_spec_file, execution_time)
|
85
|
-
data = { '__execution_time__' => execution_time }
|
86
|
-
Coverage.result.each do |file_name, stats|
|
87
|
-
relative_file_name = file_name.gsub("#{FileUtils.pwd}/", '')
|
88
|
-
if file_name.include?(FileUtils.pwd)
|
89
|
-
data[relative_file_name] = stats.join(',')
|
90
|
-
end
|
91
|
-
end
|
92
|
-
YAML::ENGINE.yamler = 'psych'
|
93
|
-
@storage.set(main_spec_file, data)
|
94
|
-
@storage.flush if @storage.respond_to?(:flush)
|
95
|
-
end
|
96
|
-
|
97
|
-
def remove_tests_that_do_not_exist
|
98
|
-
@tests_to_run.delete_if do |s|
|
99
|
-
!File.exist?("#{Config.working_directory}/#{s.filename}")
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def remove_tests_in_wrong_folder
|
104
|
-
@tests_to_run.delete_if do |s|
|
105
|
-
!s.filename.start_with?("#{spec_folder}/")
|
106
|
-
end
|
13
|
+
info_files = []
|
14
|
+
RunableTests.new(info_files, @spec_folder).add_changed_files
|
15
|
+
batch_queue = Queue.new
|
16
|
+
info_files.each { |info_file| batch_queue << info_file.filename }
|
17
|
+
CoverageRunner.run(batch_queue, @pre_load, @continue)
|
107
18
|
end
|
108
19
|
end
|
109
20
|
end
|
data/lib/test_diff/config.rb
CHANGED
@@ -10,10 +10,18 @@ module TestDiff
|
|
10
10
|
attr_writer :test_runner, :version_control, :storage
|
11
11
|
|
12
12
|
def initialize
|
13
|
+
reset
|
14
|
+
end
|
15
|
+
|
16
|
+
def reset
|
13
17
|
self.working_directory = '.'
|
14
18
|
self.map_subfolder = 'test_diff_coverage'
|
15
19
|
self.current_tracking_filename = 'sha'
|
16
20
|
self.test_pattern = /spec.rb\z/
|
21
|
+
@version_control = nil
|
22
|
+
@storage = nil
|
23
|
+
@test_runner = nil
|
24
|
+
@logger = nil
|
17
25
|
end
|
18
26
|
|
19
27
|
def version_control
|
@@ -29,6 +37,11 @@ module TestDiff
|
|
29
37
|
@test_runner ||= TestRunner::Rspec.new
|
30
38
|
end
|
31
39
|
|
40
|
+
def logger
|
41
|
+
require 'logger'
|
42
|
+
@logger ||= Logger.new($stdout)
|
43
|
+
end
|
44
|
+
|
32
45
|
def map_folder
|
33
46
|
"#{working_directory}/#{map_subfolder}"
|
34
47
|
end
|
@@ -44,5 +57,9 @@ module TestDiff
|
|
44
57
|
super
|
45
58
|
end
|
46
59
|
end
|
60
|
+
|
61
|
+
def self.respond_to_missing?(method, *args)
|
62
|
+
super && instance.respond_to?(method)
|
63
|
+
end
|
47
64
|
end
|
48
65
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module TestDiff
|
2
|
+
# runs each spec and saves it to storage
|
3
|
+
class CoverageRunner
|
4
|
+
def self.run(batch_queue, pre_load, continue)
|
5
|
+
new(batch_queue, pre_load, continue).run
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(batch_queue, pre_load, continue)
|
9
|
+
@pre_load = pre_load
|
10
|
+
@batch_queue = batch_queue
|
11
|
+
@storage = Storage.new
|
12
|
+
@continue = continue
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
require 'coverage.so'
|
17
|
+
Coverage.start
|
18
|
+
|
19
|
+
require_boot
|
20
|
+
require_rspec
|
21
|
+
require_pre_load
|
22
|
+
run_batch
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def require_boot
|
28
|
+
return unless File.exist?('config/boot.rb')
|
29
|
+
puts 'Loading config/boot.rb'
|
30
|
+
require File.expand_path('config/boot.rb')
|
31
|
+
end
|
32
|
+
|
33
|
+
def require_pre_load
|
34
|
+
return unless @pre_load
|
35
|
+
puts "pre_loading #{@pre_load}"
|
36
|
+
$LOAD_PATH << "#{Dir.getwd}/spec"
|
37
|
+
require File.expand_path(@pre_load)
|
38
|
+
end
|
39
|
+
|
40
|
+
def require_rspec
|
41
|
+
puts 'Loading rspec'
|
42
|
+
require 'rspec'
|
43
|
+
end
|
44
|
+
|
45
|
+
def run_batch
|
46
|
+
TimingTracker.run(@batch_queue) { start }
|
47
|
+
puts 'Test done, compacting db'
|
48
|
+
@storage.compact if @storage.respond_to?(:compact)
|
49
|
+
end
|
50
|
+
|
51
|
+
def start
|
52
|
+
until @batch_queue.empty?
|
53
|
+
pid = start_process_fork(@batch_queue.pop(true))
|
54
|
+
_pid, status = Process.waitpid2(pid)
|
55
|
+
raise 'Test Failed' unless status.success?
|
56
|
+
end
|
57
|
+
Coverage.result # disable coverage
|
58
|
+
end
|
59
|
+
|
60
|
+
def start_process_fork(main_spec_file)
|
61
|
+
Process.fork do
|
62
|
+
ENV['TEST_DIFF_COVERAGE'] = 'yes'
|
63
|
+
puts "running #{main_spec_file}"
|
64
|
+
ActiveRecord::Base.connection.reconnect! if defined?(ActiveRecord::Base)
|
65
|
+
Time.zone_default = (Time.zone = 'UTC') if Time.respond_to?(:zone_default) && Time.zone_default.nil?
|
66
|
+
run_test(main_spec_file)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def run_test(main_spec_file)
|
71
|
+
s = Time.now
|
72
|
+
result = run_tests(main_spec_file)
|
73
|
+
if result
|
74
|
+
save_coverage_data(main_spec_file, Time.now - s)
|
75
|
+
else
|
76
|
+
$stderr.puts(@last_output.to_s)
|
77
|
+
Coverage.result # disable coverage
|
78
|
+
exit!(false) unless @continue
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def run_tests(main_spec_file)
|
83
|
+
@last_output = StringIO.new
|
84
|
+
::RSpec::Core::Runner.run([main_spec_file], @last_output, @last_output).zero?
|
85
|
+
end
|
86
|
+
|
87
|
+
def save_coverage_data(main_spec_file, execution_time)
|
88
|
+
data = { '__execution_time__' => execution_time }
|
89
|
+
Coverage.result.each do |file_name, stats|
|
90
|
+
relative_file_name = file_name.gsub("#{FileUtils.pwd}/", '')
|
91
|
+
if file_name.start_with?(FileUtils.pwd)
|
92
|
+
data[relative_file_name] = stats.join(',')
|
93
|
+
end
|
94
|
+
end
|
95
|
+
@storage.set(main_spec_file, data)
|
96
|
+
@storage.flush if @storage.respond_to?(:flush)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# TestDiff module
|
2
|
+
module TestDiff
|
3
|
+
# adds logging to a class
|
4
|
+
module Logging
|
5
|
+
def log_info(*args)
|
6
|
+
Config.logger.info(*args)
|
7
|
+
end
|
8
|
+
|
9
|
+
def log_debug(*args)
|
10
|
+
Config.logger.info(*args)
|
11
|
+
end
|
12
|
+
|
13
|
+
module_function :log_debug, :log_info
|
14
|
+
end
|
15
|
+
end
|
data/lib/test_diff/storage.rb
CHANGED
@@ -10,7 +10,7 @@ module TestDiff
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def set(file, coverage_data)
|
13
|
-
|
13
|
+
raise 'Data must be a Hash' unless coverage_data.is_a?(Hash)
|
14
14
|
get_store(file).transaction do |store|
|
15
15
|
store.roots.each do |key|
|
16
16
|
store.delete(key)
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# TestDiff module
|
2
|
+
module TestDiff
|
3
|
+
# estimates and prints how long it will take to empty a queue
|
4
|
+
class TimingTracker
|
5
|
+
def self.run(queue, &block)
|
6
|
+
new(queue).run(&block)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(queue)
|
10
|
+
@queue = queue
|
11
|
+
@original_size = queue_size
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
@start_time = Time.now
|
16
|
+
thread = start_timing_thread
|
17
|
+
yield
|
18
|
+
thread.kill
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def queue_size
|
24
|
+
@queue.size
|
25
|
+
end
|
26
|
+
|
27
|
+
def queue_completed
|
28
|
+
@original_size - queue_size
|
29
|
+
end
|
30
|
+
|
31
|
+
def seconds_elapsed
|
32
|
+
(Time.now - @start_time).to_f
|
33
|
+
end
|
34
|
+
|
35
|
+
def start_timing_thread
|
36
|
+
Thread.new do
|
37
|
+
begin
|
38
|
+
do_timing
|
39
|
+
rescue => e
|
40
|
+
puts "----- Timing failed: #{e.message} -----"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def do_timing
|
46
|
+
puts "Timing #{@original_size} specs"
|
47
|
+
until queue_empty?
|
48
|
+
current_size = queue_size
|
49
|
+
current_completed = queue_completed
|
50
|
+
if current_completed > 5
|
51
|
+
time_per_spec = seconds_elapsed / current_completed.to_f
|
52
|
+
est_time_left = time_per_spec * current_size
|
53
|
+
puts "specs left #{current_size}, est time_left: #{est_time_left.to_i}"
|
54
|
+
else
|
55
|
+
puts "specs left #{current_size}, est time_left: N/A"
|
56
|
+
end
|
57
|
+
sleep(30)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def queue_empty?
|
62
|
+
@queue.empty?
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -4,14 +4,16 @@ require 'git'
|
|
4
4
|
module TestDiff
|
5
5
|
# Class used to calculate the tests than need to be run
|
6
6
|
class TrackBuild
|
7
|
-
def initialize(sha)
|
7
|
+
def initialize(sha, git_dir)
|
8
|
+
@git_dir = git_dir
|
8
9
|
@sha = sha
|
9
10
|
end
|
10
11
|
|
11
12
|
def run
|
12
|
-
git = Git.open('.')
|
13
|
+
git = Git.open(@git_dir || '.')
|
13
14
|
sha = git.object(@sha || 'HEAD').sha
|
14
15
|
File.open('test_diff_coverage/sha', 'w+') { |f| f << sha }
|
16
|
+
puts 'updated test_diff_coverage/sha'
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
data/lib/test_diff/version.rb
CHANGED
@@ -5,14 +5,24 @@ module TestDiff
|
|
5
5
|
module VersionControl
|
6
6
|
# class to find changed files for git
|
7
7
|
class Git
|
8
|
-
|
9
|
-
|
8
|
+
include Logging
|
9
|
+
|
10
|
+
def initialize(wd, last_tracked, current = 'HEAD', git_lib = ::GIT)
|
11
|
+
@git = git_lib.open(wd)
|
10
12
|
@last_tracked = last_tracked
|
11
13
|
@current = current
|
12
14
|
end
|
13
15
|
|
14
16
|
def changed_files
|
15
|
-
|
17
|
+
diff_changed_files
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def diff_changed_files
|
23
|
+
@git.diff(@last_tracked, @current).map(&:path).tap do |files|
|
24
|
+
log_debug "diff_changed_files: #{files.join(',')}"
|
25
|
+
end
|
16
26
|
end
|
17
27
|
end
|
18
28
|
end
|
data/lib/test_diff.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
require 'test_diff/version'
|
2
2
|
require 'test_diff/storage'
|
3
|
+
require 'test_diff/logging'
|
3
4
|
require 'test_diff/test_info'
|
4
5
|
require 'test_diff/version_control/git'
|
5
6
|
require 'test_diff/test_runner/rspec'
|
6
7
|
require 'test_diff/test_runner/spec'
|
7
8
|
require 'test_diff/config'
|
8
9
|
require 'test_diff/runable_tests'
|
10
|
+
require 'test_diff/timing_tracker'
|
11
|
+
require 'test_diff/coverage_runner'
|
9
12
|
require 'test_diff/build_coverage'
|
10
13
|
require 'test_diff/run_diff'
|
11
14
|
require 'test_diff/build_coverage_diff'
|
data/test_diff.gemspec
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
|
2
3
|
lib = File.expand_path('../lib', __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'test_diff/version'
|
@@ -7,7 +8,7 @@ Gem::Specification.new do |spec|
|
|
7
8
|
spec.name = 'test_diff'
|
8
9
|
spec.version = TestDiff::VERSION
|
9
10
|
spec.authors = ['Grant Speelman']
|
10
|
-
spec.email = ['
|
11
|
+
spec.email = ['grantspeelman@gmail.com']
|
11
12
|
|
12
13
|
spec.summary = 'Gem that attempts to find the tests that are required to run for the changes you have made.'
|
13
14
|
spec.description = 'Gem that attempts to find the tests that are required to run for the changes you have made.'
|
@@ -22,9 +23,7 @@ Gem::Specification.new do |spec|
|
|
22
23
|
spec.add_dependency 'thor'
|
23
24
|
spec.add_dependency 'git'
|
24
25
|
|
25
|
-
spec.add_development_dependency 'rubocop'
|
26
26
|
spec.add_development_dependency 'minitest', '>= 0.8.0'
|
27
|
-
spec.add_development_dependency 'minitest-reporters'
|
28
27
|
spec.add_development_dependency 'bundler', '~> 1.6'
|
29
28
|
spec.add_development_dependency 'rake', '~> 10.0'
|
30
29
|
end
|
metadata
CHANGED
@@ -1,125 +1,98 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: test_diff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Grant Speelman
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: git
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rubocop
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ! '>='
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ! '>='
|
38
|
+
- - ">="
|
53
39
|
- !ruby/object:Gem::Version
|
54
40
|
version: '0'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: minitest
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
58
44
|
requirements:
|
59
|
-
- -
|
45
|
+
- - ">="
|
60
46
|
- !ruby/object:Gem::Version
|
61
47
|
version: 0.8.0
|
62
48
|
type: :development
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
66
|
-
- -
|
52
|
+
- - ">="
|
67
53
|
- !ruby/object:Gem::Version
|
68
54
|
version: 0.8.0
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: minitest-reporters
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ! '>='
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ! '>='
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
55
|
- !ruby/object:Gem::Dependency
|
84
56
|
name: bundler
|
85
57
|
requirement: !ruby/object:Gem::Requirement
|
86
58
|
requirements:
|
87
|
-
- - ~>
|
59
|
+
- - "~>"
|
88
60
|
- !ruby/object:Gem::Version
|
89
61
|
version: '1.6'
|
90
62
|
type: :development
|
91
63
|
prerelease: false
|
92
64
|
version_requirements: !ruby/object:Gem::Requirement
|
93
65
|
requirements:
|
94
|
-
- - ~>
|
66
|
+
- - "~>"
|
95
67
|
- !ruby/object:Gem::Version
|
96
68
|
version: '1.6'
|
97
69
|
- !ruby/object:Gem::Dependency
|
98
70
|
name: rake
|
99
71
|
requirement: !ruby/object:Gem::Requirement
|
100
72
|
requirements:
|
101
|
-
- - ~>
|
73
|
+
- - "~>"
|
102
74
|
- !ruby/object:Gem::Version
|
103
75
|
version: '10.0'
|
104
76
|
type: :development
|
105
77
|
prerelease: false
|
106
78
|
version_requirements: !ruby/object:Gem::Requirement
|
107
79
|
requirements:
|
108
|
-
- - ~>
|
80
|
+
- - "~>"
|
109
81
|
- !ruby/object:Gem::Version
|
110
82
|
version: '10.0'
|
111
83
|
description: Gem that attempts to find the tests that are required to run for the
|
112
84
|
changes you have made.
|
113
85
|
email:
|
114
|
-
-
|
86
|
+
- grantspeelman@gmail.com
|
115
87
|
executables:
|
116
88
|
- test_diff
|
117
89
|
extensions: []
|
118
90
|
extra_rdoc_files: []
|
119
91
|
files:
|
120
|
-
- .gitignore
|
121
|
-
- .
|
122
|
-
- .
|
92
|
+
- ".gitignore"
|
93
|
+
- ".rspec"
|
94
|
+
- ".rubocop.yml"
|
95
|
+
- ".travis.yml"
|
123
96
|
- CODE_OF_CONDUCT.md
|
124
97
|
- Gemfile
|
125
98
|
- LICENSE.txt
|
@@ -132,12 +105,15 @@ files:
|
|
132
105
|
- lib/test_diff/build_coverage.rb
|
133
106
|
- lib/test_diff/build_coverage_diff.rb
|
134
107
|
- lib/test_diff/config.rb
|
108
|
+
- lib/test_diff/coverage_runner.rb
|
109
|
+
- lib/test_diff/logging.rb
|
135
110
|
- lib/test_diff/run_diff.rb
|
136
111
|
- lib/test_diff/runable_tests.rb
|
137
112
|
- lib/test_diff/storage.rb
|
138
113
|
- lib/test_diff/test_info.rb
|
139
114
|
- lib/test_diff/test_runner/rspec.rb
|
140
115
|
- lib/test_diff/test_runner/spec.rb
|
116
|
+
- lib/test_diff/timing_tracker.rb
|
141
117
|
- lib/test_diff/track_build.rb
|
142
118
|
- lib/test_diff/version.rb
|
143
119
|
- lib/test_diff/version_control/git.rb
|
@@ -152,17 +128,17 @@ require_paths:
|
|
152
128
|
- lib
|
153
129
|
required_ruby_version: !ruby/object:Gem::Requirement
|
154
130
|
requirements:
|
155
|
-
- -
|
131
|
+
- - ">="
|
156
132
|
- !ruby/object:Gem::Version
|
157
133
|
version: '0'
|
158
134
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
159
135
|
requirements:
|
160
|
-
- -
|
136
|
+
- - ">="
|
161
137
|
- !ruby/object:Gem::Version
|
162
138
|
version: '0'
|
163
139
|
requirements: []
|
164
140
|
rubyforge_project:
|
165
|
-
rubygems_version: 2.4
|
141
|
+
rubygems_version: 2.7.4
|
166
142
|
signing_key:
|
167
143
|
specification_version: 4
|
168
144
|
summary: Gem that attempts to find the tests that are required to run for the changes
|