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 +5 -0
- data/Rakefile +2 -0
- data/Readme.md +26 -0
- data/bin/fixture-reducer +8 -0
- data/fixture_reducer.gemspec +15 -0
- data/gem-public_cert.pem +20 -0
- data/lib/fixture_reducer/version.rb +3 -0
- data/lib/fixture_reducer.rb +147 -0
- data/spec/fixture_reducer_spec.rb +7 -0
- data/spec/spec_helper.rb +1 -0
- data.tar.gz.sig +0 -0
- metadata +89 -0
- metadata.gz.sig +0 -0
data/Gemfile
ADDED
data/Rakefile
ADDED
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/>
|
data/bin/fixture-reducer
ADDED
@@ -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
|
data/gem-public_cert.pem
ADDED
@@ -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,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
|
data/spec/spec_helper.rb
ADDED
@@ -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
|