rack-combobot 0.1.0 → 0.2.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.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