what_to_run 0.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8627bc44ac70f2e2911589b7a59e1c7bfac33bac
4
+ data.tar.gz: 26b2e777319a8d6ebcac6e7552aa95a23b8ce94d
5
+ SHA512:
6
+ metadata.gz: af570365e27f5a2c07e9debf012e7d2962e8c44849ae3fd10a8308de46b30aff32578d4c9fcef809aaf725d9da2aa36e195e0745aa172d3b875b336ebed3552e
7
+ data.tar.gz: f338f32e7886d66b61f2f816e4176287d2944ba4a7a107e57aad97705f9df3401307837790be6945c9979f82339f46fc4329902b9b4496c97bac3eb6770c8dcc
@@ -0,0 +1,67 @@
1
+ # Regression Test Selection
2
+
3
+ This is a demo repository for regression test selection. You will need Ruby 2.3 to use this (which is currently trunk Ruby).
4
+
5
+ ## Make it go with Minitest
6
+
7
+ To try it with Minitest, do:
8
+
9
+ ```
10
+ $ COLLECTION=1 ruby -I lib spec/whatever_test.rb
11
+ ```
12
+
13
+ This will create the initial coverage information. Then modify `lib/my_thing.rb` so that the diff looks like this:
14
+
15
+ ```patch
16
+ diff --git a/lib/my_thing.rb b/lib/my_thing.rb
17
+ index 806deff..eb057b9 100644
18
+ --- a/lib/my_thing.rb
19
+ +++ b/lib/my_thing.rb
20
+ @@ -4,7 +4,7 @@ class Whatever
21
+ end
22
+
23
+ def bar
24
+ - "bar #{@foo}"
25
+ + raise
26
+ end
27
+
28
+ def baz
29
+ ```
30
+
31
+ Now to predict which tests will fail, do this:
32
+
33
+ ```
34
+ $ ruby what_to_run.rb
35
+ ```
36
+
37
+ ## Make it go with RSpec
38
+
39
+ To try it with RSpec, do:
40
+
41
+ ```
42
+ $ COLLECTION=1 rspec spec/whatever_spec.rb
43
+ ```
44
+
45
+ This will create the initial coverage information. Then modify `lib/my_thing.rb` so that the diff looks like this:
46
+
47
+ ```patch
48
+ diff --git a/lib/my_thing.rb b/lib/my_thing.rb
49
+ index 806deff..eb057b9 100644
50
+ --- a/lib/my_thing.rb
51
+ +++ b/lib/my_thing.rb
52
+ @@ -4,7 +4,7 @@ class Whatever
53
+ end
54
+
55
+ def bar
56
+ - "bar #{@foo}"
57
+ + raise
58
+ end
59
+
60
+ def baz
61
+ ```
62
+
63
+ Now to predict which tests will fail, do this:
64
+
65
+ ```
66
+ $ ruby what_to_run.rb
67
+ ```
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'what_to_run'
4
+
5
+ puts WhatToRun.predict
@@ -0,0 +1,97 @@
1
+ require 'json'
2
+ require 'shellwords'
3
+ require 'rugged'
4
+ require 'set'
5
+
6
+ module WhatToRun
7
+ extend self
8
+
9
+ def predict
10
+ lines_to_run.inject([]) do |tests, (file, line)|
11
+ cov_map[File.expand_path(file)][line].each do |desc|
12
+ tests += Array(desc)
13
+ end
14
+ tests
15
+ end
16
+ end
17
+
18
+ def lines_to_run
19
+ repo = Rugged::Repository.new '.'
20
+ lines_to_run = Set.new
21
+
22
+ repo.index.diff.each_patch { |patch|
23
+ file = patch.delta.old_file[:path]
24
+
25
+ patch.each_hunk { |hunk|
26
+ hunk.each_line { |line|
27
+ case line.line_origin
28
+ when :addition
29
+ lines_to_run << [file, line.new_lineno]
30
+ when :deletion
31
+ lines_to_run << [file, line.old_lineno]
32
+ when :context
33
+ # do nothing
34
+ end
35
+ }
36
+ }
37
+ }
38
+
39
+ lines_to_run
40
+ end
41
+
42
+ def diff before, after
43
+ after.each_with_object({}) do |(file_name,line_cov), res|
44
+ before_line_cov = before[file_name]
45
+
46
+ # skip arrays that are exactly the same
47
+ next if before_line_cov == line_cov
48
+
49
+ # subtract the old coverage from the new coverage
50
+ cov = line_cov.zip(before_line_cov).map do |line_after, line_before|
51
+ if line_after
52
+ line_after - line_before
53
+ else
54
+ line_after
55
+ end
56
+ end
57
+
58
+ # add the "diffed" coverage to the hash
59
+ res[file_name] = cov
60
+ end
61
+ end
62
+
63
+ def cov_map
64
+ cov_map = Hash.new { |h, file| h[file] = Hash.new { |i, line| i[line] = [] } }
65
+
66
+ File.open('run_log.json') do |f|
67
+ # Read in the coverage info
68
+ JSON.parse(f.read).each do |args|
69
+ if args.length == 4 # for Minitest
70
+ desc = args.first(2).join('#')
71
+ else # for RSpec
72
+ desc = args.first
73
+ end
74
+
75
+ before, after = args.last(2)
76
+
77
+ # calculate the per test coverage
78
+ delta = diff before, after
79
+
80
+ delta.each_pair do |file, lines|
81
+ file_map = cov_map[file]
82
+
83
+ lines.each_with_index do |val, i|
84
+ # skip lines that weren't executed
85
+ next unless val && val > 0
86
+
87
+ # add the test name to the map. Multiple tests can execute the same
88
+ # line, so we need to use an array.
89
+ file_map[i + 1] << desc
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ cov_map
96
+ end
97
+ end
@@ -0,0 +1,25 @@
1
+ require 'coverage'
2
+ require 'json'
3
+
4
+ Coverage.start
5
+
6
+ require 'minitest'
7
+
8
+ class Minitest::Runnable
9
+ LOGS = []
10
+
11
+ Minitest.after_run {
12
+ File.open('run_log.json', 'w') { |f| f.write JSON.dump LOGS }
13
+ }
14
+
15
+ class << self
16
+ alias :old_run_one_method :run_one_method
17
+
18
+ def run_one_method klass, method_name, reporter
19
+ before = Coverage.peek_result
20
+ old_run_one_method klass, method_name, reporter
21
+ after = Coverage.peek_result
22
+ LOGS << [ klass.name, method_name.to_s, before, after ]
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,17 @@
1
+ require 'coverage'
2
+ require 'json'
3
+ require 'rspec'
4
+
5
+ LOGS = []
6
+ Coverage.start
7
+
8
+ RSpec.configuration.after(:suite) {
9
+ File.open('run_log.json', 'w') { |f| f.write JSON.dump LOGS }
10
+ }
11
+
12
+ RSpec.configuration.around(:example) do |example|
13
+ before = Coverage.peek_result
14
+ example.call
15
+ after = Coverage.peek_result
16
+ LOGS << [ example.full_description, before, after ]
17
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: what_to_run
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Aaron Patterson
8
+ - Dyego Costa
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-03-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rugged
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '0.21'
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.21.0
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - "~>"
29
+ - !ruby/object:Gem::Version
30
+ version: '0.21'
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.21.0
34
+ description: Predict which tests are likely to fail after you’ve changed the code
35
+ email: dyego@dyegocosta.com
36
+ executables:
37
+ - what_to_run
38
+ extensions: []
39
+ extra_rdoc_files: []
40
+ files:
41
+ - README.md
42
+ - bin/what_to_run
43
+ - lib/what_to_run.rb
44
+ - lib/what_to_run/minitest.rb
45
+ - lib/what_to_run/rspec.rb
46
+ homepage: https://github.com/DyegoCosta/what_to_run
47
+ licenses:
48
+ - MIT
49
+ metadata: {}
50
+ post_install_message:
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ requirements: []
65
+ rubyforge_project:
66
+ rubygems_version: 2.4.6
67
+ signing_key:
68
+ specification_version: 4
69
+ summary: Regression test selection
70
+ test_files: []