cleanser 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH << File.expand_path("../../lib", __FILE__)
3
+ require "rubygems" if RUBY_VERSION < "1.9"
4
+ require "cleanser"
5
+ exit Cleanser.cli(ARGV)
@@ -0,0 +1,3 @@
1
+ module Cleanser
2
+ VERSION = "0.1.0"
3
+ end
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: []