rack-combobot 0.0.3 → 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.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rack-combobot (0.0.2)
4
+ rack-combobot (0.0.3)
5
5
  rack
6
6
  rake
7
7
 
@@ -12,7 +12,7 @@ GEM
12
12
  guard (0.10.0)
13
13
  ffi (>= 0.5.0)
14
14
  thor (~> 0.14.6)
15
- guard-minitest (0.4.0)
15
+ guard-minitest (0.5.0)
16
16
  guard (~> 0.4)
17
17
  minitest (2.10.0)
18
18
  rack (1.4.0)
data/Guardfile CHANGED
@@ -1,6 +1,5 @@
1
1
  guard 'minitest' do
2
2
  watch(%r|^spec/(.*)_spec\.rb|)
3
- watch(%r|^lib/(.*)\.rb|) { |m| "spec/#{m[1]}_spec.rb" }
4
- watch(%r|^lib/rack/(.*)\.rb|) { |m| "spec/rack_#{m[1]}_spec.rb" }
5
- watch(%r|^spec/spec_helper\.rb|) { "spec" }
3
+ watch(%r|^lib/(.*)\.rb|) { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch(%r|^spec/spec_helper\.rb|) { "spec" }
6
5
  end
data/Rakefile CHANGED
@@ -7,7 +7,7 @@ require 'rake'
7
7
  require 'rake/testtask'
8
8
 
9
9
  Rake::TestTask.new do |t|
10
- t.pattern = "spec/*_spec.rb"
10
+ t.pattern = "spec/**/*_spec.rb"
11
11
  end
12
12
 
13
13
  task :default => [:test]
data/config.ru ADDED
@@ -0,0 +1,6 @@
1
+ require 'rack'
2
+ require './lib/rack-combobot'
3
+
4
+ use Rack::Combobot, :root => 'spec/public'
5
+
6
+ run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Dummy App"]] }
@@ -0,0 +1,33 @@
1
+ # encoding: UTF-8
2
+
3
+ module Rack
4
+ class Combobot
5
+ class Combination
6
+ def initialize(root, file_names)
7
+ @root = root
8
+
9
+ @file_contents = fetch_file_contents file_names if file_names
10
+ end
11
+
12
+ def fetch_file_contents(file_names = [])
13
+ file_names.map do |file_name|
14
+
15
+ raise PathError if file_name.include?('..') || file_name.include?("~")
16
+
17
+ root_prefix = ::File.expand_path(".", @root) + "/"
18
+ file_path = ::File.expand_path(file_name, @root)
19
+
20
+ raise PathError unless file_path.start_with?(root_prefix) && ::File.exist?(file_path)
21
+
22
+ file_content = ::File.open(file_path, 'r') { |f| f.read }
23
+ end
24
+ end
25
+
26
+ def combine
27
+ @combo ||= @file_contents.join
28
+ end
29
+
30
+ class PathError < ArgumentError; end
31
+ end
32
+ end
33
+ end
data/lib/rack/combobot.rb CHANGED
@@ -1,32 +1,45 @@
1
+ # encoding: UTF-8
2
+
1
3
  require "rack/combobot/config"
4
+ require "rack/combobot/combination"
2
5
  require "pathname"
3
6
  require "uri"
4
7
 
5
8
  module Rack
6
9
  class Combobot
7
- def self.configure(*args)
8
- new(*args)
9
- end
10
10
 
11
11
  MIME_TYPES = {
12
12
  "js" => "text/javascript",
13
13
  "css" => "text/css"
14
14
  }
15
15
 
16
- def initialize(options = {})
16
+ def initialize(app, options = {})
17
+ @app = app
18
+
17
19
  root = Pathname.new(options[:root] || Dir.pwd)
18
20
  @config = Rack::Combobot::Config.new(root)
19
21
  end
20
22
 
21
23
  # rack request handler
22
24
  def call(env)
25
+ if Rack::Request.new(env).path == '/combobot'
26
+ combine(env)
27
+ else
28
+ @app.call(env)
29
+ end
30
+ end
31
+
32
+ def combine(env)
23
33
  params = env["QUERY_STRING"]
24
34
  file_names = params.split("&")
25
- extention = file_names[0].split(".").last
35
+
36
+ return not_found if file_names.empty?
37
+
38
+ extension = file_names[0].split(".").last
26
39
 
27
40
  begin
28
41
  combo = Combination.new(@config.root, file_names).combine
29
- [200, {"Content-Type" => MIME_TYPES[extention]}, [combo]]
42
+ [200, {"Content-Type" => MIME_TYPES[extension]}, [combo]]
30
43
  rescue Combination::PathError
31
44
  not_found
32
45
  end
@@ -36,30 +49,5 @@ module Rack
36
49
  [404, {'Content-Type' => 'text/html'}, ['File not found']]
37
50
  end
38
51
 
39
- class Combination
40
- def initialize(root, file_names)
41
- @file_contents = combine_files(root, file_names)
42
- end
43
-
44
- def combine_files(root, file_names = [])
45
- file_names.map do |file_name|
46
-
47
- raise PathError if file_name.include?('..') || file_name.include?("~")
48
-
49
- root_prefix = ::File.expand_path(".", root) + "/"
50
- file_path = ::File.expand_path(file_name, root)
51
-
52
- raise PathError unless file_path.start_with?(root_prefix) && ::File.exist?(file_path)
53
-
54
- file_content = ::File.open(file_path, 'r') { |f| f.read }
55
- end
56
- end
57
-
58
- def combine
59
- @combo ||= @file_contents.join
60
- end
61
-
62
- class PathError < ArgumentError; end
63
- end
64
52
  end
65
53
  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.0.3"
7
+ s.version = "0.1.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"
@@ -0,0 +1,41 @@
1
+ require File.dirname(__FILE__) + '/../../../spec_helper'
2
+
3
+ describe Rack::Combobot::Combination do
4
+
5
+ let(:combination) { Rack::Combobot::Combination.new(File.dirname(__FILE__) + '/../../../public', ['js1.js', 'js2.js']) }
6
+
7
+ describe 'fetch' do
8
+
9
+ it 'fetches files content' do
10
+ contents = combination.fetch_file_contents(['js1.js', 'js2.js'])
11
+ contents.must_equal(["function lorem() { return \"a\"; }\n", "function ipsum() { return \"b\"; }\n"])
12
+ end
13
+
14
+ describe 'error handling' do
15
+ it 'raises PathError when files are not found' do
16
+ proc {
17
+ combination.fetch_file_contents(['js3.js'])
18
+ }.must_raise Rack::Combobot::Combination::PathError
19
+ end
20
+
21
+ it 'raises PathError when trying to move outside the root' do
22
+ proc {
23
+ combination.fetch_file_contents(['js1.js', '../../etc/hosts'])
24
+ }.must_raise Rack::Combobot::Combination::PathError
25
+ end
26
+ end
27
+ end
28
+
29
+ describe 'combination' do
30
+
31
+ before do
32
+ combination.fetch_file_contents(['js1.js', 'js2.js'])
33
+ end
34
+
35
+ it 'combines file content' do
36
+ combination.combine.must_equal("function lorem() { return \"a\"; }\nfunction ipsum() { return \"b\"; }\n")
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,49 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Rack::Combobot do
4
+ include Rack::Test::Methods
5
+
6
+ # the dummy app represents any other middleware in the rack stack
7
+ let(:dummy_app_response) { [200, {"Content-Type" => "text/html"}, ["Dummy App"]] }
8
+ let(:dummy_app) { Proc.new {|env| dummy_app_response } }
9
+
10
+ before do
11
+ @app = Rack::Combobot.new(dummy_app, :root => File.dirname(__FILE__) + '/../../public')
12
+ end
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" }) }
22
+
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']] }
27
+
28
+ it 'should not respond to anything other than "/combobot"' do
29
+ @app.call({}).must_equal(dummy_app_response)
30
+ end
31
+
32
+ it "combines javascript" do
33
+ @app.call(combobot_js_request).must_equal(combobot_js_response)
34
+ end
35
+
36
+ it "combines css" do
37
+ @app.call(combobot_css_request).must_equal(combobot_css_response)
38
+ end
39
+
40
+ it "returns 404 when it can't find files" do
41
+ @app.call(combobot_404_request).must_equal(combobot_404_response)
42
+ end
43
+
44
+ it 'returns 404 when trying to move up from the root dir' do
45
+ @app.call(combobot_hack_request).must_equal(combobot_404_response)
46
+ end
47
+ end
48
+
49
+ 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.0.3
4
+ version: 0.1.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-09 00:00:00.000000000 Z
13
+ date: 2012-03-14 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
17
- requirement: &2154066720 !ruby/object:Gem::Requirement
17
+ requirement: &2153707180 !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: *2154066720
25
+ version_requirements: *2153707180
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rack
28
- requirement: &2154066280 !ruby/object:Gem::Requirement
28
+ requirement: &2153706740 !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: *2154066280
36
+ version_requirements: *2153706740
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: minitest
39
- requirement: &2154065860 !ruby/object:Gem::Requirement
39
+ requirement: &2153706320 !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: *2154065860
47
+ version_requirements: *2153706320
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: rack-test
50
- requirement: &2154065440 !ruby/object:Gem::Requirement
50
+ requirement: &2153705900 !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: *2154065440
58
+ version_requirements: *2153705900
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: guard
61
- requirement: &2154065020 !ruby/object:Gem::Requirement
61
+ requirement: &2153705480 !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: *2154065020
69
+ version_requirements: *2153705480
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: guard-minitest
72
- requirement: &2154064600 !ruby/object:Gem::Requirement
72
+ requirement: &2153705060 !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: *2154064600
80
+ version_requirements: *2153705060
81
81
  description: combines assets to server 1 file
82
82
  email:
83
83
  - r.hackr@gmail.com
@@ -94,15 +94,18 @@ files:
94
94
  - Guardfile
95
95
  - README.md
96
96
  - Rakefile
97
+ - config.ru
97
98
  - lib/rack-combobot.rb
98
99
  - lib/rack/combobot.rb
100
+ - lib/rack/combobot/combination.rb
99
101
  - lib/rack/combobot/config.rb
100
102
  - rack-combobot.gemspec
103
+ - spec/lib/rack/combobot/combination_spec.rb
104
+ - spec/lib/rack/combobot_spec.rb
101
105
  - spec/public/css1.css
102
106
  - spec/public/css2.css
103
107
  - spec/public/js1.js
104
108
  - spec/public/js2.js
105
- - spec/rack_combobot_spec.rb
106
109
  - spec/spec_helper.rb
107
110
  homepage: https://github.com/hojberg/rack-combobot
108
111
  licenses: []
@@ -129,9 +132,10 @@ signing_key:
129
132
  specification_version: 3
130
133
  summary: asset combinator
131
134
  test_files:
135
+ - spec/lib/rack/combobot/combination_spec.rb
136
+ - spec/lib/rack/combobot_spec.rb
132
137
  - spec/public/css1.css
133
138
  - spec/public/css2.css
134
139
  - spec/public/js1.js
135
140
  - spec/public/js2.js
136
- - spec/rack_combobot_spec.rb
137
141
  - spec/spec_helper.rb
@@ -1,50 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
2
-
3
- describe "combing assets from query string" do
4
- include Rack::Test::Methods
5
-
6
- before(:each) do
7
- @app = Rack::Combobot.configure(:root => File.dirname(__FILE__) + '/public')
8
- end
9
-
10
- it "combines javascript" do
11
- @app.call({
12
- "QUERY_STRING" => "js1.js&js2.js"
13
- }).must_equal([
14
- 200,
15
- {"Content-Type" => "text/javascript"},
16
- ["function lorem() { return \"a\"; }\nfunction ipsum() { return \"b\"; }\n"]
17
- ])
18
- end
19
-
20
- it "combines css" do
21
- @app.call({
22
- "QUERY_STRING" => "css1.css&css2.css"
23
- }).must_equal([
24
- 200,
25
- {"Content-Type" => "text/css"},
26
- [".lorem { background: blue; }\n#lipsum { border: 1px solid red }\n"]
27
- ])
28
- end
29
-
30
- it "returns 404 when it can't find files" do
31
- @app.call({
32
- "QUERY_STRING" => "js3.js&js4.js"
33
- }).must_equal([
34
- 404,
35
- {'Content-Type' => 'text/html'},
36
- ['File not found']
37
- ])
38
- end
39
-
40
- it 'returns 404 when trying to move up from the root dir' do
41
- @app.call({
42
- "QUERY_STRING" => "js3.js&../../js4.js"
43
- }).must_equal([
44
- 404,
45
- {'Content-Type' => 'text/html'},
46
- ['File not found']
47
- ])
48
- end
49
-
50
- end