rack-pagespeed 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/Gemfile +13 -0
  2. data/Gemfile.lock +59 -0
  3. data/README.md +15 -0
  4. data/Rakefile +36 -0
  5. data/VERSION +1 -0
  6. data/lib/rack-pagespeed.rb +1 -0
  7. data/lib/rack/pagespeed.rb +46 -0
  8. data/lib/rack/pagespeed/config.rb +72 -0
  9. data/lib/rack/pagespeed/filters/all.rb +7 -0
  10. data/lib/rack/pagespeed/filters/base.rb +53 -0
  11. data/lib/rack/pagespeed/filters/combine_css.rb +73 -0
  12. data/lib/rack/pagespeed/filters/combine_javascripts.rb +69 -0
  13. data/lib/rack/pagespeed/filters/inline_css.rb +16 -0
  14. data/lib/rack/pagespeed/filters/inline_javascripts.rb +17 -0
  15. data/lib/rack/pagespeed/filters/minify_javascripts.rb +41 -0
  16. data/lib/rack/pagespeed/store/all.rb +6 -0
  17. data/lib/rack/pagespeed/store/disk.rb +18 -0
  18. data/lib/rack/pagespeed/store/memcached.rb +17 -0
  19. data/spec/config_spec.rb +187 -0
  20. data/spec/filters/combine_css_spec.rb +30 -0
  21. data/spec/filters/combine_javascripts_spec.rb +48 -0
  22. data/spec/filters/filter_spec.rb +57 -0
  23. data/spec/filters/inline_css_spec.rb +33 -0
  24. data/spec/filters/inline_javascript_spec.rb +30 -0
  25. data/spec/filters/minify_javascript_spec.rb +59 -0
  26. data/spec/fixtures/complex.html +33 -0
  27. data/spec/fixtures/foo.js +1 -0
  28. data/spec/fixtures/hh-reset.css +1 -0
  29. data/spec/fixtures/huge.css +1176 -0
  30. data/spec/fixtures/iphone.css +1 -0
  31. data/spec/fixtures/jquery-1.4.1.min.js +152 -0
  32. data/spec/fixtures/medialess1.css +2 -0
  33. data/spec/fixtures/medialess2.css +2 -0
  34. data/spec/fixtures/mylib.js +3 -0
  35. data/spec/fixtures/noexternalcss.html +11 -0
  36. data/spec/fixtures/noscripts.html +9 -0
  37. data/spec/fixtures/ohno.js +1 -0
  38. data/spec/fixtures/reset.css +1 -0
  39. data/spec/fixtures/screen.css +2 -0
  40. data/spec/fixtures/styles.html +10 -0
  41. data/spec/fixtures/zecoolwebsite/css/awesomebydesign.css +94 -0
  42. data/spec/fixtures/zecoolwebsite/css/reset.css +190 -0
  43. data/spec/fixtures/zecoolwebsite/img/bg-idevice.png +0 -0
  44. data/spec/fixtures/zecoolwebsite/img/bg.png +0 -0
  45. data/spec/fixtures/zecoolwebsite/img/bottom-left-arrow.png +0 -0
  46. data/spec/fixtures/zecoolwebsite/img/bottom-right-arrow.png +0 -0
  47. data/spec/fixtures/zecoolwebsite/img/consulting-arrow.png +0 -0
  48. data/spec/fixtures/zecoolwebsite/img/design-arrow.png +0 -0
  49. data/spec/fixtures/zecoolwebsite/img/prototyping-arrow.png +0 -0
  50. data/spec/fixtures/zecoolwebsite/img/top-left-arrow.png +0 -0
  51. data/spec/fixtures/zecoolwebsite/img/top-right-arrow.png +0 -0
  52. data/spec/fixtures/zecoolwebsite/img/webdev-arrow.png +0 -0
  53. data/spec/fixtures/zecoolwebsite/index.html +87 -0
  54. data/spec/fixtures/zecoolwebsite/js/awesomebydesign.js +103 -0
  55. data/spec/fixtures/zecoolwebsite/js/jquery-1.4.2.min.js +154 -0
  56. data/spec/fixtures/zecoolwebsite/js/modernizr-1.5.min.js +28 -0
  57. data/spec/fixtures/zecoolwebsite/js/sayhi.js +1 -0
  58. data/spec/integration/integration_spec.rb +54 -0
  59. data/spec/pagespeed_spec.rb +101 -0
  60. data/spec/spec_helper.rb +54 -0
  61. data/spec/store/disk_spec.rb +34 -0
  62. data/spec/store/memcached_spec.rb +29 -0
  63. metadata +344 -0
