miss_cleo 0.3.1 → 0.3.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 +4 -4
- data/bin/miss_cleo +3 -101
- data/lib/miss_cleo/coverage_filter.rb +1 -1
- data/lib/miss_cleo/coverage_map_helper.rb +117 -0
- data/lib/miss_cleo/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f65320c1042c0c225a420c0a71a9bb176146c2ea
|
4
|
+
data.tar.gz: 9bee07706949fbf2529d07eee3407fe2559039a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 16a9d3f6c1820e6f8473a947979950177193afdfc7d195212c6275b532e50e90f75e91ea165820b26cbad6594752cacbff67c4638f211e6490190f6dfad0de0f
|
7
|
+
data.tar.gz: c2b1726859d10f06bc6fdb36a12dab107eba1ad7c4d6347cf22aa15d803188a9ed17ba038f2fd04c7b1303be3bea59b9bb2cabd5cb5f358977e8e2d6d1b9831e
|
data/bin/miss_cleo
CHANGED
@@ -2,112 +2,14 @@
|
|
2
2
|
|
3
3
|
require "miss_cleo"
|
4
4
|
require 'pry'
|
5
|
+
include MissCleo::CoverageMapHelper
|
5
6
|
|
6
7
|
case ARGV.first
|
7
8
|
when "build_deck"
|
8
|
-
|
9
|
-
cov_map = Hash.new { |h, file| h[file] = Hash.new { |i, line| i[line] = [] } }
|
10
|
-
filenames.each do |filename|
|
11
|
-
File.open(filename, "r") do |f|
|
12
|
-
f.read
|
13
|
-
end.tap do |contents|
|
14
|
-
build_coverage_map(cov_map, JSON.parse(contents))
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
File.open("total_coverage_map.json", "w") do |f|
|
19
|
-
f.write(JSON.dump(cov_map))
|
20
|
-
end
|
9
|
+
build_deck(ARGV[1..-1])
|
21
10
|
when "predict"
|
22
|
-
|
23
|
-
lines_changed = Set.new
|
24
|
-
|
25
|
-
repo.index.diff.each_patch do |patch|
|
26
|
-
file = patch.delta.old_file[:path]
|
27
|
-
|
28
|
-
patch.each_hunk do |hunk|
|
29
|
-
hunk.each_line do |line|
|
30
|
-
case line.line_origin
|
31
|
-
when :addition
|
32
|
-
lines_changed << [file, line.new_lineno] unless exclude_from_map?(file)
|
33
|
-
when :deletion
|
34
|
-
lines_changed << [file, line.old_lineno] unless exclude_from_map?(file)
|
35
|
-
when :context
|
36
|
-
# do nothing
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
coverage_map = JSON.parse(File.open("total_coverage_map.json").read)
|
43
|
-
tests_to_run = []
|
44
|
-
lines_changed.each do |file, line|
|
45
|
-
coverage_map && coverage_map[File.expand_path(file)] && coverage_map[File.expand_path(file)].fetch(line.to_s, []).uniq.each do |desc|
|
46
|
-
tests_to_run << desc
|
47
|
-
end
|
48
|
-
end
|
49
|
-
if lines_changed.empty?
|
50
|
-
puts "No line changes detected."
|
51
|
-
elsif tests_to_run.empty?
|
52
|
-
puts "No tests found. May be due to blind spot, new tests you've just written, or the changes may be untested."
|
53
|
-
else
|
54
|
-
puts "Run these tests:"
|
55
|
-
puts tests_to_run.uniq.sort
|
56
|
-
end
|
11
|
+
predict
|
57
12
|
else
|
58
13
|
puts "Please run miss_cleo with 'build_deck' or 'predict'."
|
59
14
|
end
|
60
15
|
|
61
|
-
def exclude_from_map?(file_name)
|
62
|
-
# Let's add a configuration for ignored files
|
63
|
-
file_name == "db/structure.sql"
|
64
|
-
end
|
65
|
-
|
66
|
-
def diff before, after
|
67
|
-
after.each_with_object({}) do |(file_name,line_cov), res|
|
68
|
-
before_line_cov = before[file_name] || []
|
69
|
-
|
70
|
-
# skip arrays that are exactly the same
|
71
|
-
next if before_line_cov == line_cov
|
72
|
-
|
73
|
-
# subtract the old coverage from the new coverage
|
74
|
-
cov = line_cov.zip(before_line_cov).map do |line_after, line_before|
|
75
|
-
if line_before
|
76
|
-
line_after - line_before
|
77
|
-
else
|
78
|
-
line_after
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
# add the "diffed" coverage to the hash
|
83
|
-
res[file_name] = cov
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def build_coverage_map(cov_map, cov_diffs)
|
88
|
-
cov_diffs.each do |test_to_code_map|
|
89
|
-
if test_to_code_map.length == 4 # for Minitest
|
90
|
-
test_file_and_line = test_to_code_map.first(2).join('#')
|
91
|
-
else # for RSpec
|
92
|
-
test_file_and_line = test_to_code_map.first
|
93
|
-
end
|
94
|
-
before, after = test_to_code_map.last(2)
|
95
|
-
|
96
|
-
# calculate the per test coverage
|
97
|
-
delta = diff before, after
|
98
|
-
|
99
|
-
delta.each_pair do |file, lines|
|
100
|
-
file_map = cov_map[file]
|
101
|
-
|
102
|
-
lines.each_with_index do |val, i|
|
103
|
-
# skip lines that weren't executed
|
104
|
-
next unless val && val > 0
|
105
|
-
|
106
|
-
# add the test name to the map. Multiple tests can execute the same
|
107
|
-
# line, so we need to use an array.
|
108
|
-
file_map[i + 1] << test_file_and_line
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
@@ -14,7 +14,7 @@ module MissCleo
|
|
14
14
|
def self.normalize_paths(result_hash)
|
15
15
|
normalized_hash = Hash.new
|
16
16
|
result_hash.each do |key, value|
|
17
|
-
trimmed_key = key.gsub(/#{Regexp.quote(`pwd`.chomp)}
|
17
|
+
trimmed_key = key.gsub(/#{Regexp.quote(`pwd`.chomp)}\//, "")
|
18
18
|
normalized_hash[trimmed_key] = value
|
19
19
|
end
|
20
20
|
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module MissCleo
|
2
|
+
module CoverageMapHelper
|
3
|
+
|
4
|
+
def build_deck(filenames)
|
5
|
+
cov_map = Hash.new { |h, file| h[file] = Hash.new { |i, line| i[line] = [] } }
|
6
|
+
filenames.each do |filename|
|
7
|
+
File.open(filename, "r") do |f|
|
8
|
+
f.read
|
9
|
+
end.tap do |contents|
|
10
|
+
begin
|
11
|
+
build_coverage_map(cov_map, JSON.parse(contents))
|
12
|
+
rescue
|
13
|
+
puts "#{filename} is malformed, this may affect test predictons"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
File.open("total_coverage_map.json", "w") do |f|
|
19
|
+
f.write(JSON.dump(cov_map))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def predict
|
24
|
+
repo = Rugged::Repository.new '.'
|
25
|
+
lines_changed = Set.new
|
26
|
+
|
27
|
+
repo.index.diff.each_patch do |patch|
|
28
|
+
file = patch.delta.old_file[:path]
|
29
|
+
|
30
|
+
patch.each_hunk do |hunk|
|
31
|
+
hunk.each_line do |line|
|
32
|
+
case line.line_origin
|
33
|
+
when :addition
|
34
|
+
lines_changed << [file, line.new_lineno] unless exclude_from_map?(file)
|
35
|
+
when :deletion
|
36
|
+
lines_changed << [file, line.old_lineno] unless exclude_from_map?(file)
|
37
|
+
when :context
|
38
|
+
# do nothing
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
coverage_map = JSON.parse(File.open("total_coverage_map.json").read)
|
45
|
+
tests_to_run = []
|
46
|
+
lines_changed.each do |file, line|
|
47
|
+
coverage_map && coverage_map[file] && coverage_map[file].fetch(line.to_s, []).uniq.each do |desc|
|
48
|
+
tests_to_run << desc
|
49
|
+
end
|
50
|
+
end
|
51
|
+
if lines_changed.empty?
|
52
|
+
puts "No line changes detected."
|
53
|
+
elsif tests_to_run.empty?
|
54
|
+
puts "No tests found. May be due to blind spot, new tests you've just written, or the changes may be untested."
|
55
|
+
else
|
56
|
+
puts "Run these tests:"
|
57
|
+
puts tests_to_run.uniq.sort
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def exclude_from_map?(file_name)
|
65
|
+
# Let's add a configuration for ignored files
|
66
|
+
file_name == "db/structure.sql"
|
67
|
+
end
|
68
|
+
|
69
|
+
def build_coverage_map(cov_map, cov_diffs)
|
70
|
+
cov_diffs.each do |test_to_code_map|
|
71
|
+
if test_to_code_map.length == 4 # for Minitest
|
72
|
+
test_file_and_line = test_to_code_map.first(2).join('#')
|
73
|
+
else # for RSpec
|
74
|
+
test_file_and_line = test_to_code_map.first
|
75
|
+
end
|
76
|
+
before, after = test_to_code_map.last(2)
|
77
|
+
|
78
|
+
# calculate the per test coverage
|
79
|
+
delta = diff before, after
|
80
|
+
|
81
|
+
delta.each_pair do |file, lines|
|
82
|
+
file_map = cov_map[file]
|
83
|
+
|
84
|
+
lines.each_with_index do |val, i|
|
85
|
+
# skip lines that weren't executed
|
86
|
+
next unless val && val > 0
|
87
|
+
|
88
|
+
# add the test name to the map. Multiple tests can execute the same
|
89
|
+
# line, so we need to use an array.
|
90
|
+
file_map[i + 1] << test_file_and_line
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def diff before, after
|
97
|
+
after.each_with_object({}) do |(file_name,line_cov), res|
|
98
|
+
before_line_cov = before[file_name] || []
|
99
|
+
|
100
|
+
# skip arrays that are exactly the same
|
101
|
+
next if before_line_cov == line_cov
|
102
|
+
|
103
|
+
# subtract the old coverage from the new coverage
|
104
|
+
cov = line_cov.zip(before_line_cov).map do |line_after, line_before|
|
105
|
+
if line_before
|
106
|
+
line_after - line_before
|
107
|
+
else
|
108
|
+
line_after
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# add the "diffed" coverage to the hash
|
113
|
+
res[file_name] = cov
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/lib/miss_cleo/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: miss_cleo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dean Hu
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2015-11-
|
13
|
+
date: 2015-11-20 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -62,6 +62,7 @@ files:
|
|
62
62
|
- bin/setup
|
63
63
|
- lib/miss_cleo.rb
|
64
64
|
- lib/miss_cleo/coverage_filter.rb
|
65
|
+
- lib/miss_cleo/coverage_map_helper.rb
|
65
66
|
- lib/miss_cleo/test_configurations/cucumber_config.rb
|
66
67
|
- lib/miss_cleo/test_configurations/rspec_config.rb
|
67
68
|
- lib/miss_cleo/version.rb
|