rack-combobot 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rack-combobot (0.0.3)
4
+ rack-combobot (0.2.0)
5
5
  rack
6
6
  rake
7
7
 
data/README.md CHANGED
@@ -6,10 +6,35 @@ Asset combinator for rack
6
6
 
7
7
  `gem install rack-combobot`
8
8
 
9
+ ## Path
10
+
11
+ Point your frontend to `/combobot?script1.js&script2.js` to get script1.js and script2.js combined.
12
+
13
+ ### Usage in Rack apps (config.ru)
14
+
15
+ ```ruby
16
+ require 'rack'
17
+ require 'rack-combobot'
18
+ require 'my-app'
19
+
20
+ use Rack::Combobot, :root => '/public'
21
+ run MyApp
22
+ ```
23
+
9
24
  ### Usage in Rails apps
10
25
 
11
- In your routes.rb file add the following route
26
+ In your config/application.rb
12
27
 
13
28
  ```ruby
14
- match '/combobot', :to => Rack::Combobot.configure(:root => RAILS_ROOT + "/public")
29
+ config.middleware.use 'Rack::Combobot', :root => "#{Rails.root}/public"
15
30
  ```
31
+
32
+ ### Expires header
33
+
34
+ Add expires header by like so
35
+
36
+ ```ruby
37
+ config.middleware.use 'Rack::Combobot', :root => "#{Rails.root}/public", :expires => Time.gm(2020)
38
+ ```
39
+
40
+ To bust the cache, simple add a unique string to your request like so `/combobot/BUSTINGSRING?script1.js&script2.js`.
data/lib/rack/combobot.rb CHANGED
@@ -8,6 +8,8 @@ require "uri"
8
8
  module Rack
9
9
  class Combobot
10
10
 
11
+ attr_reader :config
12
+
11
13
  MIME_TYPES = {
12
14
  "js" => "text/javascript",
13
15
  "css" => "text/css"
@@ -17,12 +19,13 @@ module Rack
17
19
  @app = app
18
20
 
19
21
  root = Pathname.new(options[:root] || Dir.pwd)
20
- @config = Rack::Combobot::Config.new(root)
22
+ expires = options[:expires]
23
+ @config = Rack::Combobot::Config.new(root, expires)
21
24
  end
22
25
 
23
26
  # rack request handler
24
27
  def call(env)
25
- if Rack::Request.new(env).path == '/combobot'
28
+ if Rack::Request.new(env).path =~ /^\/combobot/
26
29
  combine(env)
27
30
  else
28
31
  @app.call(env)
@@ -35,16 +38,27 @@ module Rack
35
38
 
36
39
  return not_found if file_names.empty?
37
40
 
38
- extension = file_names[0].split(".").last
41
+ extension = file_names[0].split(".").last
42
+ headers = create_headers(extension)
39
43
 
40
44
  begin
41
45
  combo = Combination.new(@config.root, file_names).combine
42
- [200, {"Content-Type" => MIME_TYPES[extension]}, [combo]]
46
+ [200, headers, [combo]]
43
47
  rescue Combination::PathError
44
48
  not_found
45
49
  end
46
50
  end
47
51
 
52
+ def create_headers(extension)
53
+ headers = {"Content-Type" => MIME_TYPES[extension]}
54
+
55
+ if @config.expires
56
+ headers['Expires'] = @config.expires.httpdate
57
+ end
58
+
59
+ headers
60
+ end
61
+
48
62
  def not_found
49
63
  [404, {'Content-Type' => 'text/html'}, ['File not found']]
50
64
  end
@@ -1,18 +1,13 @@
1
1
  module Rack
2
2
  class Combobot
3
3
  class Config
4
- def initialize(root)
5
- @cache = []
4
+ attr_accessor :root, :expires
5
+
6
+ def initialize(root, expires = nil)
6
7
  @root = root
8
+ @expires = expires
7
9
  end
8
10
 
9
- def cache(*names)
10
- @cache.concat(names)
11
- end
12
-
13
- def root
14
- @root
15
- end
16
11
  end
17
12
  end
18
13
  end
@@ -4,7 +4,7 @@ $:.push File.expand_path("../lib", __FILE__)
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "rack-combobot"
7
- s.version = "0.1.0"
7
+ s.version = "0.2.0"
8
8
  s.authors = ["Simon Højberg", "Christopher Meiklejohn"]
9
9
  s.email = ["r.hackr@gmail.com", "christopher.meiklejohn@gmail.com"]
10
10
  s.homepage = "https://github.com/hojberg/rack-combobot"
@@ -11,24 +11,26 @@ describe Rack::Combobot do
11
11
  @app = Rack::Combobot.new(dummy_app, :root => File.dirname(__FILE__) + '/../../public')
12
12
  end
13
13
 
14
- describe 'routing' do
15
-
16
- # request helpers
17
- let(:combobot_request) { { 'PATH_INFO' => '/combobot' } }
18
- let(:combobot_js_request) { combobot_request.merge({ "QUERY_STRING" => "js1.js&js2.js" }) }
19
- let(:combobot_css_request) { combobot_request.merge({ "QUERY_STRING" => "css1.css&css2.css" }) }
20
- let(:combobot_404_request) { combobot_request.merge({ "QUERY_STRING" => "js3.js&js4.js" }) }
21
- let(:combobot_hack_request) { combobot_request.merge({ "QUERY_STRING" => "js3.js&../../js4.js" }) }
14
+ # request helpers
15
+ let(:combobot_request) { { 'PATH_INFO' => '/combobot' } }
16
+ let(:combobot_js_request) { combobot_request.merge({ "QUERY_STRING" => "js1.js&js2.js" }) }
17
+ let(:combobot_css_request) { combobot_request.merge({ "QUERY_STRING" => "css1.css&css2.css" }) }
18
+ let(:combobot_404_request) { combobot_request.merge({ "QUERY_STRING" => "js3.js&js4.js" }) }
19
+ let(:combobot_hack_request) { combobot_request.merge({ "QUERY_STRING" => "js3.js&../../js4.js" }) }
22
20
 
23
- # response helpers
24
- let(:combobot_js_response) { [200, {"Content-Type" => "text/javascript"}, ["function lorem() { return \"a\"; }\nfunction ipsum() { return \"b\"; }\n"]] }
25
- let(:combobot_css_response) { [200, {"Content-Type" => "text/css"}, [".lorem { background: blue; }\n#lipsum { border: 1px solid red }\n"]] }
26
- let(:combobot_404_response) { [404, {'Content-Type' => 'text/html'}, ['File not found']] }
21
+ # response helpers
22
+ let(:combobot_js_response) { [200, {"Content-Type" => "text/javascript"}, ["function lorem() { return \"a\"; }\nfunction ipsum() { return \"b\"; }\n"]] }
23
+ let(:expires_js_response) { [200, {"Content-Type" => "text/javascript", 'Expires' => 'Wed, 01 Jan 2020 00:00:00 GMT'}, ["function lorem() { return \"a\"; }\nfunction ipsum() { return \"b\"; }\n"]] }
24
+ let(:combobot_css_response) { [200, {"Content-Type" => "text/css"}, [".lorem { background: blue; }\n#lipsum { border: 1px solid red }\n"]] }
25
+ let(:combobot_404_response) { [404, {'Content-Type' => 'text/html'}, ['File not found']] }
27
26
 
27
+ describe 'routing' do
28
28
  it 'should not respond to anything other than "/combobot"' do
29
29
  @app.call({}).must_equal(dummy_app_response)
30
30
  end
31
+ end
31
32
 
33
+ describe 'combination' do
32
34
  it "combines javascript" do
33
35
  @app.call(combobot_js_request).must_equal(combobot_js_response)
34
36
  end
@@ -36,7 +38,9 @@ describe Rack::Combobot do
36
38
  it "combines css" do
37
39
  @app.call(combobot_css_request).must_equal(combobot_css_response)
38
40
  end
41
+ end
39
42
 
43
+ describe 'error handling' do
40
44
  it "returns 404 when it can't find files" do
41
45
  @app.call(combobot_404_request).must_equal(combobot_404_response)
42
46
  end
@@ -46,4 +50,22 @@ describe Rack::Combobot do
46
50
  end
47
51
  end
48
52
 
53
+ describe 'caching' do
54
+
55
+ it 'adds expires headers' do
56
+ @app.config.expires = Time.gm(2020)
57
+ @app.call(combobot_js_request).must_equal(expires_js_response)
58
+ end
59
+
60
+ it 'allows for versioning' do
61
+ @app.call(
62
+ combobot_js_request.merge({ 'PATH_INFO' => '/combobot/CACHEBUSTINGSHA1'})
63
+ ).must_equal(combobot_js_response)
64
+
65
+ @app.call(
66
+ combobot_js_request.merge({ 'PATH_INFO' => '/combobot/CACHEBUSTINGSHA2'})
67
+ ).must_equal(combobot_js_response)
68
+ end
69
+ end
70
+
49
71
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-combobot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-03-14 00:00:00.000000000 Z
13
+ date: 2012-03-21 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
17
- requirement: &2153707180 !ruby/object:Gem::Requirement
17
+ requirement: &2156803500 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *2153707180
25
+ version_requirements: *2156803500
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rack
28
- requirement: &2153706740 !ruby/object:Gem::Requirement
28
+ requirement: &2156803060 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *2153706740
36
+ version_requirements: *2156803060
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: minitest
39
- requirement: &2153706320 !ruby/object:Gem::Requirement
39
+ requirement: &2156802640 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: '0'
45
45
  type: :development
46
46
  prerelease: false
47
- version_requirements: *2153706320
47
+ version_requirements: *2156802640
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: rack-test
50
- requirement: &2153705900 !ruby/object:Gem::Requirement
50
+ requirement: &2156802220 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: '0'
56
56
  type: :development
57
57
  prerelease: false
58
- version_requirements: *2153705900
58
+ version_requirements: *2156802220
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: guard
61
- requirement: &2153705480 !ruby/object:Gem::Requirement
61
+ requirement: &2156801800 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: '0'
67
67
  type: :development
68
68
  prerelease: false
69
- version_requirements: *2153705480
69
+ version_requirements: *2156801800
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: guard-minitest
72
- requirement: &2153705060 !ruby/object:Gem::Requirement
72
+ requirement: &2156801380 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ! '>='
@@ -77,7 +77,7 @@ dependencies:
77
77
  version: '0'
78
78
  type: :development
79
79
  prerelease: false
80
- version_requirements: *2153705060
80
+ version_requirements: *2156801380
81
81
  description: combines assets to server 1 file
82
82
  email:
83
83
  - r.hackr@gmail.com