@@ -0,0 +1,101 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe 'rack-pagespeed' do
4
+ before do
5
+ @pagespeed = Rack::PageSpeed.new Apps.complex, :public => Fixtures.path, :store => {}
6
+ @env = Rack::MockRequest.env_for '/'
7
+ end
8
+
9
+ context 'parsing the response body' do
10
+ before do
11
+ status, headers, @response = @pagespeed.call @env
12
+ end
13
+
14
+ it "doesn't happen unless the response is not HTML" do
15
+ pagespeed = Rack::PageSpeed.new Apps.plain_text, :public => Fixtures.path
16
+ pagespeed.call @env
17
+ pagespeed.instance_variable_get(:@document).should be_nil
18
+ end
19
+
20
+ it "only happens if the response is HTML" do
21
+ pagespeed = Rack::PageSpeed.new Apps.complex, :public => Fixtures.path
22
+ pagespeed.call @env
23
+ pagespeed.instance_variable_get(:@document).should_not be_nil
24
+ end
25
+ end
26
+
27
+ context 'configuration' do
28
+ before do
29
+ class BarFilter < Rack::PageSpeed::Filters::Base; end
30
+ class FooFilter < Rack::PageSpeed::Filters::Base; end
31
+ end
32
+
33
+ it "takes an options hash which gets passed to it's config" do
34
+ @pagespeed.config.public.should == Fixtures.path
35
+ end
36
+
37
+ it "takes a block which gets passed to it's config" do
38
+ pagespeed = Rack::PageSpeed.new Apps.complex, :public => Fixtures.path do
39
+ bar_filter
40
+ end
41
+ pagespeed.config.filters.first.should be_a BarFilter
42
+ end
43
+
44
+ it "passes the constructor's options down to the filters" do
45
+ pagespeed = Rack::PageSpeed.new Apps.complex, :public => Fixtures.path, :store => {} do
46
+ foo_filter
47
+ end
48
+ pagespeed.config.filters.first.options.should == {:public => Fixtures.path, :store => {}}
49
+ end
50
+
51
+ end
52
+
53
+ context 'dispatching filters' do
54
+ before do
55
+ $foo = []
56
+ class AddsFoo < Rack::PageSpeed::Filters::Base; def execute! document; $foo << 'foo' end; end
57
+ class AddsBar < Rack::PageSpeed::Filters::Base; def execute! document; $foo << 'bar' end; end
58
+ @pagespeed = Rack::PageSpeed.new Apps.complex, :public => Fixtures.path do
59
+ adds_foo
60
+ adds_bar
61
+ end
62
+ end
63
+
64
+ it "calls #execute! on each filter it finds in it's config" do
65
+ @pagespeed.call @env
66
+ $foo.should include('foo', 'bar')
67
+ end
68
+ end
69
+
70
+ context 'responding to /rack-pagespeed-* requests' do
71
+ context 'for assets that it finds in store' do
72
+ before do
73
+ store = @pagespeed.config.store
74
+ store['12345.js'] = 'Little poney'
75
+ @status, @headers, @response = @pagespeed.call Rack::MockRequest.env_for '/rack-pagespeed-12345.js'
76
+ end
77
+
78
+ it "responds with the contents in store that match the asset unique id" do
79
+ @response.to_s.should == 'Little poney'
80
+ end
81
+
82
+ it "responds with the appropriate MIME type for the asset stored" do
83
+ @headers['Content-Type'].should == 'application/javascript'
84
+ end
85
+
86
+ it "responds with HTTP 200" do
87
+ @status.should == 200
88
+ end
89
+ end
90
+ end
91
+
92
+ context "for assets that can't be found in store" do
93
+ before do
94
+ @status, @headers, @response = @pagespeed.call Rack::MockRequest.env_for '/rack-pagespeed-nonexistent.css'
95
+ end
96
+
97
+ it "responds with HTTP 404" do
98
+ @status.should == 404
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,54 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
+ require 'rspec'
3
+ require 'fileutils'
4
+ require 'rack/pagespeed'
5
+ require 'fileutils'
6
+ require 'tmpdir'
7
+ require 'ostruct'
8
+
9
+ def fixture name
10
+ File.read(File.join(Fixtures.path, name))
11
+ end
12
+
13
+ module Apps
14
+ class << self
15
+ def complex
16
+ lambda { |env| [200, { 'Content-Type' => 'text/html' }, [fixture('complex.html')]] }
17
+ end
18
+
19
+ def plain_text
20
+ lambda { |env| [200, { 'Content-Type' => 'text/plain' }, ['plain texto']] }
21
+ end
22
+ end
23
+ end
24
+
25
+ Fixtures = OpenStruct.new unless defined?(Fixtures)
26
+ Fixtures.path = File.join(File.dirname(__FILE__), 'fixtures')
27
+ Fixtures.complex = Nokogiri::HTML(fixture('complex.html'))
28
+ Fixtures.noscripts = Nokogiri::HTML(fixture('noscripts.html'))
29
+ Fixtures.noexternalcss = Nokogiri::HTML(fixture('noexternalcss.html'))
30
+ Fixtures.styles = Nokogiri::HTML(fixture('styles.html'))
31
+
32
+
33
+ def include_an_instance_of klass
34
+ simple_matcher("have an instance of #{klass.to_s}") do |given|
35
+ given.select { |entry| entry.is_a? klass }.any?
36
+ end
37
+ end
38
+
39
+ RSpec::Matchers.define :include_an_instance_of do |klass|
40
+ match do |given|
41
+ given.select { |entry| entry.is_a? klass }.count > 0
42
+ end
43
+ end
44
+
45
+ RSpec.configure do |config|
46
+ # Restore fixtures' original state
47
+ config.before :each do
48
+ Fixtures.complex = Nokogiri::HTML(fixture('complex.html'))
49
+ Fixtures.noscripts = Nokogiri::HTML(fixture('noscripts.html'))
50
+ Fixtures.noexternalcss = Nokogiri::HTML(fixture('noexternalcss.html'))
51
+ Fixtures.styles = Nokogiri::HTML(fixture('styles.html'))
52
+ end
53
+ end
54
+
@@ -0,0 +1,34 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe 'disk storage' do
4
+ before :all do
5
+ Rack::PageSpeed::Config
6
+ @store = Rack::PageSpeed::Store::Disk.new
7
+ end
8
+
9
+ context 'initializing' do
10
+ it "sets the path to the value passed to the constructor" do
11
+ Rack::PageSpeed::Store::Disk.new(Fixtures.path).instance_variable_get(:@path).should == Fixtures.path
12
+ end
13
+ it "defaults to the system's TMP dir if nothing is passed to the constructor" do
14
+ Rack::PageSpeed::Store::Disk.new.instance_variable_get(:@path).should == Dir.tmpdir
15
+ end
16
+ it "raises ArgumentError if the path passed to the constructor is not a directory" do
17
+ expect { Rack::PageSpeed::Store::Disk.new 'unpossible sir' }.to raise_error(ArgumentError)
18
+ end
19
+ end
20
+
21
+ context 'writing' do
22
+ it "writes to disk with a Hash-like syntax" do
23
+ @store['omg'] = "value"
24
+ File.read("#{Dir.tmpdir}/rack-pagespeed-omg").should == "value"
25
+ end
26
+ end
27
+
28
+ context 'reading' do
29
+ it "reads from disk with a Hash-like syntax" do
30
+ File.open("#{Dir.tmpdir}/rack-pagespeed-hola", 'w') { |file| file << "Hola mundo" }
31
+ @store['hola'].should == "Hola mundo"
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe 'memcached storage' do
4
+ before :all do
5
+ Rack::PageSpeed::Config # load all storage mechanisms
6
+ @store = Rack::PageSpeed::Store::Memcached.new
7
+ @client = @store.instance_variable_get(:@client)
8
+ end
9
+
10
+ context 'initializing' do
11
+ it "errors out if it can't connect to Memcached" do
12
+ expect { MemcachedStore.new('ohfoo').new }.to raise_error
13
+ end
14
+ end
15
+
16
+ context 'writing' do
17
+ it "writes with a Hash-like syntax" do
18
+ @client.should_receive(:set).with('omg', 'value')
19
+ @store['omg'] = "value"
20
+ end
21
+ end
22
+
23
+ context 'reading' do
24
+ it "reads with a Hash-like syntax" do
25
+ @client.set 'hola', 'Hola mundo'
26
+ @store['hola'].should == "Hola mundo"
27
+ end
28
+ end
29
+ end
metadata ADDED
@@ -0,0 +1,344 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-pagespeed
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Julio Cesar Ody
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-12-23 00:00:00 +11:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: nokogiri
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - "="
28
+ - !ruby/object:Gem::Version
29
+ hash: 15
30
+ segments:
31
+ - 1
32
+ - 4
33
+ - 4
34
+ version: 1.4.4
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: rack
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - "="
44
+ - !ruby/object:Gem::Version
45
+ hash: 29
46
+ segments:
47
+ - 1
48
+ - 2
49
+ - 1
50
+ version: 1.2.1
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: memcached
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - "="
60
+ - !ruby/object:Gem::Version
61
+ hash: 19
62
+ segments:
63
+ - 1
64
+ - 0
65
+ - 2
66
+ version: 1.0.2
67
+ type: :runtime
68
+ version_requirements: *id003
69
+ - !ruby/object:Gem::Dependency
70
+ name: mime-types
71
+ prerelease: false
72
+ requirement: &id004 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - "="
76
+ - !ruby/object:Gem::Version
77
+ hash: 47
78
+ segments:
79
+ - 1
80
+ - 16
81
+ version: "1.16"
82
+ type: :runtime
83
+ version_requirements: *id004
84
+ - !ruby/object:Gem::Dependency
85
+ name: jsmin
86
+ prerelease: false
87
+ requirement: &id005 !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - "="
91
+ - !ruby/object:Gem::Version
92
+ hash: 21
93
+ segments:
94
+ - 1
95
+ - 0
96
+ - 1
97
+ version: 1.0.1
98
+ type: :runtime
99
+ version_requirements: *id005
100
+ - !ruby/object:Gem::Dependency
101
+ name: nokogiri
102
+ prerelease: false
103
+ requirement: &id006 !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - "="
107
+ - !ruby/object:Gem::Version
108
+ hash: 15
109
+ segments:
110
+ - 1
111
+ - 4
112
+ - 4
113
+ version: 1.4.4
114
+ type: :runtime
115
+ version_requirements: *id006
116
+ - !ruby/object:Gem::Dependency
117
+ name: rack
118
+ prerelease: false
119
+ requirement: &id007 !ruby/object:Gem::Requirement
120
+ none: false
121
+ requirements:
122
+ - - "="
123
+ - !ruby/object:Gem::Version
124
+ hash: 29
125
+ segments:
126
+ - 1
127
+ - 2
128
+ - 1
129
+ version: 1.2.1
130
+ type: :runtime
131
+ version_requirements: *id007
132
+ - !ruby/object:Gem::Dependency
133
+ name: memcached
134
+ prerelease: false
135
+ requirement: &id008 !ruby/object:Gem::Requirement
136
+ none: false
137
+ requirements:
138
+ - - "="
139
+ - !ruby/object:Gem::Version
140
+ hash: 19
141
+ segments:
142
+ - 1
143
+ - 0
144
+ - 2
145
+ version: 1.0.2
146
+ type: :runtime
147
+ version_requirements: *id008
148
+ - !ruby/object:Gem::Dependency
149
+ name: mime-types
150
+ prerelease: false
151
+ requirement: &id009 !ruby/object:Gem::Requirement
152
+ none: false
153
+ requirements:
154
+ - - "="
155
+ - !ruby/object:Gem::Version
156
+ hash: 47
157
+ segments:
158
+ - 1
159
+ - 16
160
+ version: "1.16"
161
+ type: :runtime
162
+ version_requirements: *id009
163
+ - !ruby/object:Gem::Dependency
164
+ name: jsmin
165
+ prerelease: false
166
+ requirement: &id010 !ruby/object:Gem::Requirement
167
+ none: false
168
+ requirements:
169
+ - - "="
170
+ - !ruby/object:Gem::Version
171
+ hash: 21
172
+ segments:
173
+ - 1
174
+ - 0
175
+ - 1
176
+ version: 1.0.1
177
+ type: :runtime
178
+ version_requirements: *id010
179
+ - !ruby/object:Gem::Dependency
180
+ name: rspec
181
+ prerelease: false
182
+ requirement: &id011 !ruby/object:Gem::Requirement
183
+ none: false
184
+ requirements:
185
+ - - "="
186
+ - !ruby/object:Gem::Version
187
+ hash: 11
188
+ segments:
189
+ - 2
190
+ - 1
191
+ - 0
192
+ version: 2.1.0
193
+ type: :development
194
+ version_requirements: *id011
195
+ - !ruby/object:Gem::Dependency
196
+ name: steak
197
+ prerelease: false
198
+ requirement: &id012 !ruby/object:Gem::Requirement
199
+ none: false
200
+ requirements:
201
+ - - "="
202
+ - !ruby/object:Gem::Version
203
+ hash: 23
204
+ segments:
205
+ - 1
206
+ - 0
207
+ - 0
208
+ version: 1.0.0
209
+ type: :development
210
+ version_requirements: *id012
211
+ - !ruby/object:Gem::Dependency
212
+ name: capybara
213
+ prerelease: false
214
+ requirement: &id013 !ruby/object:Gem::Requirement
215
+ none: false
216
+ requirements:
217
+ - - "="
218
+ - !ruby/object:Gem::Version
219
+ hash: 15
220
+ segments:
221
+ - 0
222
+ - 4
223
+ - 0
224
+ version: 0.4.0
225
+ type: :development
226
+ version_requirements: *id013
227
+ description: Web page speed optimizations at the Rack level
228
+ email: julio@awesomebydesign.com
229
+ executables: []
230
+
231
+ extensions: []
232
+
233
+ extra_rdoc_files:
234
+ - README.md
235
+ files:
236
+ - Gemfile
237
+ - Gemfile.lock
238
+ - README.md
239
+ - Rakefile
240
+ - VERSION
241
+ - lib/rack-pagespeed.rb
242
+ - lib/rack/pagespeed.rb
243
+ - lib/rack/pagespeed/config.rb
244
+ - lib/rack/pagespeed/filters/all.rb
245
+ - lib/rack/pagespeed/filters/base.rb
246
+ - lib/rack/pagespeed/filters/combine_css.rb
247
+ - lib/rack/pagespeed/filters/combine_javascripts.rb
248
+ - lib/rack/pagespeed/filters/inline_css.rb
249
+ - lib/rack/pagespeed/filters/inline_javascripts.rb
250
+ - lib/rack/pagespeed/filters/minify_javascripts.rb
251
+ - lib/rack/pagespeed/store/all.rb
252
+ - lib/rack/pagespeed/store/disk.rb
253
+ - lib/rack/pagespeed/store/memcached.rb
254
+ - spec/config_spec.rb
255
+ - spec/filters/combine_css_spec.rb
256
+ - spec/filters/combine_javascripts_spec.rb
257
+ - spec/filters/filter_spec.rb
258
+ - spec/filters/inline_css_spec.rb
259
+ - spec/filters/inline_javascript_spec.rb
260
+ - spec/filters/minify_javascript_spec.rb
261
+ - spec/fixtures/complex.html
262
+ - spec/fixtures/foo.js
263
+ - spec/fixtures/hh-reset.css
264
+ - spec/fixtures/huge.css
265
+ - spec/fixtures/iphone.css
266
+ - spec/fixtures/jquery-1.4.1.min.js
267
+ - spec/fixtures/medialess1.css
268
+ - spec/fixtures/medialess2.css
269
+ - spec/fixtures/mylib.js
270
+ - spec/fixtures/noexternalcss.html
271
+ - spec/fixtures/noscripts.html
272
+ - spec/fixtures/ohno.js
273
+ - spec/fixtures/reset.css
274
+ - spec/fixtures/screen.css
275
+ - spec/fixtures/styles.html
276
+ - spec/fixtures/zecoolwebsite/css/awesomebydesign.css
277
+ - spec/fixtures/zecoolwebsite/css/reset.css
278
+ - spec/fixtures/zecoolwebsite/img/bg-idevice.png
279
+ - spec/fixtures/zecoolwebsite/img/bg.png
280
+ - spec/fixtures/zecoolwebsite/img/bottom-left-arrow.png
281
+ - spec/fixtures/zecoolwebsite/img/bottom-right-arrow.png
282
+ - spec/fixtures/zecoolwebsite/img/consulting-arrow.png
283
+ - spec/fixtures/zecoolwebsite/img/design-arrow.png
284
+ - spec/fixtures/zecoolwebsite/img/prototyping-arrow.png
285
+ - spec/fixtures/zecoolwebsite/img/top-left-arrow.png
286
+ - spec/fixtures/zecoolwebsite/img/top-right-arrow.png
287
+ - spec/fixtures/zecoolwebsite/img/webdev-arrow.png
288
+ - spec/fixtures/zecoolwebsite/index.html
289
+ - spec/fixtures/zecoolwebsite/js/awesomebydesign.js
290
+ - spec/fixtures/zecoolwebsite/js/jquery-1.4.2.min.js
291
+ - spec/fixtures/zecoolwebsite/js/modernizr-1.5.min.js
292
+ - spec/fixtures/zecoolwebsite/js/sayhi.js
293
+ - spec/integration/integration_spec.rb
294
+ - spec/pagespeed_spec.rb
295
+ - spec/spec_helper.rb
296
+ - spec/store/disk_spec.rb
297
+ - spec/store/memcached_spec.rb
298
+ has_rdoc: true
299
+ homepage: http://github.com/juliocesar/rack-pagespeed
300
+ licenses: []
301
+
302
+ post_install_message:
303
+ rdoc_options: []
304
+
305
+ require_paths:
306
+ - lib
307
+ required_ruby_version: !ruby/object:Gem::Requirement
308
+ none: false
309
+ requirements:
310
+ - - ">="
311
+ - !ruby/object:Gem::Version
312
+ hash: 3
313
+ segments:
314
+ - 0
315
+ version: "0"
316
+ required_rubygems_version: !ruby/object:Gem::Requirement
317
+ none: false
318
+ requirements:
319
+ - - ">="
320
+ - !ruby/object:Gem::Version
321
+ hash: 3
322
+ segments:
323
+ - 0
324
+ version: "0"
325
+ requirements: []
326
+
327
+ rubyforge_project:
328
+ rubygems_version: 1.3.7
329
+ signing_key:
330
+ specification_version: 3
331
+ summary: Web page speed optimizations at the Rack level
332
+ test_files:
333
+ - spec/config_spec.rb
334
+ - spec/filters/combine_css_spec.rb
335
+ - spec/filters/combine_javascripts_spec.rb
336
+ - spec/filters/filter_spec.rb
337
+ - spec/filters/inline_css_spec.rb
338
+ - spec/filters/inline_javascript_spec.rb
339
+ - spec/filters/minify_javascript_spec.rb
340
+ - spec/integration/integration_spec.rb
341
+ - spec/pagespeed_spec.rb
342
+ - spec/spec_helper.rb
343
+ - spec/store/disk_spec.rb
344
+ - spec/store/memcached_spec.rb