hobbit-contrib 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 099f376fda08a626af17438fbf1e3642602ace9c
4
- data.tar.gz: 2eb4379e2612f064b90b7d0b6d9d0d02fc043a28
3
+ metadata.gz: b7f3320b3437d3168749e5581b999a443a48e001
4
+ data.tar.gz: 4cc4a32c36aeb3068cfc17aca524be92ecbee78d
5
5
  SHA512:
6
- metadata.gz: 6d571097bd56bc82f5d2602875df361b7dc00b4ac843482aa178c6ff5e0c24010ffe930eadab8b34ffeed950c7a16b833b436b513c3b55839a9539a758d8dc12
7
- data.tar.gz: a682e80b5c624d83fda243403484dfed7837a3f0e8c834b24941b0033bedec2c0565cfc8a579f7f619c3a8cb9f9213d21a1aeed2b8220be00b934ec0f22fcca3
6
+ metadata.gz: a3464d83f2d94c32c9a32d29afa4a5a7548539d9fa00876ba20b9301b43b306aa4b56f219b4854006fb9f50b96963634a586eedcff26825eeb49e67c9c2b9c39
7
+ data.tar.gz: 0248e6223440165e6f2c0efe3ab91ea95c50c3af3c67496d4061edce43a866c7607a4b86da1008b45cffa9ab8ab76af3139da33ceeb60bf96b0136ba8d5223e1
data/README.md CHANGED
@@ -1,7 +1,4 @@
1
- # Hobbit::Contrib
2
-
3
- [![Build Status](https://travis-ci.org/patriciomacadden/hobbit-contrib.png?branch=master)](https://travis-ci.org/patriciomacadden/hobbit-contrib)
4
- [![Code Climate](https://codeclimate.com/github/patriciomacadden/hobbit-contrib.png)](https://codeclimate.com/github/patriciomacadden/hobbit-contrib)
1
+ # Hobbit::Contrib [![Build Status](https://travis-ci.org/patriciomacadden/hobbit-contrib.png?branch=master)](https://travis-ci.org/patriciomacadden/hobbit-contrib) [![Code Climate](https://codeclimate.com/github/patriciomacadden/hobbit-contrib.png)](https://codeclimate.com/github/patriciomacadden/hobbit-contrib) [![Coverage Status](https://coveralls.io/repos/patriciomacadden/hobbit-contrib/badge.png?branch=master)](https://coveralls.io/r/patriciomacadden/hobbit-contrib) [![Dependency Status](https://gemnasium.com/patriciomacadden/hobbit-contrib.png)](https://gemnasium.com/patriciomacadden/hobbit-contrib) [![Gem Version](https://badge.fury.io/rb/hobbit-contrib.png)](http://badge.fury.io/rb/hobbit-contrib)
5
2
 
6
3
  Contributed Hobbit extensions.
7
4
 
@@ -29,20 +26,98 @@ $ gem install hobbit-contrib
29
26
 
30
27
  ## Usage
31
28
 
32
- Each extension may have its own usage. In general, including (or extending) the
33
- module will be enough.
29
+ Each extension may have its own usage. In general, including the module will be
30
+ enough.
34
31
 
35
32
  ```ruby
36
33
  require 'hobbit'
37
34
  require 'hobbit/contrib'
38
35
 
39
36
  class App < Hobbit::Base
37
+ # include hobbit session extension
38
+ include Hobbit::Session
39
+
40
40
  # define your application
41
41
  end
42
42
  ```
43
43
 
44
44
  ## Available extensions
45
45
 
46
+ ### Hobbit::AssetTag
47
+
48
+ This module allows you to include images, javascripts and stylesheets in a easy
49
+ way. To use this extension just include the module:
50
+
51
+ In `config.ru`:
52
+
53
+ ```ruby
54
+ require 'hobbit'
55
+ require 'hobbit/contrib'
56
+
57
+ class App < Hobbit::Base
58
+ # Put your assets in:
59
+ # * public/images
60
+ # * public/javascripts
61
+ # * public/stylesheets
62
+ use Rack::Static, root: 'public', urls: ['/images', '/javascripts', '/stylesheets']
63
+ include Hobbit::AssetTag
64
+ include Hobbit::EnhancedRender # see below
65
+
66
+ get '/' do
67
+ render 'index', {}, layout: 'layout'
68
+ end
69
+ end
70
+
71
+ run App.new
72
+ ```
73
+
74
+ in `views/layouts/layout.erb`:
75
+
76
+ ```ruby
77
+ <!DOCTYPE html>
78
+ <html>
79
+ <head>
80
+ <title>Hobbit::AssetTag</title>
81
+ <!--
82
+ becomes:
83
+ <script src="http://code.jquery.com/jquery-2.0.0.min.js" type="text/javascript"></script>
84
+ <script src="/javascripts/application.js" type="text/javascript"></script>
85
+ -->
86
+ <%= javascript 'http://code.jquery.com/jquery-2.0.0.min.js', 'application' %>
87
+ <!--
88
+ becomes:
89
+ <link href="/stylesheets/application.css" rel="stylesheet"/>
90
+ -->
91
+ <%= stylesheet 'application' %>
92
+ </head>
93
+ <body>
94
+ <%= yield %>
95
+ </body>
96
+ </html>
97
+ ```
98
+
99
+ and in `views/index.erb`:
100
+
101
+ ```ruby
102
+ <h1>Hobbit::AssetTag</h1>
103
+ <!-- becomes: /images/some-hobbit.png -->
104
+ <img src="<%= image_path 'some-hobbit.png' %>"/>
105
+ ```
106
+
107
+ #### Available methods
108
+
109
+ * `image_path`: Returns the path for a given image.
110
+ * `javascript`: Returns a list of one or more script tags (see the example
111
+ above).
112
+ * `javascript_path`: Returns the path for a given javascript file. If you pass
113
+ an url, it returns the given url. If you pass an arbitrary string, it returns
114
+ `/javascripts/#{url}.js`.
115
+ * `stylesheet`: Returns a list of one or more link tags (see the example
116
+ above).
117
+ * `stylesheet_path`: Returns the path for a given stylesheet file. If you pass
118
+ an url, it returns the given url. If you pass an arbitrary string, it returns
119
+ `/stylesheets/#{url}.css`.
120
+
46
121
  ### Hobbit::EnhancedRender
47
122
 
48
123
  This module extends the functionality of `Hobbit::Render`. To use this extension
@@ -78,6 +153,159 @@ views path, except that the template name will start with an underscore. For
78
153
  instance, if you call `partial 'partial'`, the path will become
79
154
  `views/_partial.erb`
80
155
 
156
+ ### Hobbit::Environment
157
+
158
+ This extension allows you to control the application environment by using the
159
+ provided methods. To use this extension just include the module:
160
+
161
+ ```ruby
162
+ require 'hobbit'
163
+ require 'hobbit/contrib'
164
+
165
+ class App < Hobbit::Base
166
+ include Hobbit::Environment
167
+
168
+ get '/' do
169
+ "currently in #{environment}"
170
+ end
171
+ end
172
+
173
+ run App.new
174
+ ```
175
+
176
+ #### Available methods
177
+
178
+ * `environment`: Returns the current environment. By default is
179
+ `ENV['RACK_ENV']`.
180
+ * `environment=()`: Sets the environment.
181
+ * `development?`: Returns true if the current environment is `:development`.
182
+ * `production?`: Returns true if the current environment is `:production`.
183
+ * `test?`: Returns true if the current environment is `:test`.
184
+
185
+ ### Hobbit::ErrorHandling
186
+
187
+ This extension provides a way of handling errors raised by your application. To
188
+ use this extension just include the module:
189
+
190
+ ```ruby
191
+ require 'hobbit'
192
+ require 'hobbit/contrib'
193
+
194
+ class App < Hobbit::Base
195
+ include Hobbit::ErrorHandling
196
+
197
+ error Exception do |exception|
198
+ exception.message
199
+ end
200
+
201
+ get '/' do
202
+ raise Exception, 'Oops'
203
+ end
204
+ end
205
+
206
+ run App.new
207
+ ```
208
+
209
+ #### Available methods
210
+
211
+ * `errors`: Returns a hash with the exceptions being handled and its
212
+ corresponding handler.
213
+ * `error`: Sets a handler for a given exception.
214
+
215
+ **Note**: If you define more than one handler per exception the last one
216
+ defined will have precedence over the others.
217
+
218
+ ### Hobbit::Filter
219
+
220
+ This extension provides a way of calling blocks before and after the
221
+ evaluation of a route (just like sinatra's filters). To use this extension just
222
+ include the module:
223
+
224
+ ```ruby
225
+ require 'hobbit'
226
+ require 'hobbit/contrib'
227
+
228
+ class App < Hobbit::Base
229
+ include Hobbit::Filter
230
+
231
+ def authenticate_user!
232
+ # ...
233
+ end
234
+
235
+ before do
236
+ authenticate_user!
237
+ end
238
+
239
+ get '/' do
240
+ # ...
241
+ end
242
+ end
243
+
244
+ run App.new
245
+ ```
246
+
247
+ #### Available methods
248
+
249
+ * `after`: Sets an after filter. Optionally, you can specify a route.
250
+ * `before`: Sets a before filter. Optionally, you can specify a route.
251
+
252
+ **Note**: It is recommended to include `Hobbit::Filter` before
253
+ `Hobbit::ErrorHandling` if you want to use both extensions.
254
+
255
+ ### Hobbit::Render
256
+
257
+ This module provides rendering to your hobbit application. To use this
258
+ extension just include the module:
259
+
260
+ ```ruby
261
+ require 'hobbit'
262
+ require 'hobbit/contrib'
263
+
264
+ class App < Hobbit::Base
265
+ include Hobbit::Render
266
+
267
+ get '/' do
268
+ render 'views/index.erb'
269
+ end
270
+
271
+ get '/with-layout' do
272
+ render 'views/layout.erb' do
273
+ render 'views/index.erb'
274
+ end
275
+ end
276
+ end
277
+ ```
278
+
279
+ #### Available methods
280
+
281
+ * `render`: Renders the given template using tilt.
282
+
283
+ ### Hobbit::Session
284
+
285
+ This module provides helper methods for handling user sessions. To use this
286
+ extension just include the module:
287
+
288
+ ```ruby
289
+ require 'hobbit'
290
+ require 'hobbit/contrib'
291
+
292
+ class App < Hobbit::Base
293
+ include Hobbit::Session
294
+
295
+ post '/' do
296
+ session[:name] = 'hobbit'
297
+ end
298
+
299
+ get '/' do
300
+ "Hello #{session[:name]}!"
301
+ end
302
+ end
303
+ ```
304
+
305
+ #### Available methods
306
+
307
+ * `session`: Returns the user's session.
308
+
81
309
  ## Contributing
82
310
 
83
311
  1. Fork it
@@ -18,10 +18,14 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency 'hobbit'
22
-
23
21
  spec.add_development_dependency 'bundler', '~> 1.3'
22
+ spec.add_development_dependency 'coveralls'
23
+ spec.add_development_dependency 'hobbit'
24
24
  spec.add_development_dependency 'minitest'
25
25
  spec.add_development_dependency 'rack-test'
26
26
  spec.add_development_dependency 'rake'
27
+ spec.add_development_dependency 'tilt'
28
+
29
+ spec.add_runtime_dependency 'hobbit'
30
+ spec.add_runtime_dependency 'tilt'
27
31
  end
@@ -0,0 +1,23 @@
1
+ module Hobbit
2
+ module AssetTag
3
+ def image_path(url)
4
+ url =~ /^https?:\/\// ? url : "/images/#{url}"
5
+ end
6
+
7
+ def javascript(*urls)
8
+ urls.map { |url| "<script src=\"#{javascript_path url}\" type=\"text/javascript\"></script>" }.join
9
+ end
10
+
11
+ def javascript_path(url)
12
+ url =~ /^https?:\/\// ? url : "/javascripts/#{url}.js"
13
+ end
14
+
15
+ def stylesheet(*urls)
16
+ urls.map { |url| "<link href=\"#{stylesheet_path url}\" rel=\"stylesheet\"/>" }.join
17
+ end
18
+
19
+ def stylesheet_path(url)
20
+ url =~ /^http(s)?:\/\// ? url : "/stylesheets/#{url}.css"
21
+ end
22
+ end
23
+ end
@@ -1,5 +1,5 @@
1
1
  module Hobbit
2
2
  module Contrib
3
- VERSION = '0.0.1'
3
+ VERSION = '0.1.0'
4
4
  end
5
5
  end
@@ -1,2 +1,8 @@
1
+ require 'hobbit/asset_tag'
1
2
  require 'hobbit/contrib/version'
2
3
  require 'hobbit/enhanced_render'
4
+ require 'hobbit/environment'
5
+ require 'hobbit/error_handling'
6
+ require 'hobbit/filter'
7
+ require 'hobbit/render'
8
+ require 'hobbit/session'
@@ -27,7 +27,7 @@ module Hobbit
27
27
  end
28
28
 
29
29
  def view_path(template)
30
- "views/#{template}.erb"
30
+ "views/#{template}.#{template_engine}"
31
31
  end
32
32
  end
33
33
  end
@@ -0,0 +1,15 @@
1
+ module Hobbit
2
+ module Environment
3
+ def environment
4
+ self.class.settings[:environment] || ENV['RACK_ENV'].to_sym
5
+ end
6
+
7
+ def environment=(environment)
8
+ self.class.settings[:environment] = environment.to_sym
9
+ end
10
+
11
+ %w(development production test).each do |environment|
12
+ define_method("#{environment}?") { self.class.settings[:environment] == environment.to_sym }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,25 @@
1
+ module Hobbit
2
+ module ErrorHandling
3
+ module ClassMethods
4
+ def error(exception, &block)
5
+ errors[exception] = block
6
+ end
7
+
8
+ def errors
9
+ @errors ||= Hash.new
10
+ end
11
+ end
12
+
13
+ def _call(env)
14
+ super
15
+ rescue Exception => e
16
+ body = instance_eval { self.class.errors[e.class].call(e) }
17
+ response.body = [body] if self.class.errors.include? e.class
18
+ response.finish
19
+ end
20
+
21
+ def self.included(othermod)
22
+ othermod.extend ClassMethods
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,54 @@
1
+ module Hobbit
2
+ module Filter
3
+ module ClassMethods
4
+ %w(after before).each do |kind|
5
+ define_method(kind) { |path = '', &block| filters[kind.to_sym] << compile_filter!(path, &block) }
6
+ end
7
+
8
+ def filters
9
+ @filters ||= Hash.new { |hash, key| hash[key] = [] }
10
+ end
11
+
12
+ private
13
+
14
+ def compile_filter!(path, &block)
15
+ filter = { block: block, compiled_path: nil, extra_params: [], path: path }
16
+
17
+ compiled_path = path.gsub(/:\w+/) do |match|
18
+ filter[:extra_params] << match.gsub(':', '').to_sym
19
+ '([^/?#]+)'
20
+ end
21
+ filter[:compiled_path] = /^#{compiled_path}$/
22
+
23
+ filter
24
+ end
25
+ end
26
+
27
+ def _call(env)
28
+ @env = env
29
+ @request = self.class.settings[:request_class].new(@env)
30
+ @response = self.class.settings[:response_class].new
31
+ filter!(:before)
32
+ super
33
+ filter!(:after)
34
+ @response.finish
35
+ end
36
+
37
+ def self.included(othermod)
38
+ othermod.extend ClassMethods
39
+ end
40
+
41
+ private
42
+
43
+ def filter!(kind)
44
+ filter = self.class.filters[kind].detect { |f| f[:compiled_path] =~ request.path_info || f[:path] =~ // }
45
+ if filter
46
+ $~.captures.each_with_index do |value, index|
47
+ param = filter[:extra_params][index]
48
+ request.params[param] = value
49
+ end
50
+ instance_eval(&filter[:block])
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,17 @@
1
+ require 'tilt'
2
+
3
+ module Hobbit
4
+ module Render
5
+ def render(template, locals = {}, options = {}, &block)
6
+ cache.fetch(template) do
7
+ Tilt.new(template, options)
8
+ end.render(self, locals, &block)
9
+ end
10
+
11
+ private
12
+
13
+ def cache
14
+ Thread.current[:cache] ||= Tilt::Cache.new
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ module Hobbit
2
+ module Session
3
+ def session
4
+ env['rack.session']
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,84 @@
1
+ require 'minitest_helper'
2
+
3
+ describe Hobbit::AssetTag do
4
+ include Hobbit::Contrib::Mock
5
+
6
+ def app
7
+ mock_app do
8
+ include Hobbit::AssetTag
9
+ end
10
+ end
11
+
12
+ describe '#image_path' do
13
+ describe 'when passing an url' do
14
+ it 'must return the url' do
15
+ url = 'http://example.com/image.png'
16
+ app.to_app.image_path(url).must_equal url
17
+ end
18
+ end
19
+
20
+ describe 'when not passing an url' do
21
+ it 'must return a path to an image' do
22
+ app.to_app.image_path('hobbit.png').must_equal '/images/hobbit.png'
23
+ end
24
+ end
25
+ end
26
+
27
+ describe '#javascript' do
28
+ describe 'when passing one string' do
29
+ it 'must return one script tag' do
30
+ app.to_app.javascript('application').scan('script src').size.must_equal 1
31
+ end
32
+ end
33
+
34
+ describe 'when passing more than one string' do
35
+ it 'must return more than one script tag' do
36
+ app.to_app.javascript('application', 'other_script').scan('script src').size.must_equal 2
37
+ end
38
+ end
39
+ end
40
+
41
+ describe '#javascript_path' do
42
+ describe 'when passing an url' do
43
+ it 'must return the url' do
44
+ url = 'http://example.com/app.js'
45
+ app.to_app.javascript_path(url).must_equal url
46
+ end
47
+ end
48
+
49
+ describe 'when not passing an url' do
50
+ it 'must return a path to a javascript file' do
51
+ app.to_app.javascript_path('application').must_equal '/javascripts/application.js'
52
+ end
53
+ end
54
+ end
55
+
56
+ describe '#stylesheet' do
57
+ describe 'when passing one string' do
58
+ it 'must return one link tag' do
59
+ app.to_app.stylesheet('application').scan('link href').size.must_equal 1
60
+ end
61
+ end
62
+
63
+ describe 'when passing more than one string' do
64
+ it 'must return more than one link tag' do
65
+ app.to_app.stylesheet('application', 'other_style').scan('link href').size.must_equal 2
66
+ end
67
+ end
68
+ end
69
+
70
+ describe '#stylesheet_path' do
71
+ describe 'when passing an url' do
72
+ it 'must return the url' do
73
+ url = 'http://example.com/app.css'
74
+ app.to_app.stylesheet_path(url).must_equal url
75
+ end
76
+ end
77
+
78
+ describe 'when not passing an url' do
79
+ it 'must return a path to a stylesheet file' do
80
+ app.to_app.stylesheet_path('application').must_equal '/stylesheets/application.css'
81
+ end
82
+ end
83
+ end
84
+ end
@@ -1,15 +1,40 @@
1
1
  require 'minitest_helper'
2
2
 
3
3
  describe Hobbit::EnhancedRender do
4
+ include Hobbit::Contrib::Mock
4
5
  include Rack::Test::Methods
5
6
 
6
7
  def app
7
- TestEnhancedRenderApp.new
8
+ mock_app do
9
+ include Hobbit::EnhancedRender
10
+
11
+ # we do this because it the layout path is relative to file being run
12
+ def layout_path(template)
13
+ File.expand_path("../fixtures/enhanced_render/#{super}", __FILE__)
14
+ end
15
+
16
+ # we do this because it the view path is relative to file being run
17
+ def view_path(template)
18
+ File.expand_path("../fixtures/enhanced_render/#{super}", __FILE__)
19
+ end
20
+
21
+ get '/' do
22
+ render 'index', {}, layout: 'layout'
23
+ end
24
+
25
+ get '/without-layout' do
26
+ render 'index'
27
+ end
28
+
29
+ get '/partial' do
30
+ partial 'partial'
31
+ end
32
+ end
8
33
  end
9
34
 
10
35
  describe '#layout_path' do
11
36
  it 'must return a path' do
12
- path = File.expand_path('../fixtures/test_enhanced_render_app/views/layouts/layout.erb', __FILE__)
37
+ path = File.expand_path('../fixtures/enhanced_render/views/layouts/layout.erb', __FILE__)
13
38
  app.to_app.layout_path('layout').must_equal path
14
39
  end
15
40
  end
@@ -50,7 +75,7 @@ describe Hobbit::EnhancedRender do
50
75
 
51
76
  describe '#view_path' do
52
77
  it 'must return a path' do
53
- path = File.expand_path('../fixtures/test_enhanced_render_app/views/index.erb', __FILE__)
78
+ path = File.expand_path('../fixtures/enhanced_render/views/index.erb', __FILE__)
54
79
  app.to_app.view_path('index').must_equal path
55
80
  end
56
81
  end
@@ -0,0 +1,65 @@
1
+ require 'minitest_helper'
2
+
3
+ describe Hobbit::Environment do
4
+ include Hobbit::Contrib::Mock
5
+
6
+ let(:app) do
7
+ mock_app do
8
+ include Hobbit::Environment
9
+ end
10
+ end
11
+
12
+ describe '#environment' do
13
+ it 'must return the current environment' do
14
+ app.to_app.environment = :development
15
+ app.to_app.environment.must_equal :development
16
+ end
17
+
18
+ it 'must default to RACK_ENV' do
19
+ app.to_app.environment.must_equal ENV['RACK_ENV'].to_sym
20
+ end
21
+ end
22
+
23
+ describe '#environment=()' do
24
+ it 'must set the environment' do
25
+ app.to_app.environment = :test
26
+ app.to_app.environment.must_equal :test
27
+ end
28
+ end
29
+
30
+ describe '#development?' do
31
+ it 'must return true if self.class.settings[:environment] = :development' do
32
+ app.to_app.environment = :development
33
+ app.to_app.development?.must_equal true
34
+ end
35
+
36
+ it 'must return false if self.class.settings[:environment] != :development' do
37
+ app.to_app.environment = :production
38
+ app.to_app.development?.must_equal false
39
+ end
40
+ end
41
+
42
+ describe '#production?' do
43
+ it 'must return true if self.class.settings[:environment] = :production' do
44
+ app.to_app.environment = :production
45
+ app.to_app.production?.must_equal true
46
+ end
47
+
48
+ it 'must return false if self.class.settings[:environment] != :production' do
49
+ app.to_app.environment = :test
50
+ app.to_app.production?.must_equal false
51
+ end
52
+ end
53
+
54
+ describe '#test?' do
55
+ it 'must return true if self.class.settings[:environment] = :test' do
56
+ app.to_app.environment = :test
57
+ app.to_app.test?.must_equal true
58
+ end
59
+
60
+ it 'must return false if self.class.settings[:environment] != :test' do
61
+ app.to_app.environment = :development
62
+ app.to_app.test?.must_equal false
63
+ end
64
+ end
65
+ end