gin 1.0.4 → 1.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/History.rdoc +16 -0
- data/Manifest.txt +12 -2
- data/README.rdoc +33 -0
- data/Rakefile +5 -0
- data/TODO.rdoc +7 -0
- data/bin/gin +158 -0
- data/lib/gin.rb +19 -2
- data/lib/gin/app.rb +420 -173
- data/lib/gin/cache.rb +65 -0
- data/lib/gin/config.rb +174 -18
- data/lib/gin/constants.rb +4 -0
- data/lib/gin/controller.rb +219 -11
- data/lib/gin/core_ext/gin_class.rb +16 -0
- data/lib/gin/errorable.rb +16 -2
- data/lib/gin/filterable.rb +29 -19
- data/lib/gin/reloadable.rb +1 -1
- data/lib/gin/request.rb +11 -0
- data/lib/gin/router.rb +185 -61
- data/lib/gin/rw_lock.rb +109 -0
- data/lib/gin/test.rb +702 -0
- data/public/gin.css +15 -3
- data/test/app/layouts/bar.erb +9 -0
- data/test/app/layouts/foo.erb +9 -0
- data/test/app/views/bar.erb +1 -0
- data/test/mock_app.rb +94 -0
- data/test/mock_config/invalid.yml +2 -0
- data/test/test_app.rb +160 -45
- data/test/test_cache.rb +57 -0
- data/test/test_config.rb +108 -13
- data/test/test_controller.rb +201 -11
- data/test/test_errorable.rb +1 -1
- data/test/test_gin.rb +9 -0
- data/test/test_helper.rb +3 -1
- data/test/test_router.rb +33 -0
- data/test/test_rw_lock.rb +65 -0
- data/test/test_test.rb +627 -0
- metadata +86 -6
- data/.autotest +0 -23
- data/.gitignore +0 -7
data/test/test_cache.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
class CacheTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@cache = Gin::Cache.new
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
def test_write_timeout
|
11
|
+
assert_equal 0.05, @cache.write_timeout
|
12
|
+
@cache.write_timeout = 0.1
|
13
|
+
assert_equal 0.1, @cache.write_timeout
|
14
|
+
assert_equal 0.1, @cache.instance_variable_get("@lock").write_timeout
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
def test_write_thread_safe
|
19
|
+
@cache[:num] = 0
|
20
|
+
threads = []
|
21
|
+
10.times do
|
22
|
+
threads << Thread.new{ @cache[:num] += 1 }
|
23
|
+
end
|
24
|
+
threads.each(&:join)
|
25
|
+
|
26
|
+
assert_equal 10, @cache[:num]
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def test_has_key
|
31
|
+
assert !@cache.has_key?(:num)
|
32
|
+
@cache[:num] = 123
|
33
|
+
assert @cache.has_key?(:num)
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def test_cache_value
|
38
|
+
val = @cache.cache :num, 1234
|
39
|
+
assert_equal 1234, val
|
40
|
+
assert_equal 1234, @cache[:num]
|
41
|
+
|
42
|
+
val = @cache.cache :num, 5678
|
43
|
+
assert_equal 1234, val
|
44
|
+
assert_equal 1234, @cache[:num]
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def test_cache_block
|
49
|
+
val = @cache.cache(:num){ 1234 }
|
50
|
+
assert_equal 1234, val
|
51
|
+
assert_equal 1234, @cache[:num]
|
52
|
+
|
53
|
+
val = @cache.cache(:num){ 5678 }
|
54
|
+
assert_equal 1234, val
|
55
|
+
assert_equal 1234, @cache[:num]
|
56
|
+
end
|
57
|
+
end
|
data/test/test_config.rb
CHANGED
@@ -3,31 +3,126 @@ require 'gin/config'
|
|
3
3
|
|
4
4
|
class ConfigTest < Test::Unit::TestCase
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
CONFIG_DIR = File.expand_path("../mock_config", __FILE__)
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@error_io = StringIO.new
|
10
|
+
@config = Gin::Config.new "development",
|
11
|
+
dir: CONFIG_DIR, logger: @error_io, ttl: 300
|
8
12
|
end
|
9
13
|
|
10
14
|
|
11
15
|
def test_config_dev
|
12
|
-
|
13
|
-
|
14
|
-
assert_equal "localhost", config.memcache['host']
|
15
|
-
assert_equal 1, config.memcache['connections']
|
16
|
+
assert_equal "localhost", @config['memcache.host']
|
17
|
+
assert_equal 1, @config['memcache.connections']
|
16
18
|
|
17
|
-
assert_equal "dev.backend.example.com", config
|
19
|
+
assert_equal "dev.backend.example.com", @config['backend.host']
|
18
20
|
|
19
|
-
|
21
|
+
assert_nil @config['not_a_config']
|
20
22
|
end
|
21
23
|
|
22
24
|
|
23
25
|
def test_config_unknown_env
|
24
|
-
config = Gin::Config.new "foo",
|
26
|
+
@config = Gin::Config.new "foo", dir: CONFIG_DIR
|
27
|
+
|
28
|
+
assert_equal "example.com", @config['memcache.host']
|
29
|
+
assert_equal 5, @config['memcache.connections']
|
30
|
+
|
31
|
+
assert_equal "backend.example.com", @config['backend.host']
|
32
|
+
|
33
|
+
assert_nil @config['not_a_config']
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def test_set
|
38
|
+
assert !@config.has?('foo'), "Config shouldn't have foo available"
|
39
|
+
assert_nil @config['foo']
|
40
|
+
|
41
|
+
@config.set 'foo', 1234
|
42
|
+
assert_equal 1234, @config['foo']
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def test_load_all
|
47
|
+
assert @config.instance_variable_get("@data").empty?
|
48
|
+
@config.load!
|
49
|
+
assert_equal %w{backend memcache},
|
50
|
+
@config.instance_variable_get("@data").keys
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
def test_bracket
|
55
|
+
assert_equal "localhost", @config['memcache.host']
|
56
|
+
assert_equal 1, @config['memcache.connections']
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
def test_invalid_yaml
|
61
|
+
assert_raise Psych::SyntaxError do
|
62
|
+
YAML.load_file @config.send(:filepath_for, 'invalid')
|
63
|
+
end
|
64
|
+
assert_nil @config.load_config('invalid')
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def test_get
|
69
|
+
assert_equal "localhost", @config.get('memcache')['host']
|
70
|
+
@config.set('memcache', 'host' => 'example.com')
|
71
|
+
assert_equal "example.com", @config.get('memcache')['host']
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
def test_get_non_existant
|
76
|
+
assert_raise Gin::MissingConfig do
|
77
|
+
@config.get('non_existant')
|
78
|
+
end
|
79
|
+
|
80
|
+
assert_nil @config.get('non_existant', true)
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
def test_get_reload
|
85
|
+
@config['memcache']
|
86
|
+
@config.set('memcache', 'host' => 'example.com')
|
87
|
+
@config.instance_variable_set("@load_times", 'memcache' => Time.now - (@config.ttl + 1))
|
88
|
+
@config.instance_variable_set("@mtimes", 'memcache' => Time.now)
|
89
|
+
assert_equal 'localhost', @config.get('memcache')['host']
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
def test_get_reload_no_change
|
94
|
+
@config['memcache']
|
95
|
+
@config.set('memcache', 'host' => 'example.com')
|
96
|
+
@config.instance_variable_set("@load_times", 'memcache' => Time.now - (@config.ttl + 1))
|
97
|
+
assert_equal 'example.com', @config.get('memcache')['host']
|
98
|
+
|
99
|
+
last_check = @config.instance_variable_get("@load_times")['memcache']
|
100
|
+
assert Time.now - last_check <= 1
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
def test_current
|
105
|
+
assert !@config.current?('memcache')
|
106
|
+
assert @config['memcache']
|
107
|
+
assert @config.current?('memcache')
|
108
|
+
|
109
|
+
@config.instance_variable_set("@load_times", 'memcache' => Time.now)
|
110
|
+
assert @config.current?('memcache')
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
def test_current_expired
|
115
|
+
@config.instance_variable_set("@load_times", 'memcache' => Time.now - (@config.ttl + 1))
|
116
|
+
assert !@config.current?('memcache')
|
117
|
+
end
|
25
118
|
|
26
|
-
assert_equal "example.com", config.memcache['host']
|
27
|
-
assert_equal 5, config.memcache['connections']
|
28
119
|
|
29
|
-
|
120
|
+
def test_current_no_ttl
|
121
|
+
assert @config['memcache']
|
122
|
+
@config.instance_variable_set("@load_times", 'memcache' => Time.now - (@config.ttl + 1))
|
123
|
+
assert !@config.current?('memcache')
|
30
124
|
|
31
|
-
|
125
|
+
@config.ttl = false
|
126
|
+
assert @config.current?('memcache')
|
32
127
|
end
|
33
128
|
end
|
data/test/test_controller.rb
CHANGED
@@ -18,6 +18,9 @@ class AppController < Gin::Controller
|
|
18
18
|
error Gin::BadRequest do
|
19
19
|
body "Bad Request"
|
20
20
|
end
|
21
|
+
|
22
|
+
|
23
|
+
layout :foo
|
21
24
|
end
|
22
25
|
|
23
26
|
class TestController < Gin::Controller
|
@@ -26,7 +29,15 @@ class TestController < Gin::Controller
|
|
26
29
|
end
|
27
30
|
end
|
28
31
|
|
32
|
+
module BarHelper
|
33
|
+
def test_val
|
34
|
+
"BarHelper"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
29
38
|
class BarController < AppController
|
39
|
+
include BarHelper
|
40
|
+
|
30
41
|
before_filter :stop, :only => :delete do
|
31
42
|
FILTERS_RUN << :stop
|
32
43
|
halt 404, "Not Found"
|
@@ -57,6 +68,9 @@ end
|
|
57
68
|
|
58
69
|
class ControllerTest < Test::Unit::TestCase
|
59
70
|
class MockApp < Gin::App
|
71
|
+
|
72
|
+
root_dir "test/app"
|
73
|
+
|
60
74
|
mount BarController do
|
61
75
|
get :show, "/:id"
|
62
76
|
get :delete, :rm_bar
|
@@ -66,10 +80,33 @@ class ControllerTest < Test::Unit::TestCase
|
|
66
80
|
end
|
67
81
|
|
68
82
|
|
83
|
+
class MockTemplateEngine
|
84
|
+
attr_reader :file
|
85
|
+
|
86
|
+
class << self
|
87
|
+
attr_accessor :default_mime_type
|
88
|
+
end
|
89
|
+
|
90
|
+
def initialize file
|
91
|
+
@file = file
|
92
|
+
end
|
93
|
+
|
94
|
+
def render scope, locals
|
95
|
+
"mock render"
|
96
|
+
end
|
97
|
+
|
98
|
+
def default_mime_type
|
99
|
+
self.class.default_mime_type
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
|
69
104
|
def setup
|
70
|
-
|
71
|
-
MockApp.
|
72
|
-
|
105
|
+
MockTemplateEngine.default_mime_type = nil
|
106
|
+
MockApp.options[:environment] = 'test'
|
107
|
+
MockApp.options[:asset_host] = nil
|
108
|
+
BarController.instance_variable_set("@layout", nil)
|
109
|
+
@app = MockApp.new logger: StringIO.new
|
73
110
|
@ctrl = BarController.new(@app, rack_env)
|
74
111
|
end
|
75
112
|
|
@@ -88,6 +125,156 @@ class ControllerTest < Test::Unit::TestCase
|
|
88
125
|
end
|
89
126
|
|
90
127
|
|
128
|
+
def test_class_layout
|
129
|
+
assert_equal :foo, BarController.layout
|
130
|
+
assert_equal :foo, AppController.layout
|
131
|
+
assert_nil TestController.layout
|
132
|
+
|
133
|
+
BarController.layout :bar
|
134
|
+
assert_equal :bar, BarController.layout
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
def test_layout
|
139
|
+
assert_equal :foo, @ctrl.layout
|
140
|
+
BarController.layout :bar
|
141
|
+
assert_equal :bar, @ctrl.layout
|
142
|
+
|
143
|
+
@ctrl = TestController.new @app, {}
|
144
|
+
assert_equal @app.layout, @ctrl.layout
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
def test_template_path
|
149
|
+
assert_equal File.join(@app.views_dir, "foo"),
|
150
|
+
@ctrl.template_path("foo")
|
151
|
+
assert_equal File.join(@app.root_dir, "foo"),
|
152
|
+
@ctrl.template_path("/foo")
|
153
|
+
assert_equal File.join(@app.layouts_dir, "foo"),
|
154
|
+
@ctrl.template_path("foo", true)
|
155
|
+
assert_equal File.join(@app.views_dir, "bar/foo"),
|
156
|
+
@ctrl.template_path("*/foo")
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
def test_view
|
161
|
+
str = @ctrl.view :bar
|
162
|
+
assert(/Foo Layout/ === str)
|
163
|
+
assert(/BarHelper/ === str)
|
164
|
+
assert_equal File.join(@app.layouts_dir, "foo.erb"),
|
165
|
+
@ctrl.env[Gin::Constants::GIN_TEMPLATES].first
|
166
|
+
assert_equal File.join(@app.views_dir, "bar.erb"),
|
167
|
+
@ctrl.env[Gin::Constants::GIN_TEMPLATES].last
|
168
|
+
end
|
169
|
+
|
170
|
+
|
171
|
+
def test_view_layout_missing
|
172
|
+
str = @ctrl.view :bar, layout: "missing"
|
173
|
+
assert_equal "Value is BarHelper\n", str
|
174
|
+
assert_equal [File.join(@app.views_dir, "bar.erb")],
|
175
|
+
@ctrl.env[Gin::Constants::GIN_TEMPLATES]
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
def test_view_other_layout
|
180
|
+
str = @ctrl.view :bar, layout: "bar.erb"
|
181
|
+
assert(/Bar Layout/ === str)
|
182
|
+
assert(/BarHelper/ === str)
|
183
|
+
assert_equal File.join(@app.layouts_dir, "bar.erb"),
|
184
|
+
@ctrl.env[Gin::Constants::GIN_TEMPLATES].first
|
185
|
+
assert_equal File.join(@app.views_dir, "bar.erb"),
|
186
|
+
@ctrl.env[Gin::Constants::GIN_TEMPLATES].last
|
187
|
+
end
|
188
|
+
|
189
|
+
|
190
|
+
def test_view_no_layout
|
191
|
+
str = @ctrl.view :bar, layout: false
|
192
|
+
assert_equal "Value is BarHelper\n", str
|
193
|
+
assert_equal [File.join(@app.views_dir, "bar.erb")],
|
194
|
+
@ctrl.env[Gin::Constants::GIN_TEMPLATES]
|
195
|
+
end
|
196
|
+
|
197
|
+
|
198
|
+
def test_view_missing
|
199
|
+
assert_raises(Gin::TemplateMissing){ @ctrl.view :missing }
|
200
|
+
end
|
201
|
+
|
202
|
+
|
203
|
+
def test_view_locals
|
204
|
+
str = @ctrl.view :bar, locals: {test_val: "LOCAL"}
|
205
|
+
assert(/Foo Layout/ === str)
|
206
|
+
assert(str !~ /BarHelper/)
|
207
|
+
assert(/Value is LOCAL/ === str)
|
208
|
+
assert_equal File.join(@app.layouts_dir, "foo.erb"),
|
209
|
+
@ctrl.env[Gin::Constants::GIN_TEMPLATES].first
|
210
|
+
assert_equal File.join(@app.views_dir, "bar.erb"),
|
211
|
+
@ctrl.env[Gin::Constants::GIN_TEMPLATES].last
|
212
|
+
end
|
213
|
+
|
214
|
+
|
215
|
+
def test_view_scope
|
216
|
+
scope = Struct.new(:test_val).new("SCOPED")
|
217
|
+
str = @ctrl.view :bar, scope: scope
|
218
|
+
assert(/Foo Layout/ === str)
|
219
|
+
assert(str !~ /BarHelper/)
|
220
|
+
assert(/Value is SCOPED/ === str)
|
221
|
+
assert_equal File.join(@app.layouts_dir, "foo.erb"),
|
222
|
+
@ctrl.env[Gin::Constants::GIN_TEMPLATES].first
|
223
|
+
assert_equal File.join(@app.views_dir, "bar.erb"),
|
224
|
+
@ctrl.env[Gin::Constants::GIN_TEMPLATES].last
|
225
|
+
end
|
226
|
+
|
227
|
+
|
228
|
+
def test_view_engine
|
229
|
+
str = @ctrl.view :bar, engine: MockTemplateEngine
|
230
|
+
assert(/Foo Layout/ === str)
|
231
|
+
assert(str !~ /BarHelper/)
|
232
|
+
assert(/mock render/ === str)
|
233
|
+
assert_equal File.join(@app.layouts_dir, "foo.erb"),
|
234
|
+
@ctrl.env[Gin::Constants::GIN_TEMPLATES].first
|
235
|
+
assert_equal File.join(@app.views_dir, "bar.erb"),
|
236
|
+
@ctrl.env[Gin::Constants::GIN_TEMPLATES].last
|
237
|
+
end
|
238
|
+
|
239
|
+
|
240
|
+
def test_view_layout_engine
|
241
|
+
str = @ctrl.view :bar, layout_engine: MockTemplateEngine
|
242
|
+
assert_equal "mock render", str
|
243
|
+
end
|
244
|
+
|
245
|
+
|
246
|
+
def test_view_content_type
|
247
|
+
@ctrl.content_type "text/html"
|
248
|
+
MockTemplateEngine.default_mime_type = "application/json"
|
249
|
+
@ctrl.view :bar, engine: MockTemplateEngine, content_type: "application/xml"
|
250
|
+
assert_equal "application/xml;charset=UTF-8",
|
251
|
+
@ctrl.response[Gin::Constants::CNT_TYPE]
|
252
|
+
end
|
253
|
+
|
254
|
+
|
255
|
+
def test_view_template_content_type
|
256
|
+
@ctrl.response[Gin::Constants::CNT_TYPE] = nil
|
257
|
+
MockTemplateEngine.default_mime_type = "application/json"
|
258
|
+
@ctrl.view :bar, engine: MockTemplateEngine
|
259
|
+
assert_equal "application/json;charset=UTF-8",
|
260
|
+
@ctrl.response[Gin::Constants::CNT_TYPE]
|
261
|
+
end
|
262
|
+
|
263
|
+
|
264
|
+
def test_view_default_content_type
|
265
|
+
@ctrl.content_type "text/html"
|
266
|
+
MockTemplateEngine.default_mime_type = "application/json"
|
267
|
+
@ctrl.view :bar, engine: MockTemplateEngine
|
268
|
+
assert_equal "text/html;charset=UTF-8",
|
269
|
+
@ctrl.response[Gin::Constants::CNT_TYPE]
|
270
|
+
end
|
271
|
+
|
272
|
+
|
273
|
+
def test_config
|
274
|
+
assert_equal @ctrl.app.config.object_id, @ctrl.config.object_id
|
275
|
+
end
|
276
|
+
|
277
|
+
|
91
278
|
def test_etag
|
92
279
|
@ctrl.etag("my-etag")
|
93
280
|
assert_equal "my-etag".inspect, @ctrl.response['ETag']
|
@@ -198,7 +385,7 @@ class ControllerTest < Test::Unit::TestCase
|
|
198
385
|
assert_equal "public, must-revalidate, max-age=60",
|
199
386
|
@ctrl.response['Cache-Control']
|
200
387
|
|
201
|
-
assert_equal
|
388
|
+
assert_equal((time + 60).httpdate, @ctrl.response['Expires'])
|
202
389
|
end
|
203
390
|
|
204
391
|
|
@@ -237,7 +424,6 @@ class ControllerTest < Test::Unit::TestCase
|
|
237
424
|
|
238
425
|
def test_set_cookie
|
239
426
|
exp = Time.now + 360
|
240
|
-
cookie = {:value => "user@example.com", :expires => exp}
|
241
427
|
|
242
428
|
@ctrl.set_cookie "test", "user@example.com", :expires => exp
|
243
429
|
expected = "test=user%40example.com; expires=#{exp.gmtime.strftime("%a, %d %b %Y %H:%M:%S -0000")}"
|
@@ -303,6 +489,7 @@ class ControllerTest < Test::Unit::TestCase
|
|
303
489
|
|
304
490
|
|
305
491
|
def test_dispatch_error
|
492
|
+
@app.options[:environment] = 'development'
|
306
493
|
@ctrl.content_type :json
|
307
494
|
@ctrl.send(:dispatch, :index)
|
308
495
|
assert_equal [:f1, :f2], BarController::FILTERS_RUN
|
@@ -316,7 +503,7 @@ class ControllerTest < Test::Unit::TestCase
|
|
316
503
|
|
317
504
|
|
318
505
|
def test_dispatch_error_nondev
|
319
|
-
|
506
|
+
@app.options[:environment] = "prod"
|
320
507
|
@ctrl.send(:dispatch, :index)
|
321
508
|
|
322
509
|
assert_equal 500, @ctrl.response.status
|
@@ -328,7 +515,7 @@ class ControllerTest < Test::Unit::TestCase
|
|
328
515
|
|
329
516
|
|
330
517
|
def test_dispatch_bad_request_nondev
|
331
|
-
|
518
|
+
@app.options[:environment] = "prod"
|
332
519
|
@ctrl = TestController.new @app, rack_env
|
333
520
|
@ctrl.params.delete('id')
|
334
521
|
@ctrl.send(:dispatch, :show)
|
@@ -341,7 +528,7 @@ class ControllerTest < Test::Unit::TestCase
|
|
341
528
|
|
342
529
|
|
343
530
|
def test_dispatch_not_found_nondev
|
344
|
-
|
531
|
+
@app.options[:environment] = "prod"
|
345
532
|
@ctrl = TestController.new @app, rack_env
|
346
533
|
@ctrl.params.delete('id')
|
347
534
|
@ctrl.send(:dispatch, :not_found)
|
@@ -414,9 +601,12 @@ end
|
|
414
601
|
old_public_dir = MockApp.public_dir
|
415
602
|
MockApp.public_dir File.dirname(__FILE__)
|
416
603
|
|
417
|
-
|
604
|
+
@app = MockApp.new
|
605
|
+
file_id = @app.md5 __FILE__
|
418
606
|
expected = "/test_controller.rb?#{file_id}"
|
419
607
|
|
608
|
+
@ctrl = BarController.new(@app, rack_env)
|
609
|
+
|
420
610
|
assert_equal 8, file_id.length
|
421
611
|
assert_equal expected, @ctrl.asset_url(File.basename(__FILE__))
|
422
612
|
|
@@ -431,10 +621,10 @@ end
|
|
431
621
|
|
432
622
|
|
433
623
|
def test_asset_url_w_host
|
434
|
-
|
624
|
+
@app.options[:asset_host] = "http://example.com"
|
435
625
|
assert_equal "http://example.com/foo.jpg", @ctrl.asset_url("foo.jpg")
|
436
626
|
|
437
|
-
|
627
|
+
@app.options[:asset_host] = proc do |file|
|
438
628
|
file =~ /\.js$/ ? "http://js.example.com" : "http://img.example.com"
|
439
629
|
end
|
440
630
|
assert_equal "http://js.example.com/foo.js", @ctrl.asset_url("foo.js")
|