fixture_reducer 0.1.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.
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+ gemspec
3
+
4
+ gem "bump"
5
+ gem "rake"
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ require "bump/tasks"
data/Readme.md ADDED
@@ -0,0 +1,26 @@
1
+ Test speedup by replacing fixtures :all with only the necessary
2
+
3
+ - reduces fixtures :all
4
+ - tries common fixtures first before going to one-by-one approach
5
+ - uses zeus if zeus is running (faster)
6
+
7
+ Install
8
+ =======
9
+
10
+ gem install fixture_reducer
11
+
12
+ Usage
13
+ =====
14
+
15
+ fixture-reducer test/foo_test.rb test/bar_test.rb ...
16
+
17
+ TODO
18
+ ====
19
+ - tests + travis (please use rspec)
20
+ - rspec support
21
+
22
+ Author
23
+ ======
24
+ [Michael Grosser](http://grosser.it)<br/>
25
+ michael@grosser.it<br/>
26
+ License: MIT<br/>
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
3
+ require 'fixture_reducer'
4
+
5
+ raise "pass me test files" if ARGV.empty?
6
+ puts "running on #{ARGV.inspect}"
7
+
8
+ ARGV.each { |file| FixtureReducer.new(file).reduce_fixtures! }
@@ -0,0 +1,15 @@
1
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
2
+ name = "fixture_reducer"
3
+ require "#{name.gsub("-","/")}/version"
4
+
5
+ Gem::Specification.new name, FixtureReducer::VERSION do |s|
6
+ s.summary = "Test speedup by replacing fixtures :all with only the necessary"
7
+ s.authors = ["Michael Grosser"]
8
+ s.email = "michael@grosser.it"
9
+ s.homepage = "http://github.com/grosser/#{name}"
10
+ s.files = `git ls-files`.split("\n")
11
+ s.license = "MIT"
12
+ s.signing_key = File.expand_path("~/.ssh/gem-private_key.pem")
13
+ s.cert_chain = ["gem-public_cert.pem"]
14
+ s.executables = ["fixture-reducer"]
15
+ end
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDMjCCAhqgAwIBAgIBADANBgkqhkiG9w0BAQUFADA/MRAwDgYDVQQDDAdtaWNo
3
+ YWVsMRcwFQYKCZImiZPyLGQBGRYHZ3Jvc3NlcjESMBAGCgmSJomT8ixkARkWAml0
4
+ MB4XDTEzMDIwMzE4MTMxMVoXDTE0MDIwMzE4MTMxMVowPzEQMA4GA1UEAwwHbWlj
5
+ aGFlbDEXMBUGCgmSJomT8ixkARkWB2dyb3NzZXIxEjAQBgoJkiaJk/IsZAEZFgJp
6
+ dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMorXo/hgbUq97+kII9H
7
+ MsQcLdC/7wQ1ZP2OshVHPkeP0qH8MBHGg6eYisOX2ubNagF9YTCZWnhrdKrwpLOO
8
+ cPLaZbjUjljJ3cQR3B8Yn1veV5IhG86QseTBjymzJWsLpqJ1UZGpfB9tXcsFtuxO
9
+ 6vHvcIHdzvc/OUkICttLbH+1qb6rsHUceqh+JrH4GrsJ5H4hAfIdyS2XMK7YRKbh
10
+ h+IBu6dFWJJByzFsYmV1PDXln3UBmgAt65cmCu4qPfThioCGDzbSJrGDGLmw/pFX
11
+ FPpVCm1zgYSb1v6Qnf3cgXa2f2wYGm17+zAVyIDpwryFru9yF/jJxE38z/DRsd9R
12
+ /88CAwEAAaM5MDcwCQYDVR0TBAIwADAdBgNVHQ4EFgQUsiNnXHtKeMYYcr4yJVmQ
13
+ WONL+IwwCwYDVR0PBAQDAgSwMA0GCSqGSIb3DQEBBQUAA4IBAQAlyN7kKo/NQCQ0
14
+ AOzZLZ3WAePvStkCFIJ53tsv5Kyo4pMAllv+BgPzzBt7qi605mFSL6zBd9uLou+W
15
+ Co3s48p1dy7CjjAfVQdmVNHF3MwXtfC2OEyvSQPi4xKR8iba8wa3xp9LVo1PuLpw
16
+ /6DsrChWw74HfsJN6qJOK684hJeT8lBYAUfiC3wD0owoPSg+XtyAAddisR+KV5Y1
17
+ NmVHuLtQcNTZy+gRht3ahJRMuC6QyLmkTsf+6MaenwAMkAgHdswGsJztOnNnBa3F
18
+ y0kCSWmK6D+x/SbfS6r7Ke07MRqziJdB9GuE1+0cIRuFh8EQ+LN6HXCKM5pon/GU
19
+ ycwMXfl0
20
+ -----END CERTIFICATE-----
@@ -0,0 +1,3 @@
1
+ module FixtureReducer
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,147 @@
1
+ require "fixture_reducer/version"
2
+
3
+ module FixtureReducer
4
+ class FixtureReducer
5
+ # also use multiline fixture declarations
6
+ FIXTURE_REX = /(^\s+)fixtures\s+([^,\s]+(,\s*[^,\s]+)*)/m
7
+
8
+ attr_reader :test_file
9
+
10
+ def initialize(test_file)
11
+ @test_file = test_file
12
+ @test_folder = test_file.split("/").first
13
+ @test_extension = "_#{@test_folder}.rb"
14
+ end
15
+
16
+ def reduce_fixtures!
17
+ if fixtures = fixture_params(test_file)
18
+ puts "#{test_file} uses #{fixtures.join(", ")}"
19
+
20
+ if run_with(fixtures)
21
+ puts "initial run: SUCCESS"
22
+ original_fixtures = fixtures.dup
23
+ fixtures = reduced_via_common([99, 95, 90, 80, 50]) if fixtures == [":all"]
24
+ fixtures = reduce_one_by_one(fixtures)
25
+ report_and_keep_reduction(original_fixtures, fixtures)
26
+ else
27
+ puts "initial run: FAILED"
28
+ end
29
+ else
30
+ puts "did not find fixtures in #{test_file}"
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def usage_stats
37
+ @usage_stats ||= begin
38
+ used_fixtures = Dir["#{@test_folder}/**/*#{@test_extension}"].map { |file| fixture_params(file) }.compact.flatten
39
+ used_fixtures -= [":all"]
40
+ used_fixtures.flatten.group_by(&:to_s).map { |g, f| [g, f.size] }.sort_by(&:last)
41
+ end.freeze
42
+ end
43
+
44
+ def common_fixtures(percent)
45
+ usage = usage_stats.dup
46
+ total = usage.map(&:last).inject(&:+)
47
+ used = 0
48
+ used += usage.shift.last while used < (total / 100 * percent)
49
+ usage.reverse.map(&:first)
50
+ end
51
+
52
+ def run(file)
53
+ `bundle exec rake db:test:prepare && #{test_runner} #{file}`
54
+ $?.success?
55
+ end
56
+
57
+ def test_runner
58
+ if File.exist? ".zeus.sock"
59
+ "zeus testrb"
60
+ else
61
+ "bundle exec ruby"
62
+ end
63
+ end
64
+
65
+ def run_with(fixtures)
66
+ old = read(test_file)
67
+ write_fixtures(fixtures)
68
+ run test_file
69
+ ensure
70
+ write(test_file, old)
71
+ end
72
+
73
+ def write(file, content)
74
+ File.open(file, 'w'){|f| f.write content }
75
+ end
76
+
77
+ def write_fixtures(fixtures)
78
+ code = (fixtures.empty? ? "" : "fixtures #{fixtures.join(', ')}")
79
+ write(test_file, File.read(test_file).sub(FIXTURE_REX, "\\1#{code}"))
80
+ end
81
+
82
+ def read(file)
83
+ File.read(file)
84
+ end
85
+
86
+ def fixtures_in_file
87
+ found = fixture_params(test_file)
88
+ found == [":all"] ? available_fixtures : found
89
+ end
90
+
91
+ def fixture_params(file)
92
+ content = File.read(file)
93
+ return unless match = content.match(FIXTURE_REX)
94
+ match[2].split(/,\s+/)
95
+ end
96
+
97
+ def available_fixtures
98
+ folder = "#{@test_folder}/fixtures/"
99
+ extensions = ["yml", "csv"]
100
+ Dir["#{folder}*.{#{extensions.join(",")}}"].map{|f| f.sub(%r{#{folder}(.*)(\.#{extensions.join("|")})}, ":\\1") }
101
+ end
102
+
103
+ def report_and_keep_reduction(original_fixtures, fixtures)
104
+ original_fixtures = available_fixtures if original_fixtures == [":all"]
105
+ removed_fixtures = original_fixtures - fixtures
106
+
107
+ if removed_fixtures.empty?
108
+ puts "could not reduce fixtures"
109
+ else
110
+ puts "could reduce fixtures by #{removed_fixtures.size}"
111
+ write_fixtures(fixtures)
112
+ end
113
+ end
114
+
115
+ def reduced_via_common(percentages)
116
+ last_success = nil
117
+ percentages.each do |percent|
118
+ fixtures = common_fixtures(percent)
119
+ if run_with(fixtures)
120
+ puts "common #{percent}% run: SUCCESS"
121
+ last_success = fixtures
122
+ else
123
+ puts "common #{percent}% run: FAILED"
124
+ break
125
+ end
126
+ end
127
+ last_success || available_fixtures
128
+ end
129
+
130
+ def reduce_one_by_one(fixtures)
131
+ necessary_fixtures = fixtures
132
+ fixtures.each do |fixture|
133
+ current_try = necessary_fixtures - [fixture]
134
+
135
+ if read(test_file) =~ /(^|[^a-z\d_])#{fixture.sub(':','')}[\( ]:/
136
+ puts "#{fixture} is called directly"
137
+ elsif run_with(current_try)
138
+ puts "#{fixture} is not needed"
139
+ necessary_fixtures = current_try
140
+ else
141
+ puts "#{fixture} is needed"
142
+ end
143
+ end
144
+ necessary_fixtures
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ describe FixtureReducer do
4
+ it "has a VERSION" do
5
+ FixtureReducer::VERSION.should =~ /^[\.\da-z]+$/
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ require "fixture_reducer"
data.tar.gz.sig ADDED
Binary file
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fixture_reducer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Michael Grosser
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain:
12
+ - !binary |-
13
+ LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURNakNDQWhxZ0F3SUJB
14
+ Z0lCQURBTkJna3Foa2lHOXcwQkFRVUZBREEvTVJBd0RnWURWUVFEREFkdGFX
15
+ Tm8KWVdWc01SY3dGUVlLQ1pJbWlaUHlMR1FCR1JZSFozSnZjM05sY2pFU01C
16
+ QUdDZ21TSm9tVDhpeGtBUmtXQW1sMApNQjRYRFRFek1ESXdNekU0TVRNeE1W
17
+ b1hEVEUwTURJd016RTRNVE14TVZvd1B6RVFNQTRHQTFVRUF3d0hiV2xqCmFH
18
+ RmxiREVYTUJVR0NnbVNKb21UOGl4a0FSa1dCMmR5YjNOelpYSXhFakFRQmdv
19
+ SmtpYUprL0lzWkFFWkZnSnAKZERDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFB
20
+ RGdnRVBBRENDQVFvQ2dnRUJBTW9yWG8vaGdiVXE5NytrSUk5SApNc1FjTGRD
21
+ Lzd3UTFaUDJPc2hWSFBrZVAwcUg4TUJIR2c2ZVlpc09YMnViTmFnRjlZVENa
22
+ V25ocmRLcndwTE9PCmNQTGFaYmpVamxqSjNjUVIzQjhZbjF2ZVY1SWhHODZR
23
+ c2VUQmp5bXpKV3NMcHFKMVVaR3BmQjl0WGNzRnR1eE8KNnZIdmNJSGR6dmMv
24
+ T1VrSUN0dExiSCsxcWI2cnNIVWNlcWgrSnJINEdyc0o1SDRoQWZJZHlTMlhN
25
+ SzdZUktiaApoK0lCdTZkRldKSkJ5ekZzWW1WMVBEWGxuM1VCbWdBdDY1Y21D
26
+ dTRxUGZUaGlvQ0dEemJTSnJHREdMbXcvcEZYCkZQcFZDbTF6Z1lTYjF2NlFu
27
+ ZjNjZ1hhMmYyd1lHbTE3K3pBVnlJRHB3cnlGcnU5eUYvakp4RTM4ei9EUnNk
28
+ OVIKLzg4Q0F3RUFBYU01TURjd0NRWURWUjBUQkFJd0FEQWRCZ05WSFE0RUZn
29
+ UVVzaU5uWEh0S2VNWVljcjR5SlZtUQpXT05MK0l3d0N3WURWUjBQQkFRREFn
30
+ U3dNQTBHQ1NxR1NJYjNEUUVCQlFVQUE0SUJBUUFseU43a0tvL05RQ1EwCkFP
31
+ elpMWjNXQWVQdlN0a0NGSUo1M3RzdjVLeW80cE1BbGx2K0JnUHp6QnQ3cWk2
32
+ MDVtRlNMNnpCZDl1TG91K1cKQ28zczQ4cDFkeTdDampBZlZRZG1WTkhGM013
33
+ WHRmQzJPRXl2U1FQaTR4S1I4aWJhOHdhM3hwOUxWbzFQdUxwdwovNkRzckNo
34
+ V3c3NEhmc0pONnFKT0s2ODRoSmVUOGxCWUFVZmlDM3dEMG93b1BTZytYdHlB
35
+ QWRkaXNSK0tWNVkxCk5tVkh1THRRY05UWnkrZ1JodDNhaEpSTXVDNlF5TG1r
36
+ VHNmKzZNYWVud0FNa0FnSGRzd0dzSnp0T25ObkJhM0YKeTBrQ1NXbUs2RCt4
37
+ L1NiZlM2cjdLZTA3TVJxemlKZEI5R3VFMSswY0lSdUZoOEVRK0xONkhYQ0tN
38
+ NXBvbi9HVQp5Y3dNWGZsMAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
39
+ date: 2013-03-10 00:00:00.000000000 Z
40
+ dependencies: []
41
+ description:
42
+ email: michael@grosser.it
43
+ executables:
44
+ - fixture-reducer
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - Gemfile
49
+ - Rakefile
50
+ - Readme.md
51
+ - bin/fixture-reducer
52
+ - fixture_reducer.gemspec
53
+ - gem-public_cert.pem
54
+ - lib/fixture_reducer.rb
55
+ - lib/fixture_reducer/version.rb
56
+ - spec/fixture_reducer_spec.rb
57
+ - spec/spec_helper.rb
58
+ homepage: http://github.com/grosser/fixture_reducer
59
+ licenses:
60
+ - MIT
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ segments:
72
+ - 0
73
+ hash: -542410227692063686
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ segments:
81
+ - 0
82
+ hash: -542410227692063686
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 1.8.25
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Test speedup by replacing fixtures :all with only the necessary
89
+ test_files: []
metadata.gz.sig ADDED
Binary file