cleanser 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/bin/cleanser +5 -0
- data/lib/cleanser/version.rb +3 -0
- data/lib/cleanser.rb +112 -0
- metadata +47 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 498aaa7929e49eedb7de42a6a1003d7c599a8a28
|
4
|
+
data.tar.gz: 84b5ee67a79f4aa5182110afc1f87bd09d47e9e6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 897729da315f468c7fe74e4a1c0c520dea48de54d77c562daf8a0e90efaf52f54c510f09047330811a4e41cd063399a9f9440bb81fac154f84d658de0850a18c
|
7
|
+
data.tar.gz: 4d97456a739ac5a6192c12584f8826218b5b701ce0079d757dceef9ade83b18040a67e2930d79157ceb7e91ea47b2df97a11ca4d4cedb741981178ab378f3c15
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (C) 2013 Michael Grosser <michael@grosser.it>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/bin/cleanser
ADDED
data/lib/cleanser.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
module Cleanser
|
2
|
+
class << self
|
3
|
+
def cli(argv)
|
4
|
+
options = parse_options(argv)
|
5
|
+
find_polluter(argv, options) ? 0 : 1
|
6
|
+
end
|
7
|
+
|
8
|
+
def find_polluter(files, options={})
|
9
|
+
failing = files.pop
|
10
|
+
expand_folders(files, failing)
|
11
|
+
|
12
|
+
if !files.include?(failing)
|
13
|
+
abort "Files have to include the failing file, use the copy helper"
|
14
|
+
elsif files.size < 2
|
15
|
+
abort "Files have to be more than 2, use the copy helper"
|
16
|
+
elsif !success?([failing], options)
|
17
|
+
abort "#{failing} fails when run on it's own"
|
18
|
+
elsif success?(files, options)
|
19
|
+
abort "tests pass locally"
|
20
|
+
else
|
21
|
+
loop do
|
22
|
+
a = remove_from(files, files.size / 2, :not => failing)
|
23
|
+
b = files - (a - [failing])
|
24
|
+
status, files = find_polluter_set([a, b], failing, options)
|
25
|
+
if status == :finished
|
26
|
+
puts "Fails when #{files.join(", ")} are run together"
|
27
|
+
return true
|
28
|
+
elsif status == :continue
|
29
|
+
next
|
30
|
+
else
|
31
|
+
abort "unable to isolate failure to 2 files"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def parse_options(argv)
|
40
|
+
require 'optparse'
|
41
|
+
options = {}
|
42
|
+
OptionParser.new do |opts|
|
43
|
+
opts.banner = <<-BANNER.gsub(/^ {10}/, "")
|
44
|
+
Find polluting test by bisecting your tests.
|
45
|
+
|
46
|
+
|
47
|
+
Usage:
|
48
|
+
cleanser a.rb failing.rb b.rb c.rb failing.rb
|
49
|
+
cleanser folder failing.rb
|
50
|
+
|
51
|
+
Options:
|
52
|
+
BANNER
|
53
|
+
opts.on("-r", "--rspec", "RSpec") { options[:rspec] = true }
|
54
|
+
opts.on("-h", "--help", "Show this.") { puts opts; exit }
|
55
|
+
opts.on("-v", "--version", "Show Version"){ require 'cleanser/version'; puts Cleanser::VERSION; exit}
|
56
|
+
end.parse!(argv)
|
57
|
+
options
|
58
|
+
end
|
59
|
+
|
60
|
+
def expand_folders(files, failing)
|
61
|
+
files.map! do |f|
|
62
|
+
File.file?(f) ? f : files_from_folder(f, pattern(failing))
|
63
|
+
end.flatten!
|
64
|
+
end
|
65
|
+
|
66
|
+
def files_from_folder(folder, pattern)
|
67
|
+
nested = "{,/*/**}" # follow one symlink and direct children
|
68
|
+
Dir[File.join(folder, nested, pattern)].map{|f|f.gsub("//", "/")}
|
69
|
+
end
|
70
|
+
|
71
|
+
def pattern(test)
|
72
|
+
base = test.split($/).last
|
73
|
+
if base =~ /^test_/
|
74
|
+
"#{$1}*"
|
75
|
+
elsif base =~ /(_test|_spec)\.rb/
|
76
|
+
"*#{$1}.rb"
|
77
|
+
else
|
78
|
+
"*"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def find_polluter_set(sets, failing, options)
|
83
|
+
sets.each do |set|
|
84
|
+
next if set == [failing]
|
85
|
+
if !success?(set, options)
|
86
|
+
if set.size == 2
|
87
|
+
return [:finished, set]
|
88
|
+
else
|
89
|
+
return [:continue, set]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
return [:failure, []]
|
94
|
+
end
|
95
|
+
|
96
|
+
def remove_from(set, x, options)
|
97
|
+
set.dup.delete_if { |f| f != options[:not] && (x -= 1) >= 0 }
|
98
|
+
end
|
99
|
+
|
100
|
+
def success?(files, options)
|
101
|
+
command = if options[:rspec]
|
102
|
+
"bundle exec rspec #{files.join(" ")}"
|
103
|
+
else
|
104
|
+
"bundle exec ruby #{files.map { |f| "-r./#{f.sub(/\.rb$/, "")}" }.join(" ")} -e ''"
|
105
|
+
end
|
106
|
+
puts "Running: #{command}"
|
107
|
+
status = system(command)
|
108
|
+
puts "Status: #{status ? "Success" : "Failure"}"
|
109
|
+
status
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
metadata
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cleanser
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Grosser
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-07-13 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email: michael@grosser.it
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- MIT-LICENSE
|
20
|
+
- bin/cleanser
|
21
|
+
- lib/cleanser.rb
|
22
|
+
- lib/cleanser/version.rb
|
23
|
+
homepage: https://github.com/grosser/cleanser
|
24
|
+
licenses:
|
25
|
+
- MIT
|
26
|
+
metadata: {}
|
27
|
+
post_install_message:
|
28
|
+
rdoc_options: []
|
29
|
+
require_paths:
|
30
|
+
- lib
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
requirements: []
|
42
|
+
rubyforge_project:
|
43
|
+
rubygems_version: 2.2.2
|
44
|
+
signing_key:
|
45
|
+
specification_version: 4
|
46
|
+
summary: Find polluting test by bisecting your tests
|
47
|
+
test_files: []
|