what_to_run 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []