sinatra-scope 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 ADDED
@@ -0,0 +1,7 @@
1
+ source :rubygems
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem "rack-test"
7
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,27 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ sinatra-scope (0.0.1)
5
+ activesupport (~> 3.0.0)
6
+ i18n (~> 0.5.0)
7
+ sinatra
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ activesupport (3.0.3)
13
+ i18n (0.5.0)
14
+ rack (1.2.1)
15
+ rack-test (0.5.6)
16
+ rack (>= 1.0)
17
+ sinatra (1.1.2)
18
+ rack (~> 1.1)
19
+ tilt (~> 1.2)
20
+ tilt (1.2.2)
21
+
22
+ PLATFORMS
23
+ ruby
24
+
25
+ DEPENDENCIES
26
+ rack-test
27
+ sinatra-scope!
@@ -0,0 +1,69 @@
1
+ require 'sinatra/scope'
2
+
3
+ module Sinatra
4
+ module Resource
5
+
6
+ def resource(name, &block)
7
+ scope name, &block
8
+ end
9
+ alias resources resource
10
+
11
+ def member(&block)
12
+ scope ":id", &block
13
+ end
14
+
15
+ def index(&block)
16
+ get &block
17
+ end
18
+
19
+ def _new(&block)
20
+ get "/new", &block
21
+ end
22
+
23
+ def create(&block)
24
+ post &block
25
+ end
26
+
27
+ def show(&block)
28
+ if block.arity == 0
29
+ get &block
30
+ else
31
+ get { block.call(params[:id]) }
32
+ end
33
+ end
34
+
35
+ def edit(&block)
36
+ if block.arity == 0
37
+ get "/edit", &block
38
+ else
39
+ get("/edit") { block.call(params[:id]) }
40
+ end
41
+ end
42
+
43
+ def update(&block)
44
+ if block.arity == 0
45
+ put &block
46
+ else
47
+ put { block.call(params[:id]) }
48
+ end
49
+ end
50
+
51
+ def _delete(&block)
52
+ if block.arity == 0
53
+ get "/delete", &block
54
+ else
55
+ get("/delete") { block.call(params[:id]) }
56
+ end
57
+ end
58
+
59
+ def destroy(&block)
60
+ if block.arity == 0
61
+ delete &block
62
+ else
63
+ delete { block.call(params[:id]) }
64
+ end
65
+ end
66
+
67
+ end
68
+
69
+ end
@@ -0,0 +1,65 @@
1
+ require 'active_support/core_ext/string/inflections'
2
+ require 'active_support/inflections'
3
+ require 'sinatra/base'
4
+
5
+ module Sinatra
6
+ module Scope
7
+
8
+ [:get, :post, :patch, :put, :delete, :head, :options].each do |verb|
9
+ define_method verb do |path = '', options = {}, &block|
10
+ super(full_path(path), options, &block)
11
+ end
12
+ end
13
+
14
+ [:before, :after].each do |action|
15
+ define_method action do |path = '', options = {}, &block|
16
+ super(full_path(path), options, &block)
17
+ end
18
+ end
19
+
20
+ def scope(path, options = {}, &block)
21
+ case path
22
+ when Class
23
+ path = path.name
24
+ path = path.demodulize unless options[:full_classname]
25
+ path = path.underscore.dasherize
26
+ path = path.pluralize unless options[:singular]
27
+ else
28
+ path = path.to_s
29
+ end
30
+
31
+ (@scopes ||= []) << path
32
+ block.call
33
+ @scopes.pop
34
+ end
35
+
36
+ def scopes(*paths, &block)
37
+ @scopes ||= []
38
+ paths.each do |path|
39
+ @scopes << path.to_s
40
+ end
41
+ block.call
42
+ paths.each do |path|
43
+ @scopes.pop
44
+ end
45
+ end
46
+
47
+ protected
48
+ def full_path(path)
49
+ case path
50
+ when String, Symbol
51
+ ("/" + (@scopes || []).join("/") + path.to_s).squeeze("/")
52
+ when Regexp
53
+ Regexp.new(Regexp.escape("/" + (@scopes || []).join("/")) + path.source)
54
+ else
55
+ path
56
+ end
57
+ end
58
+
59
+ def path_name(path)
60
+ full_path(path).gsub(/^\//, '')
61
+ end
62
+
63
+ end
64
+
65
+ end
@@ -0,0 +1,35 @@
1
+ require 'sinatra/scope'
2
+ require 'active_support/core_ext/class/attribute'
3
+
4
+ module Sinatra
5
+
6
+ class UrlTracker
7
+ class_attribute :urls
8
+ self.urls = {}
9
+
10
+ def self.add(path, scopes = [], options = {})
11
+ name = (scopes.join("_") + "_" + path.to_s).gsub(/^_|_$/, "")
12
+
13
+ if name =~ /[a-zA-z0-9_\-%]/
14
+ self.urls[name] = ("/" + scopes.join("/") + "/" + path).squeeze("/")
15
+ end
16
+ end
17
+ end
18
+
19
+ module UrlScope
20
+
21
+ def scope(path = '', options = {}, &block)
22
+ UrlTracker.add(super, @scopes, options)
23
+ end
24
+
25
+ end
26
+
27
+ module UrlHelpers
28
+
29
+ def url(name, *args)
30
+ UrlTracker.urls[name.to_s]
31
+ end
32
+
33
+ end
34
+
35
+ end
data/test/contest.rb ADDED
@@ -0,0 +1,65 @@
1
+ require "test/unit"
2
+
3
+ # Test::Unit loads a default test if the suite is empty, and the only
4
+ # purpose of that test is to fail. As having empty contexts is a common
5
+ # practice, we decided to overwrite TestSuite#empty? in order to
6
+ # allow them. Having a failure when no tests have been defined seems
7
+ # counter-intuitive.
8
+ class Test::Unit::TestSuite
9
+ unless method_defined?(:empty?)
10
+ def empty?
11
+ false
12
+ end
13
+ end
14
+ end
15
+
16
+ # We added setup, test and context as class methods, and the instance
17
+ # method setup now iterates on the setup blocks. Note that all setup
18
+ # blocks must be defined with the block syntax. Adding a setup instance
19
+ # method defeats the purpose of this library.
20
+ class Test::Unit::TestCase
21
+ def self.setup(&block)
22
+ setup_blocks << block
23
+ end
24
+
25
+ def setup
26
+ self.class.setup_blocks.each do |block|
27
+ instance_eval(&block)
28
+ end
29
+ end
30
+
31
+ def self.context(name, &block)
32
+ subclass = Class.new(self.superclass)
33
+ subclass.setup_blocks.unshift(*setup_blocks)
34
+ subclass.class_eval(&block)
35
+ const_set(context_name(name), subclass)
36
+ end
37
+
38
+ def self.test(name, &block)
39
+ define_method(test_name(name), &block)
40
+ end
41
+
42
+ class << self
43
+ alias_method :should, :test
44
+ alias_method :describe, :context
45
+ end
46
+
47
+ private
48
+
49
+ def self.setup_blocks
50
+ @setup_blocks ||= []
51
+ end
52
+
53
+ def self.context_name(name)
54
+ "Test#{sanitize_name(name).gsub(/(^| )(\w)/) { $2.upcase }}".to_sym
55
+ end
56
+
57
+ def self.test_name(name)
58
+ "test_#{sanitize_name(name).gsub(/\s+/,'_')}".to_sym
59
+ end
60
+
61
+ def self.sanitize_name(name)
62
+ name.gsub(/\W+/, ' ').strip
63
+ end
64
+ end
65
+
data/test/helper.rb ADDED
@@ -0,0 +1,83 @@
1
+ ENV['RACK_ENV'] = 'test'
2
+
3
+ require 'rack'
4
+
5
+ testdir = File.dirname(__FILE__)
6
+ $LOAD_PATH.unshift testdir unless $LOAD_PATH.include?(testdir)
7
+
8
+ libdir = File.dirname(File.dirname(__FILE__)) + '/lib'
9
+ $LOAD_PATH.unshift libdir unless $LOAD_PATH.include?(libdir)
10
+
11
+ require 'contest'
12
+ require 'rack/test'
13
+ require 'sinatra/base'
14
+ require 'sinatra/scope'
15
+ require 'sinatra/resource'
16
+ require 'sinatra/urls'
17
+
18
+ class Sinatra::Base
19
+ # Allow assertions in request context
20
+ include Test::Unit::Assertions
21
+ end
22
+
23
+ # App that includes scope helpers
24
+ class ScopeApp < Sinatra::Base
25
+ register Sinatra::Scope
26
+ register Sinatra::Resource
27
+ register Sinatra::UrlScope
28
+ helpers Sinatra::UrlHelpers
29
+ end
30
+
31
+ Sinatra::Base.set :environment, :test
32
+
33
+ class Test::Unit::TestCase
34
+ include Rack::Test::Methods
35
+
36
+ class << self
37
+ alias_method :it, :test
38
+ end
39
+
40
+ alias_method :response, :last_response
41
+
42
+ setup do
43
+ Sinatra::Base.set :environment, :test
44
+ end
45
+
46
+ # Sets up a Sinatra::Base subclass defined with the block
47
+ # given. Used in setup or individual spec methods to establish
48
+ # the application.
49
+ def mock_app(base=ScopeApp, &block)
50
+ @app = Sinatra.new(base, &block)
51
+ end
52
+
53
+ def app
54
+ Rack::Lint.new(@app)
55
+ end
56
+
57
+ def body
58
+ response.body.to_s
59
+ end
60
+
61
+ # Delegate other missing methods to response.
62
+ def method_missing(name, *args, &block)
63
+ if response && response.respond_to?(name)
64
+ response.send(name, *args, &block)
65
+ else
66
+ super
67
+ end
68
+ end
69
+
70
+ # Also check response since we delegate there.
71
+ def respond_to?(symbol, include_private=false)
72
+ super || (response && response.respond_to?(symbol, include_private))
73
+ end
74
+
75
+ # Do not output warnings for the duration of the block.
76
+ def silence_warnings
77
+ $VERBOSE, v = nil, $VERBOSE
78
+ yield
79
+ ensure
80
+ $VERBOSE = v
81
+ end
82
+ end
83
+
@@ -0,0 +1,267 @@
1
+ require File.expand_path 'helper', File.dirname(__FILE__)
2
+
3
+ class ResourceTest < Test::Unit::TestCase
4
+
5
+ it 'supports the resource method' do
6
+ mock_app {
7
+ resource "pages" do
8
+ get do
9
+ "Pages are great!"
10
+ end
11
+ end
12
+ }
13
+
14
+ get "/pages"
15
+ assert ok?
16
+ assert_equal "Pages are great!", body
17
+ end
18
+
19
+ it 'supports the resources method' do
20
+ mock_app {
21
+ resources "pages" do
22
+ get do
23
+ "Pages are great!"
24
+ end
25
+ end
26
+ }
27
+
28
+ get "/pages"
29
+ assert ok?
30
+ assert_equal "Pages are great!", body
31
+ end
32
+
33
+ it 'supports the member method' do
34
+ mock_app {
35
+ resource "pages" do
36
+ member do
37
+ get do
38
+ "Page id: #{params[:id]}"
39
+ end
40
+ end
41
+ end
42
+ }
43
+
44
+ get "/pages/3"
45
+ assert ok?
46
+ assert_equal "Page id: 3", body
47
+ end
48
+
49
+ it "supports the index method of a resource" do
50
+ mock_app do
51
+ resource "pages" do
52
+ index do
53
+ "Hello"
54
+ end
55
+ end
56
+ end
57
+
58
+ get "/pages"
59
+ assert ok?
60
+ assert_equal "Hello", body
61
+ end
62
+
63
+ it "supports the new (_new) method of a resource" do
64
+ mock_app do
65
+ resource "pages" do
66
+ _new do
67
+ "New page"
68
+ end
69
+ end
70
+ end
71
+
72
+ get "/pages/new"
73
+ assert ok?
74
+ assert_equal "New page", body
75
+ end
76
+
77
+ it "supports the create method of a resource" do
78
+ mock_app do
79
+ resource "pages" do
80
+ create do
81
+ "Created the page"
82
+ end
83
+ end
84
+ end
85
+
86
+ post "/pages", {}
87
+ assert ok?
88
+ assert_equal "Created the page", body
89
+ end
90
+
91
+ it "supports the show method of a resource" do
92
+ mock_app do
93
+ resource "pages" do
94
+ member do
95
+ show do
96
+ "Page #{params[:id]}"
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ get "/pages/1"
103
+ assert ok?
104
+ assert_equal "Page 1", body
105
+ end
106
+
107
+ it "supports the show method of a resource with the id argument" do
108
+ mock_app do
109
+ resource "pages" do
110
+ member do
111
+ show do |id|
112
+ "Page #{id}"
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ get "/pages/1"
119
+ assert ok?
120
+ assert_equal "Page 1", body
121
+ end
122
+
123
+ it "supports the edit method of a resource" do
124
+ mock_app do
125
+ resource "pages" do
126
+ member do
127
+ edit do
128
+ "Edit page #{params[:id]}"
129
+ end
130
+ end
131
+ end
132
+ end
133
+
134
+ get "/pages/1/edit"
135
+ assert ok?
136
+ assert_equal "Edit page 1", body
137
+ end
138
+
139
+ it "supports the edit method of a resource with the id argument" do
140
+ mock_app do
141
+ resource "pages" do
142
+ member do
143
+ edit do |id|
144
+ "Edit page #{id}"
145
+ end
146
+ end
147
+ end
148
+ end
149
+
150
+ get "/pages/1/edit"
151
+ assert ok?
152
+ assert_equal "Edit page 1", body
153
+ end
154
+
155
+ it "supports the update method of a resource" do
156
+ mock_app do
157
+ resource "pages" do
158
+ member do
159
+ update do
160
+ "Updated page #{params[:id]}"
161
+ end
162
+ end
163
+ end
164
+ end
165
+
166
+ put "/pages/1", {}
167
+ assert ok?
168
+ assert_equal "Updated page 1", body
169
+ end
170
+
171
+ it "supports the update method of a resource with the id argument" do
172
+ mock_app do
173
+ resource "pages" do
174
+ member do
175
+ update do |id|
176
+ "Updated page #{id}"
177
+ end
178
+ end
179
+ end
180
+ end
181
+
182
+ put "/pages/1", {}
183
+ assert ok?
184
+ assert_equal "Updated page 1", body
185
+ end
186
+
187
+ it "supports the delete (_delete) method of a resource" do
188
+ mock_app do
189
+ resource "pages" do
190
+ member do
191
+ _delete do
192
+ "Page #{params[:id]}"
193
+ end
194
+ end
195
+ end
196
+ end
197
+
198
+ get "/pages/1/delete"
199
+ assert ok?
200
+ assert_equal "Page 1", body
201
+ end
202
+
203
+ it "supports the delete (_delete) method of a resource with the id argument" do
204
+ mock_app do
205
+ resource "pages" do
206
+ member do
207
+ _delete do |id|
208
+ "Page #{id}"
209
+ end
210
+ end
211
+ end
212
+ end
213
+
214
+ get "/pages/1/delete"
215
+ assert ok?
216
+ assert_equal "Page 1", body
217
+ end
218
+
219
+ it "supports the destroy method of a resource" do
220
+ mock_app do
221
+ resource "pages" do
222
+ member do
223
+ destroy do
224
+ "destroyd page #{params[:id]}"
225
+ end
226
+ end
227
+ end
228
+ end
229
+
230
+ delete "/pages/1", {}
231
+ assert ok?
232
+ assert_equal "destroyd page 1", body
233
+ end
234
+
235
+ it "supports the destroy method of a resource with the id argument" do
236
+ mock_app do
237
+ resource "pages" do
238
+ member do
239
+ destroy do |id|
240
+ "destroyd page #{id}"
241
+ end
242
+ end
243
+ end
244
+ end
245
+
246
+ delete "/pages/1", {}
247
+ assert ok?
248
+ assert_equal "destroyd page 1", body
249
+ end
250
+
251
+ it 'supports using a class as a resource' do
252
+ class Page; end
253
+
254
+ mock_app {
255
+ resource Page do
256
+ _new do
257
+ "Create a new page?"
258
+ end
259
+ end
260
+ }
261
+
262
+ get "/pages/new"
263
+ assert ok?
264
+ assert_equal "Create a new page?", body
265
+ end
266
+
267
+ end
@@ -0,0 +1,311 @@
1
+ require File.expand_path 'helper', File.dirname(__FILE__)
2
+
3
+ class ScopeTest < Test::Unit::TestCase
4
+
5
+ it "supports the scope method" do
6
+ mock_app do
7
+ scope "admin" do
8
+ get "/login" do
9
+ "/admin/login works"
10
+ end
11
+ end
12
+ end
13
+
14
+ get "/admin/login"
15
+ assert ok?
16
+ assert_equal "/admin/login works", response.body
17
+ end
18
+
19
+ %w[get put patch post delete].each do |verb|
20
+ it "defines #{verb.upcase} request handlers with #{verb}" do
21
+ mock_app {
22
+ send verb, '/hello' do
23
+ 'Hello World'
24
+ end
25
+ }
26
+
27
+ request = Rack::MockRequest.new(@app)
28
+ response = request.request(verb.upcase, '/hello', {})
29
+ assert response.ok?
30
+ assert_equal 'Hello World', response.body
31
+ end
32
+ end
33
+
34
+ %w[get put post patch delete].each do |verb|
35
+ it "defines scoped #{verb.upcase} request handlers with #{verb}" do
36
+ mock_app {
37
+ scope "something" do
38
+ send verb, '/hello' do
39
+ 'Hello World'
40
+ end
41
+ end
42
+ }
43
+
44
+ request = Rack::MockRequest.new(@app)
45
+ response = request.request(verb.upcase, '/something/hello', {})
46
+ assert response.ok?
47
+ assert_equal 'Hello World', response.body
48
+ end
49
+ end
50
+
51
+ it "defines HEAD request handlers with HEAD" do
52
+ mock_app {
53
+ head '/hello' do
54
+ response['X-Hello'] = 'World!'
55
+ 'remove me'
56
+ end
57
+ }
58
+
59
+ request = Rack::MockRequest.new(@app)
60
+ response = request.request('HEAD', '/hello', {})
61
+ assert response.ok?
62
+ assert_equal 'World!', response['X-Hello']
63
+ assert_equal '', response.body
64
+ end
65
+
66
+ it "defines scoped HEAD request handlers with HEAD" do
67
+ mock_app {
68
+ scope "something" do
69
+ head '/hello' do
70
+ response['X-Hello'] = 'World!'
71
+ 'remove me'
72
+ end
73
+ end
74
+ }
75
+
76
+ request = Rack::MockRequest.new(@app)
77
+ response = request.request('HEAD', '/something/hello', {})
78
+ assert response.ok?
79
+ assert_equal 'World!', response['X-Hello']
80
+ assert_equal '', response.body
81
+ end
82
+
83
+ it "404s when no route satisfies the request" do
84
+ mock_app {
85
+ get('/foo') { }
86
+ }
87
+ get '/bar'
88
+ assert_equal 404, status
89
+ end
90
+
91
+ it 'takes multiple definitions of a route' do
92
+ mock_app {
93
+ user_agent(/Foo/)
94
+ get '/foo' do
95
+ 'foo'
96
+ end
97
+
98
+ get '/foo' do
99
+ 'not foo'
100
+ end
101
+ }
102
+
103
+ get '/foo', {}, 'HTTP_USER_AGENT' => 'Foo'
104
+ assert ok?
105
+ assert_equal 'foo', body
106
+
107
+ get '/foo'
108
+ assert ok?
109
+ assert_equal 'not foo', body
110
+ end
111
+
112
+ it 'takes multiple definitions of a scoped route' do
113
+ mock_app {
114
+ scope "something" do
115
+ user_agent(/Foo/)
116
+ get '/foo' do
117
+ 'foo'
118
+ end
119
+
120
+ get '/foo' do
121
+ 'not foo'
122
+ end
123
+ end
124
+ }
125
+
126
+ get '/something/foo', {}, 'HTTP_USER_AGENT' => 'Foo'
127
+ assert ok?
128
+ assert_equal 'foo', body
129
+
130
+ get '/something/foo'
131
+ assert ok?
132
+ assert_equal 'not foo', body
133
+ end
134
+
135
+ it 'supports regular expressions' do
136
+ mock_app {
137
+ get(/^\/foo...\/bar$/) do
138
+ 'Hello World'
139
+ end
140
+ }
141
+
142
+ get '/foooom/bar'
143
+ assert ok?
144
+ assert_equal 'Hello World', body
145
+ end
146
+
147
+ it 'supports regular expressions' do
148
+ mock_app {
149
+ scope "something" do
150
+ get(/\/foo...\/bar$/) do
151
+ 'Hello World'
152
+ end
153
+ end
154
+ }
155
+
156
+ get '/something/foooom/bar'
157
+ assert ok?
158
+ assert_equal 'Hello World', body
159
+ end
160
+
161
+ it 'raises a TypeError when pattern is not a String or Regexp' do
162
+ assert_raise(TypeError) {
163
+ mock_app { get(42){} }
164
+ }
165
+ end
166
+
167
+ it 'supports helpers' do
168
+ mock_app {
169
+ helpers do
170
+ def foo
171
+ "bar"
172
+ end
173
+ end
174
+
175
+ get "/foo" do
176
+ foo
177
+ end
178
+
179
+ scope "something" do
180
+ get "/foo" do
181
+ foo
182
+ end
183
+ end
184
+ }
185
+
186
+ get '/foo'
187
+ assert ok?
188
+ assert_equal 'bar', body
189
+ end
190
+
191
+ it 'supports helpers in scoped urls' do
192
+ mock_app {
193
+ helpers do
194
+ def foo
195
+ "bar"
196
+ end
197
+ end
198
+
199
+ get "/foo" do
200
+ foo
201
+ end
202
+
203
+ scope "something" do
204
+ get "/foo" do
205
+ foo
206
+ end
207
+ end
208
+ }
209
+
210
+ get '/something/foo'
211
+ assert ok?
212
+ assert_equal 'bar', body
213
+ end
214
+
215
+ it 'supports helpers inside the scope' do
216
+ mock_app {
217
+ scope "something" do
218
+ helpers do
219
+ def foo
220
+ "bar"
221
+ end
222
+ end
223
+
224
+ get "/foo" do
225
+ foo
226
+ end
227
+ end
228
+ }
229
+
230
+ get '/something/foo'
231
+ assert ok?
232
+ assert_equal 'bar', body
233
+ end
234
+
235
+ it 'supports using a class as a scope' do
236
+ class Page; end
237
+
238
+ mock_app {
239
+ scope Page do
240
+ get "/hello" do
241
+ "hello back!"
242
+ end
243
+ end
244
+ }
245
+
246
+ get "/pages/hello"
247
+ assert ok?
248
+ assert_equal 'hello back!', body
249
+ end
250
+
251
+ it 'supports using a class as a scope (singular)' do
252
+ class Page; end
253
+
254
+ mock_app {
255
+ scope Page, :singular => true do
256
+ get "/hello" do
257
+ "hello back!"
258
+ end
259
+ end
260
+ }
261
+
262
+ get "/page/hello"
263
+ assert ok?
264
+ assert_equal 'hello back!', body
265
+ end
266
+
267
+ it 'supports using a class as a scope (keep full name)' do
268
+ class Page; end
269
+
270
+ mock_app {
271
+ scope Page, :full_classname => true do
272
+ get "/hello" do
273
+ "hello back!"
274
+ end
275
+ end
276
+ }
277
+
278
+ get "/scope-test/pages/hello"
279
+ assert ok?
280
+ assert_equal 'hello back!', body
281
+ end
282
+
283
+ it "supports scoped before" do
284
+ mock_app {
285
+ get("foo") { @text.to_s + "foo" }
286
+ scope :bar do
287
+ before { @text = "baz" }
288
+ get { @text.to_s + "bar" }
289
+ end
290
+ }
291
+ get "/foo"
292
+ assert ok?
293
+ assert_equal "foo", body
294
+
295
+ get "/bar"
296
+ assert ok?
297
+ assert_equal "bazbar", body
298
+ end
299
+
300
+ it "supports multiple scopes at once" do
301
+ mock_app {
302
+ scopes :admin, :pages do
303
+ get { "hello there" }
304
+ end
305
+ }
306
+ get "/admin/pages"
307
+ assert ok?
308
+ assert_equal "hello there", body
309
+ end
310
+
311
+ end
@@ -0,0 +1,35 @@
1
+ require File.expand_path 'helper', File.dirname(__FILE__)
2
+
3
+ class UrlHelperTest < Test::Unit::TestCase
4
+
5
+ it "supports the url method" do
6
+ mock_app do
7
+ scope "admin" do
8
+ get do
9
+ "hello #{url(:admin)}"
10
+ end
11
+ end
12
+ end
13
+
14
+ get "/admin"
15
+ assert ok?
16
+ assert_equal "hello /admin", body
17
+ end
18
+
19
+ it "supports nested scopes with the url method" do
20
+ mock_app do
21
+ scope "admin" do
22
+ scope "projects" do
23
+ get do
24
+ "hello #{url(:admin_projects)}"
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ get "/admin/projects"
31
+ assert ok?
32
+ assert_equal "hello /admin/projects", body
33
+ end
34
+
35
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sinatra-scope
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nathan Herald
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sinatra
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activesupport
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 3.0.0
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 3.0.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: i18n
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 0.5.0
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.5.0
62
+ description: Simple nested routes for Sinatra.
63
+ email: nathan@myobie.com
64
+ executables: []
65
+ extensions: []
66
+ extra_rdoc_files:
67
+ - Gemfile
68
+ - Gemfile.lock
69
+ files:
70
+ - lib/sinatra/resource.rb
71
+ - lib/sinatra/scope.rb
72
+ - lib/sinatra/urls.rb
73
+ - test/contest.rb
74
+ - test/helper.rb
75
+ - test/sinatra_resource_test.rb
76
+ - test/sinatra_scope_test.rb
77
+ - test/sinatra_urls_test.rb
78
+ - Gemfile
79
+ - Gemfile.lock
80
+ homepage: http://github.com/myobie/sinatra-scope
81
+ licenses: []
82
+ post_install_message:
83
+ rdoc_options:
84
+ - --title
85
+ - Sinatra::Scope -- Simple nested routes for Sinatra
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements:
101
+ - sinatra
102
+ rubyforge_project: sinatra-scope
103
+ rubygems_version: 1.8.23
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: Simple nested routes for Sinatra
107
+ test_files: []