roda 3.28.0 → 3.29.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (188) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +10 -0
  3. data/README.rdoc +10 -0
  4. data/doc/release_notes/3.29.0.txt +15 -0
  5. data/lib/roda.rb +1 -0
  6. data/lib/roda/plugins/caching.rb +2 -0
  7. data/lib/roda/plugins/common_logger.rb +1 -1
  8. data/lib/roda/plugins/exception_page.rb +7 -1
  9. data/lib/roda/plugins/indifferent_params.rb +2 -0
  10. data/lib/roda/version.rb +1 -1
  11. metadata +4 -214
  12. data/Rakefile +0 -108
  13. data/doc/release_notes/1.0.0.txt +0 -329
  14. data/doc/release_notes/1.1.0.txt +0 -226
  15. data/doc/release_notes/1.2.0.txt +0 -406
  16. data/doc/release_notes/1.3.0.txt +0 -109
  17. data/doc/release_notes/2.0.0.txt +0 -75
  18. data/doc/release_notes/2.1.0.txt +0 -124
  19. data/doc/release_notes/2.10.0.txt +0 -27
  20. data/doc/release_notes/2.11.0.txt +0 -70
  21. data/doc/release_notes/2.12.0.txt +0 -40
  22. data/doc/release_notes/2.13.0.txt +0 -10
  23. data/doc/release_notes/2.14.0.txt +0 -44
  24. data/doc/release_notes/2.15.0.txt +0 -53
  25. data/doc/release_notes/2.16.0.txt +0 -48
  26. data/doc/release_notes/2.17.0.txt +0 -62
  27. data/doc/release_notes/2.18.0.txt +0 -69
  28. data/doc/release_notes/2.19.0.txt +0 -30
  29. data/doc/release_notes/2.2.0.txt +0 -97
  30. data/doc/release_notes/2.20.0.txt +0 -5
  31. data/doc/release_notes/2.21.0.txt +0 -17
  32. data/doc/release_notes/2.22.0.txt +0 -41
  33. data/doc/release_notes/2.23.0.txt +0 -29
  34. data/doc/release_notes/2.24.0.txt +0 -65
  35. data/doc/release_notes/2.25.0.txt +0 -14
  36. data/doc/release_notes/2.26.0.txt +0 -13
  37. data/doc/release_notes/2.27.0.txt +0 -56
  38. data/doc/release_notes/2.28.0.txt +0 -17
  39. data/doc/release_notes/2.29.0.txt +0 -156
  40. data/doc/release_notes/2.3.0.txt +0 -109
  41. data/doc/release_notes/2.4.0.txt +0 -55
  42. data/doc/release_notes/2.5.0.txt +0 -23
  43. data/doc/release_notes/2.5.1.txt +0 -4
  44. data/doc/release_notes/2.6.0.txt +0 -21
  45. data/doc/release_notes/2.7.0.txt +0 -75
  46. data/doc/release_notes/2.8.0.txt +0 -44
  47. data/doc/release_notes/2.9.0.txt +0 -6
  48. data/spec/all.rb +0 -1
  49. data/spec/assets/css/app.scss +0 -1
  50. data/spec/assets/css/no_access.css +0 -1
  51. data/spec/assets/css/raw.css +0 -1
  52. data/spec/assets/js/head/app.js +0 -1
  53. data/spec/composition_spec.rb +0 -31
  54. data/spec/define_roda_method_spec.rb +0 -274
  55. data/spec/env_spec.rb +0 -11
  56. data/spec/freeze_spec.rb +0 -37
  57. data/spec/integration_spec.rb +0 -209
  58. data/spec/matchers_spec.rb +0 -832
  59. data/spec/opts_spec.rb +0 -42
  60. data/spec/plugin/_after_hook_spec.rb +0 -19
  61. data/spec/plugin/all_verbs_spec.rb +0 -29
  62. data/spec/plugin/assets_preloading_spec.rb +0 -98
  63. data/spec/plugin/assets_spec.rb +0 -745
  64. data/spec/plugin/backtracking_array_spec.rb +0 -42
  65. data/spec/plugin/branch_locals_spec.rb +0 -106
  66. data/spec/plugin/caching_spec.rb +0 -337
  67. data/spec/plugin/chunked_spec.rb +0 -201
  68. data/spec/plugin/class_level_routing_spec.rb +0 -164
  69. data/spec/plugin/class_matchers_spec.rb +0 -40
  70. data/spec/plugin/common_logger_spec.rb +0 -85
  71. data/spec/plugin/content_for_spec.rb +0 -162
  72. data/spec/plugin/content_security_policy_spec.rb +0 -175
  73. data/spec/plugin/cookies_spec.rb +0 -51
  74. data/spec/plugin/csrf_spec.rb +0 -111
  75. data/spec/plugin/default_headers_spec.rb +0 -82
  76. data/spec/plugin/default_status_spec.rb +0 -95
  77. data/spec/plugin/delay_build_spec.rb +0 -23
  78. data/spec/plugin/delegate_spec.rb +0 -23
  79. data/spec/plugin/delete_empty_headers_spec.rb +0 -27
  80. data/spec/plugin/direct_call_spec.rb +0 -28
  81. data/spec/plugin/disallow_file_uploads_spec.rb +0 -25
  82. data/spec/plugin/drop_body_spec.rb +0 -24
  83. data/spec/plugin/early_hints_spec.rb +0 -19
  84. data/spec/plugin/empty_root_spec.rb +0 -14
  85. data/spec/plugin/environments_spec.rb +0 -42
  86. data/spec/plugin/error_email_spec.rb +0 -97
  87. data/spec/plugin/error_handler_spec.rb +0 -216
  88. data/spec/plugin/error_mail_spec.rb +0 -93
  89. data/spec/plugin/exception_page_spec.rb +0 -168
  90. data/spec/plugin/flash_spec.rb +0 -121
  91. data/spec/plugin/h_spec.rb +0 -11
  92. data/spec/plugin/halt_spec.rb +0 -119
  93. data/spec/plugin/hash_matcher_spec.rb +0 -27
  94. data/spec/plugin/hash_routes_spec.rb +0 -535
  95. data/spec/plugin/head_spec.rb +0 -52
  96. data/spec/plugin/header_matchers_spec.rb +0 -98
  97. data/spec/plugin/heartbeat_spec.rb +0 -74
  98. data/spec/plugin/hooks_spec.rb +0 -152
  99. data/spec/plugin/indifferent_params_spec.rb +0 -14
  100. data/spec/plugin/json_parser_spec.rb +0 -141
  101. data/spec/plugin/json_spec.rb +0 -83
  102. data/spec/plugin/mail_processor_spec.rb +0 -451
  103. data/spec/plugin/mailer_spec.rb +0 -282
  104. data/spec/plugin/match_affix_spec.rb +0 -43
  105. data/spec/plugin/match_hook_spec.rb +0 -79
  106. data/spec/plugin/middleware_spec.rb +0 -237
  107. data/spec/plugin/middleware_stack_spec.rb +0 -81
  108. data/spec/plugin/module_include_spec.rb +0 -48
  109. data/spec/plugin/multi_route_spec.rb +0 -268
  110. data/spec/plugin/multi_run_spec.rb +0 -87
  111. data/spec/plugin/multi_view_spec.rb +0 -50
  112. data/spec/plugin/multibyte_string_matcher_spec.rb +0 -44
  113. data/spec/plugin/named_templates_spec.rb +0 -96
  114. data/spec/plugin/not_allowed_spec.rb +0 -69
  115. data/spec/plugin/not_found_spec.rb +0 -128
  116. data/spec/plugin/optimized_string_matchers_spec.rb +0 -43
  117. data/spec/plugin/padrino_render_spec.rb +0 -34
  118. data/spec/plugin/param_matchers_spec.rb +0 -69
  119. data/spec/plugin/params_capturing_spec.rb +0 -33
  120. data/spec/plugin/partials_spec.rb +0 -43
  121. data/spec/plugin/pass_spec.rb +0 -29
  122. data/spec/plugin/path_matchers_spec.rb +0 -42
  123. data/spec/plugin/path_rewriter_spec.rb +0 -45
  124. data/spec/plugin/path_spec.rb +0 -222
  125. data/spec/plugin/placeholder_string_matchers_spec.rb +0 -126
  126. data/spec/plugin/precompile_templates_spec.rb +0 -61
  127. data/spec/plugin/public_spec.rb +0 -85
  128. data/spec/plugin/render_each_spec.rb +0 -82
  129. data/spec/plugin/render_locals_spec.rb +0 -114
  130. data/spec/plugin/render_spec.rb +0 -912
  131. data/spec/plugin/request_aref_spec.rb +0 -51
  132. data/spec/plugin/request_headers_spec.rb +0 -39
  133. data/spec/plugin/response_request_spec.rb +0 -43
  134. data/spec/plugin/route_block_args_spec.rb +0 -86
  135. data/spec/plugin/route_csrf_spec.rb +0 -305
  136. data/spec/plugin/run_append_slash_spec.rb +0 -77
  137. data/spec/plugin/run_handler_spec.rb +0 -53
  138. data/spec/plugin/sessions_spec.rb +0 -452
  139. data/spec/plugin/shared_vars_spec.rb +0 -45
  140. data/spec/plugin/sinatra_helpers_spec.rb +0 -537
  141. data/spec/plugin/slash_path_empty_spec.rb +0 -22
  142. data/spec/plugin/static_routing_spec.rb +0 -192
  143. data/spec/plugin/static_spec.rb +0 -30
  144. data/spec/plugin/status_303_spec.rb +0 -28
  145. data/spec/plugin/status_handler_spec.rb +0 -158
  146. data/spec/plugin/streaming_spec.rb +0 -246
  147. data/spec/plugin/strip_path_prefix_spec.rb +0 -24
  148. data/spec/plugin/symbol_matchers_spec.rb +0 -51
  149. data/spec/plugin/symbol_status_spec.rb +0 -25
  150. data/spec/plugin/symbol_views_spec.rb +0 -32
  151. data/spec/plugin/timestamp_public_spec.rb +0 -85
  152. data/spec/plugin/type_routing_spec.rb +0 -348
  153. data/spec/plugin/typecast_params_spec.rb +0 -1370
  154. data/spec/plugin/unescape_path_spec.rb +0 -22
  155. data/spec/plugin/view_options_spec.rb +0 -170
  156. data/spec/plugin_spec.rb +0 -71
  157. data/spec/redirect_spec.rb +0 -41
  158. data/spec/request_spec.rb +0 -97
  159. data/spec/response_spec.rb +0 -199
  160. data/spec/route_spec.rb +0 -39
  161. data/spec/session_middleware_spec.rb +0 -129
  162. data/spec/session_spec.rb +0 -37
  163. data/spec/spec_helper.rb +0 -137
  164. data/spec/version_spec.rb +0 -14
  165. data/spec/views/_test.erb +0 -1
  166. data/spec/views/a.erb +0 -1
  167. data/spec/views/a.rdoc +0 -2
  168. data/spec/views/about.erb +0 -1
  169. data/spec/views/about.str +0 -1
  170. data/spec/views/about/_test.css.gz +0 -0
  171. data/spec/views/about/_test.erb +0 -1
  172. data/spec/views/about/_test.erb.gz +0 -0
  173. data/spec/views/about/comp_test.erb +0 -1
  174. data/spec/views/b.erb +0 -1
  175. data/spec/views/c.erb +0 -1
  176. data/spec/views/comp_layout.erb +0 -1
  177. data/spec/views/comp_test.erb +0 -1
  178. data/spec/views/content-yield.erb +0 -1
  179. data/spec/views/each.str +0 -1
  180. data/spec/views/home.erb +0 -2
  181. data/spec/views/home.str +0 -2
  182. data/spec/views/iv.erb +0 -1
  183. data/spec/views/layout-alternative.erb +0 -2
  184. data/spec/views/layout-yield.erb +0 -3
  185. data/spec/views/layout.erb +0 -2
  186. data/spec/views/layout.str +0 -2
  187. data/spec/views/multiple-layout.erb +0 -1
  188. data/spec/views/multiple.erb +0 -1
@@ -1,42 +0,0 @@
1
- require_relative "spec_helper"
2
-
3
- describe "opts" do
4
- it "is inheritable and allows overriding" do
5
- c = Class.new(Roda)
6
- c.opts[:foo] = "bar"
7
- c.opts[:foo].must_equal "bar"
8
-
9
- sc = Class.new(c)
10
- sc.opts[:foo].must_equal "bar"
11
-
12
- sc.opts[:foo] = "baz"
13
- sc.opts[:foo].must_equal "baz"
14
- c.opts[:foo].must_equal "bar"
15
- end
16
-
17
- it "should be available as an instance methods" do
18
- app(:bare) do
19
- opts[:hello] = "Hello World"
20
-
21
- route do |r|
22
- r.on do
23
- opts[:hello]
24
- end
25
- end
26
- end
27
-
28
- body.must_equal "Hello World"
29
- end
30
-
31
- it "should only shallow clone by default" do
32
- c = Class.new(Roda)
33
- c.opts[:foo] = "bar".dup
34
- c.opts[:foo].must_equal "bar"
35
-
36
- sc = Class.new(c)
37
- sc.opts[:foo].replace("baz")
38
-
39
- sc.opts[:foo].must_equal "baz"
40
- c.opts[:foo].must_equal "baz"
41
- end
42
- end
@@ -1,19 +0,0 @@
1
- require_relative "../spec_helper"
2
-
3
- describe "deprecated _after_hook plugin" do
4
- it "shouldn't break things" do
5
- x = []
6
- app(:_after_hook) do |r|
7
- x << 0
8
- 'a'
9
- end
10
- @app.send(:include, Module.new do
11
- define_method(:_roda_after_00_test){|_| x << 1}
12
- private :_roda_after_00_test
13
- end)
14
-
15
- body.must_equal 'a'
16
- x.must_equal [0, 1]
17
- end
18
- end
19
-
@@ -1,29 +0,0 @@
1
- require_relative "../spec_helper"
2
-
3
- describe "all_verbs plugin" do
4
- it "adds method for each http verb" do
5
- app(:all_verbs) do |r|
6
- r.delete{'d'}
7
- r.head{'h'}
8
- r.options{'o'}
9
- r.patch{'pa'}
10
- r.put{'pu'}
11
- r.trace{'t'}
12
- if Rack::Request.method_defined?(:link?)
13
- r.link{'l'}
14
- r.unlink{'u'}
15
- end
16
- end
17
-
18
- body('REQUEST_METHOD'=>'DELETE').must_equal 'd'
19
- body('REQUEST_METHOD'=>'HEAD').must_equal 'h'
20
- body('REQUEST_METHOD'=>'OPTIONS').must_equal 'o'
21
- body('REQUEST_METHOD'=>'PATCH').must_equal 'pa'
22
- body('REQUEST_METHOD'=>'PUT').must_equal 'pu'
23
- body('REQUEST_METHOD'=>'TRACE').must_equal 't'
24
- if Rack::Request.method_defined?(:link?)
25
- body('REQUEST_METHOD'=>'LINK').must_equal 'l'
26
- body('REQUEST_METHOD'=>'UNLINK').must_equal 'u'
27
- end
28
- end
29
- end
@@ -1,98 +0,0 @@
1
- require_relative "../spec_helper"
2
-
3
- run_tests = true
4
- begin
5
- begin
6
- require 'tilt/sass'
7
- rescue LoadError
8
- begin
9
- for lib in %w'tilt sass'
10
- require lib
11
- end
12
- rescue LoadError
13
- warn "#{lib} not installed, skipping assets_preloading plugin test"
14
- run_tests = false
15
- end
16
- end
17
- end
18
-
19
- describe "assets_preloading plugin" do
20
- before do
21
- app(:bare) do
22
- plugin :assets, {
23
- :css => ['app.scss'],
24
- :js => { :head => ['app.js'] },
25
- :path => 'spec/assets',
26
- :public => 'spec',
27
- }
28
- plugin :assets_preloading
29
-
30
- route do |r|
31
- r.is 'header-css' do
32
- preload_assets_link_header :css
33
- end
34
- r.is 'header-js' do
35
- preload_assets_link_header [:js, :head]
36
- end
37
- r.is 'header-multiple' do
38
- preload_assets_link_header :css, [:js, :head]
39
- end
40
-
41
- r.is 'tags-css' do
42
- preload_assets_link_tags :css
43
- end
44
- r.is 'tags-js' do
45
- preload_assets_link_tags [:js, :head]
46
- end
47
- r.is 'tags-multiple' do
48
- preload_assets_link_tags :css, [:js, :head]
49
- end
50
- end
51
- end
52
- end
53
-
54
- it "preload_assets_link_header returns a well-formed header" do
55
- html = body('/header-multiple')
56
-
57
- assets = html.split(',')
58
- assets.count.must_equal 2
59
-
60
- assets.each do |asset|
61
- parts = asset.split(';')
62
- parts.count.must_equal 3
63
-
64
- parts[0].scan(/^<.*>$/).count.must_equal 1
65
- parts.select{|c| c == 'rel=preload' }.count.must_equal 1
66
- parts.select{|c| c.match(/^as=\w+$/) }.count.must_equal 1
67
- end
68
- end
69
-
70
- it "preload_assets_link_header returns the correct 'as' for an asset type" do
71
- html = body('/header-css')
72
- html.scan('as=style').count.must_equal 1
73
-
74
- html = body('/header-js')
75
- html.scan('as=script').count.must_equal 1
76
- end
77
-
78
- it "preload_assets_link_tags returns well-formed tags" do
79
- html = body('/tags-multiple')
80
-
81
- tags = html.scan(/<link.+?>/)
82
- tags.count.must_equal 2
83
-
84
- tags.each do |tag|
85
- tag.scan(' rel="preload"').count.must_equal 1
86
- tag.scan(/ href=".+"/).count.must_equal 1
87
- tag.scan(/ as=".+"/).count.must_equal 1
88
- end
89
- end
90
-
91
- it "preload_assets_link_tags returns the correct 'as' for an asset type" do
92
- html = body('/tags-css')
93
- html.scan('as="style"').count.must_equal 1
94
-
95
- html = body('/tags-js')
96
- html.scan('as="script"').count.must_equal 1
97
- end
98
- end if run_tests
@@ -1,745 +0,0 @@
1
- require_relative "../spec_helper"
2
- require 'fileutils'
3
-
4
- run_tests = true
5
- begin
6
- begin
7
- require 'tilt/sass'
8
- rescue LoadError
9
- begin
10
- for lib in %w'tilt sass'
11
- require lib
12
- end
13
- rescue LoadError
14
- warn "#{lib} not installed, skipping assets plugin test"
15
- run_tests = false
16
- end
17
- end
18
- end
19
-
20
- if run_tests
21
- metadata_file = File.expand_path('spec/assets/tmp/precompiled.json')
22
- js_file = File.expand_path('spec/assets/js/head/app.js')
23
- css_file = File.expand_path('spec/assets/css/no_access.css')
24
- js_mtime = File.mtime(js_file)
25
- js_atime = File.atime(js_file)
26
- css_mtime = File.mtime(css_file)
27
- css_atime = File.atime(css_file)
28
- describe 'assets plugin' do
29
- before do
30
- app(:bare) do
31
- plugin :assets,
32
- :css => ['app.scss', 'raw.css'],
33
- :js => { :head => ['app.js'] },
34
- :path => 'spec/assets',
35
- :public => 'spec',
36
- :css_opts => {:cache=>false},
37
- :css_compressor => :none,
38
- :js_compressor => :none
39
-
40
- route do |r|
41
- r.assets
42
-
43
- r.is 'test' do
44
- "#{assets(:css)}\n#{assets([:js, :head])}"
45
- end
46
-
47
- r.is 'paths_test' do
48
- css_paths = assets_paths(:css)
49
- js_paths = assets_paths([:js, :head])
50
- empty_paths = assets_paths(:empty)
51
- { 'css' => css_paths, 'js' => js_paths, 'empty' => empty_paths }.map do |k, a|
52
- "#{k}:#{a.class}:#{a.length}:#{a.join(',')}"
53
- end.join("\n")
54
- end
55
- end
56
- end
57
- end
58
- after do
59
- File.utime(js_atime, js_mtime, js_file)
60
- File.utime(css_atime, css_mtime, css_file)
61
- File.delete(metadata_file) if File.file?(metadata_file)
62
- end
63
- after(:all) do
64
- FileUtils.rm_r('spec/assets/tmp') if File.directory?('spec/assets/tmp')
65
- FileUtils.rm_r('spec/public') if File.directory?('spec/public')
66
- FileUtils.rm(Dir['spec/assets/app.*.{js,css}*'])
67
- end
68
-
69
- def gunzip(body)
70
- Zlib::GzipReader.wrap(StringIO.new(body), &:read)
71
- end
72
-
73
- it 'assets_opts should use correct paths given options' do
74
- fpaths = [:js_path, :css_path, :compiled_js_path, :compiled_css_path]
75
- rpaths = [:js_prefix, :css_prefix, :compiled_js_prefix, :compiled_css_prefix]
76
- app.assets_opts.values_at(*fpaths).must_equal %w"spec/assets/js/ spec/assets/css/ spec/assets/app spec/assets/app".map{|s| File.join(Dir.pwd, s)}
77
- app.assets_opts.values_at(*rpaths).must_equal %w"assets/js/ assets/css/ assets/app assets/app"
78
-
79
- app.plugin :assets, :path=>'bar/', :public=>'foo/', :prefix=>'as/', :js_dir=>'j/', :css_dir=>'c/', :compiled_name=>'a'
80
- app.assets_opts.values_at(*fpaths).must_equal %w"bar/j/ bar/c/ foo/as/a foo/as/a".map{|s| File.join(Dir.pwd, s)}
81
- app.assets_opts.values_at(*rpaths).must_equal %w"as/j/ as/c/ as/a as/a"
82
-
83
- app.plugin :assets, :path=>'bar', :public=>'foo', :prefix=>'as', :js_dir=>'j', :css_dir=>'c', :compiled_name=>'a'
84
- app.assets_opts.values_at(*fpaths).must_equal %w"bar/j/ bar/c/ foo/as/a foo/as/a".map{|s| File.join(Dir.pwd, s)}
85
- app.assets_opts.values_at(*rpaths).must_equal %w"as/j/ as/c/ as/a as/a"
86
-
87
- app.plugin :assets, :compiled_js_dir=>'cj', :compiled_css_dir=>'cs', :compiled_path=>'cp'
88
- app.assets_opts.values_at(*fpaths).must_equal %w"bar/j/ bar/c/ foo/cp/cj/a foo/cp/cs/a".map{|s| File.join(Dir.pwd, s)}
89
- app.assets_opts.values_at(*rpaths).must_equal %w"as/j/ as/c/ as/cj/a as/cs/a"
90
-
91
- app.plugin :assets, :compiled_js_route=>'cjr', :compiled_css_route=>'ccr', :js_route=>'jr', :css_route=>'cr'
92
- app.assets_opts.values_at(*fpaths).must_equal %w"bar/j/ bar/c/ foo/cp/cj/a foo/cp/cs/a".map{|s| File.join(Dir.pwd, s)}
93
- app.assets_opts.values_at(*rpaths).must_equal %w"as/jr/ as/cr/ as/cjr/a as/ccr/a"
94
-
95
- app.plugin :assets, :compiled_js_route=>'cj', :compiled_css_route=>'cs', :js_route=>'j', :css_route=>'c'
96
- app.assets_opts.values_at(*fpaths).must_equal %w"bar/j/ bar/c/ foo/cp/cj/a foo/cp/cs/a".map{|s| File.join(Dir.pwd, s)}
97
- app.assets_opts.values_at(*rpaths).must_equal %w"as/j/ as/c/ as/cj/a as/cs/a"
98
-
99
- app.plugin :assets
100
- app.assets_opts.values_at(*fpaths).must_equal %w"bar/j/ bar/c/ foo/cp/cj/a foo/cp/cs/a".map{|s| File.join(Dir.pwd, s)}
101
- app.assets_opts.values_at(*rpaths).must_equal %w"as/j/ as/c/ as/cj/a as/cs/a"
102
-
103
- app.plugin :assets, :compiled_js_dir=>'', :compiled_css_dir=>nil, :compiled_js_route=>nil, :compiled_css_route=>nil
104
- app.assets_opts.values_at(*fpaths).must_equal %w"bar/j/ bar/c/ foo/cp/a foo/cp/a".map{|s| File.join(Dir.pwd, s)}
105
- app.assets_opts.values_at(*rpaths).must_equal %w"as/j/ as/c/ as/a as/a"
106
-
107
- app.plugin :assets, :js_dir=>'', :css_dir=>nil, :js_route=>nil, :css_route=>nil
108
- app.assets_opts.values_at(*fpaths).must_equal %w"bar/ bar/ foo/cp/a foo/cp/a".map{|s| File.join(Dir.pwd, s)}
109
- app.assets_opts.values_at(*rpaths).must_equal %w"as/ as/ as/a as/a"
110
-
111
- app.plugin :assets, :public=>''
112
- app.assets_opts.values_at(*fpaths).must_equal %w"bar/ bar/ cp/a cp/a".map{|s| File.join(Dir.pwd, s)}
113
- app.assets_opts.values_at(*rpaths).must_equal %w"as/ as/ as/a as/a"
114
-
115
- app.plugin :assets, :path=>'', :compiled_path=>nil
116
- app.assets_opts.values_at(*fpaths).must_equal ['', '', 'a', 'a'].map{|s| File.join(Dir.pwd, s)}
117
- app.assets_opts.values_at(*rpaths).must_equal ['as/', 'as/', 'as/a', 'as/a']
118
-
119
- app.plugin :assets, :prefix=>''
120
- app.assets_opts.values_at(*fpaths).must_equal ['', '', 'a', 'a'].map{|s| File.join(Dir.pwd, s)}
121
- app.assets_opts.values_at(*rpaths).must_equal ['', '', 'a', 'a']
122
-
123
- app.plugin :assets, :compiled_name=>nil
124
- app.assets_opts.values_at(*fpaths).must_equal ['', ''].map{|s| File.join(Dir.pwd, s)} + ['', ''].map{|s| File.join(Dir.pwd, s).chop}
125
- app.assets_opts.values_at(*rpaths).must_equal ['', '', '', '']
126
- end
127
-
128
- it 'assets_opts should use headers and dependencies given options' do
129
- keys = [:css_headers, :js_headers, :dependencies]
130
- app.assets_opts.values_at(*keys).must_equal [{'Content-Type'=>"text/css; charset=UTF-8"}, {'Content-Type'=>"application/javascript; charset=UTF-8"}, {}]
131
-
132
- app.plugin :assets, :headers=>{'A'=>'B'}, :dependencies=>{'a'=>'b'}
133
- app.assets_opts.values_at(*keys).must_equal [{'Content-Type'=>"text/css; charset=UTF-8", 'A'=>'B'}, {'Content-Type'=>"application/javascript; charset=UTF-8", 'A'=>'B'}, {'a'=>'b'}]
134
-
135
- app.plugin :assets, :css_headers=>{'C'=>'D'}, :js_headers=>{'E'=>'F'}, :dependencies=>{'c'=>'d'}
136
- app.assets_opts.values_at(*keys).must_equal [{'Content-Type'=>"text/css; charset=UTF-8", 'A'=>'B', 'C'=>'D'}, {'Content-Type'=>"application/javascript; charset=UTF-8", 'A'=>'B', 'E'=>'F'}, {'a'=>'b', 'c'=>'d'}]
137
-
138
- app.plugin :assets
139
- app.assets_opts.values_at(*keys).must_equal [{'Content-Type'=>"text/css; charset=UTF-8", 'A'=>'B', 'C'=>'D'}, {'Content-Type'=>"application/javascript; charset=UTF-8", 'A'=>'B', 'E'=>'F'}, {'a'=>'b', 'c'=>'d'}]
140
-
141
- app.plugin :assets
142
- app.assets_opts.values_at(*keys).must_equal [{'Content-Type'=>"text/css; charset=UTF-8", 'A'=>'B', 'C'=>'D'}, {'Content-Type'=>"application/javascript; charset=UTF-8", 'A'=>'B', 'E'=>'F'}, {'a'=>'b', 'c'=>'d'}]
143
-
144
- app.plugin :assets, :headers=>{'Content-Type'=>'C', 'E'=>'G'}
145
- app.assets_opts.values_at(*keys).must_equal [{'Content-Type'=>"C", 'A'=>'B', 'C'=>'D', 'E'=>'G'}, {'Content-Type'=>"C", 'A'=>'B', 'E'=>'F'}, {'a'=>'b', 'c'=>'d'}]
146
-
147
- app.plugin :assets, :css_headers=>{'A'=>'B1'}, :js_headers=>{'E'=>'F1'}, :dependencies=>{'c'=>'d1'}
148
- app.assets_opts.values_at(*keys).must_equal [{'Content-Type'=>"C", 'A'=>'B1', 'C'=>'D', 'E'=>'G'}, {'Content-Type'=>"C", 'A'=>'B', 'E'=>'F1'}, {'a'=>'b', 'c'=>'d1'}]
149
- end
150
-
151
- it 'assets_paths should return arrays of source paths' do
152
- html = body('/paths_test')
153
- html.scan('css:Array:2:/assets/css/app.scss,/assets/css/raw.css').length.must_equal 1
154
- html.scan('js:Array:1:/assets/js/head/app.js').length.must_equal 1
155
- html.scan('empty:Array:0').length.must_equal 1
156
- end
157
-
158
- it 'assets_paths should return the compiled path in an array' do
159
- app.compile_assets
160
- html = body('/paths_test')
161
- css_hash = app.assets_opts[:compiled]['css']
162
- js_hash = app.assets_opts[:compiled]['js.head']
163
- html.scan("css:Array:1:/assets/app.#{css_hash}.css").length.must_equal 1
164
- html.scan("js:Array:1:/assets/app.head.#{js_hash}.js").length.must_equal 1
165
- html.scan('empty:Array:0').length.must_equal 1
166
- end
167
-
168
- it 'should handle rendering assets, linking to them, and accepting requests for them when not compiling' do
169
- html = body('/test')
170
- html.scan(/<link/).length.must_equal 2
171
- html =~ %r{href="(/assets/css/app\.scss)"}
172
- css = body($1)
173
- html =~ %r{href="(/assets/css/raw\.css)"}
174
- css2 = body($1)
175
- html.scan(/<script/).length.must_equal 1
176
- html =~ %r{src="(/assets/js/head/app\.js)"}
177
- js = body($1)
178
- css.must_match(/color: red;/)
179
- css2.must_match(/color: blue;/)
180
- js.must_include('console.log')
181
- end
182
-
183
- it 'should handle rendering assets, linking to them, and accepting requests for them when :timestamp_paths plugin option is used' do
184
- app.plugin :assets, :timestamp_paths=>true
185
- html = body('/test')
186
- html.scan(/<link/).length.must_equal 2
187
- html =~ %r{href="(/assets/css/\d+/app\.scss)"}
188
- css = body($1)
189
- html =~ %r{href="(/assets/css/\d+/raw\.css)"}
190
- css2 = body($1)
191
- html.scan(/<script/).length.must_equal 1
192
- html =~ %r{src="(/assets/js/\d+/head/app\.js)"}
193
- js = body($1)
194
- css.must_match(/color: red;/)
195
- css2.must_match(/color: blue;/)
196
- js.must_include('console.log')
197
- end
198
-
199
- it 'should handle rendering assets, linking to them, and accepting requests for them when :timestamp_paths plugin option is used with string value' do
200
- app.plugin :assets, :timestamp_paths=>'-'
201
- html = body('/test')
202
- html.scan(/<link/).length.must_equal 2
203
- html =~ %r{href="(/assets/css/\d+-app\.scss)"}
204
- css = body($1)
205
- html =~ %r{href="(/assets/css/\d+-raw\.css)"}
206
- css2 = body($1)
207
- html.scan(/<script/).length.must_equal 1
208
- html =~ %r{src="(/assets/js/\d+-head/app\.js)"}
209
- js = body($1)
210
- css.must_match(/color: red;/)
211
- css2.must_match(/color: blue;/)
212
- js.must_include('console.log')
213
- end
214
-
215
- it 'should handle early hints if the :early_hints option is used' do
216
- app.plugin :assets, :early_hints=>true
217
- eh = []
218
- html = body('/test', 'rack.early_hints'=>proc{|h| eh << h})
219
- eh.must_equal [
220
- {"Link"=>"</assets/css/app.scss>; rel=preload; as=style\n</assets/css/raw.css>; rel=preload; as=style"},
221
- {"Link"=>"</assets/js/head/app.js>; rel=preload; as=script"}
222
- ]
223
- html.scan(/<link/).length.must_equal 2
224
- html =~ %r{href="(/assets/css/app\.scss)"}
225
- css = body($1)
226
- html =~ %r{href="(/assets/css/raw\.css)"}
227
- css2 = body($1)
228
- html.scan(/<script/).length.must_equal 1
229
- html =~ %r{src="(/assets/js/head/app\.js)"}
230
- js = body($1)
231
- css.must_match(/color: red;/)
232
- css2.must_match(/color: blue;/)
233
- js.must_include('console.log')
234
- end
235
-
236
- it 'should handle rendering assets, linking to them, and accepting requests for them when :add_script_name app option is used' do
237
- app.opts[:add_script_name] = true
238
- app.plugin :assets
239
- html = body('/test', 'SCRIPT_NAME'=>'/foo')
240
- html.scan(/<link/).length.must_equal 2
241
- html =~ %r{href="/foo(/assets/css/app\.scss)"}
242
- css = body($1)
243
- html =~ %r{href="/foo(/assets/css/raw\.css)"}
244
- css2 = body($1)
245
- html.scan(/<script/).length.must_equal 1
246
- html =~ %r{src="/foo(/assets/js/head/app\.js)"}
247
- js = body($1)
248
- css.must_match(/color: red;/)
249
- css2.must_match(/color: blue;/)
250
- js.must_include('console.log')
251
- end
252
-
253
- it 'should handle rendering assets, linking to them, and accepting requests for them when not compiling, with different options' do
254
- app.plugin :assets, :path=>'spec/', :js_dir=>'assets/js', :css_dir=>'assets/css', :prefix=>'a',
255
- :js_route=>'foo', :css_route=>'bar', :add_suffix=>true, :css_opts=>{:style=>:compressed}
256
- html = body('/test')
257
- html.scan(/<link/).length.must_equal 2
258
- html =~ %r{href="(/a/bar/app\.scss.css)"}
259
- css = body($1)
260
- html =~ %r{href="(/a/bar/raw\.css.css)"}
261
- css2 = body($1)
262
- html.scan(/<script/).length.must_equal 1
263
- html =~ %r{src="(/a/foo/head/app\.js.js)"}
264
- js = body($1)
265
- css.must_match(/color:red\}/)
266
- css2.must_match(/color: blue;/)
267
- js.must_include('console.log')
268
- end
269
-
270
- it 'should handle rendering assets, linking to them, and accepting requests for them when not compiling with a multi-level hash' do
271
- app.plugin :assets, :path=>'spec', :js_dir=>nil, :css_dir=>nil, :prefix=>nil,
272
- :css=>{:assets=>{:css=>%w'app.scss raw.css'}}, :js=>{:assets=>{:js=>{:head=>'app.js'}}}
273
- app.route do |r|
274
- r.assets
275
- r.is 'test' do
276
- "#{assets([:css, :assets, :css])}\n#{assets([:js, :assets, :js, :head])}"
277
- end
278
- end
279
- html = body('/test')
280
- html.scan(/<link/).length.must_equal 2
281
- html =~ %r{href="(/assets/css/app\.scss)"}
282
- css = body($1)
283
- html =~ %r{href="(/assets/css/raw\.css)"}
284
- css2 = body($1)
285
- html.scan(/<script/).length.must_equal 1
286
- html =~ %r{src="(/assets/js/head/app\.js)"}
287
- js = body($1)
288
- css.must_match(/color: red;/)
289
- css2.must_match(/color: blue;/)
290
- js.must_include('console.log')
291
- end
292
-
293
- it 'should handle :group_subdirs => false' do
294
- app.plugin :assets, :path=>'spec', :js_dir=>nil, :css_dir=>nil, :prefix=>nil, :group_subdirs=>false,
295
- :css=>{:assets=>{:css=>%w'assets/css/app.scss assets/css/raw.css'}}, :js=>{:assets=>{:js=>{:head=>'assets/js/head/app.js'}}}
296
- app.route do |r|
297
- r.assets
298
- r.is 'test' do
299
- "#{assets([:css, :assets, :css])}\n#{assets([:js, :assets, :js, :head])}"
300
- end
301
- end
302
- html = body('/test')
303
- html.scan(/<link/).length.must_equal 2
304
- html =~ %r{href="(/assets/css/app\.scss)"}
305
- css = body($1)
306
- html =~ %r{href="(/assets/css/raw\.css)"}
307
- css2 = body($1)
308
- html.scan(/<script/).length.must_equal 1
309
- html =~ %r{src="(/assets/js/head/app\.js)"}
310
- js = body($1)
311
- css.must_match(/color: red;/)
312
- css2.must_match(/color: blue;/)
313
- js.must_include('console.log')
314
- end
315
-
316
- it 'should handle compressing using different libraries' do
317
- try_compressor = proc do |css, js|
318
- app.plugin :assets, :css_compressor=>css, :js_compressor=>js
319
- begin
320
- app.compile_assets
321
- rescue LoadError, Roda::RodaPlugins::Assets::CompressorNotFound
322
- next
323
- end
324
- File.read("spec/assets/app.#{app.assets_opts[:compiled]['css']}.css").must_match(/color: ?blue/)
325
- File.read("spec/assets/app.head.#{app.assets_opts[:compiled]['js.head']}.js").must_include('console.log')
326
- end
327
-
328
- try_compressor.call(nil, nil)
329
- try_compressor.call(:yui, :yui)
330
- try_compressor.call(:none, :closure)
331
- try_compressor.call(:none, :uglifier)
332
- try_compressor.call(:none, :minjs)
333
- end
334
-
335
- it 'should handle compiling assets, linking to them, and accepting requests for them' do
336
- app.plugin :assets, :js=>{:head => %w'comment_1.js comment_2.js'}
337
- app.compile_assets
338
- html = body('/test')
339
- html.scan(/<script/).length.must_equal 1
340
- html =~ %r{src="(/assets/app\.head\.[a-f0-9]{64}\.js)"}
341
- js = body($1)
342
- js.must_equal <<END
343
- // test
344
- /*
345
- a = 1;
346
- */
347
- END
348
- end
349
-
350
- it 'should separate compiled assets with new lines' do
351
- app.compile_assets
352
- html = body('/test')
353
- html.scan(/<link/).length.must_equal 1
354
- html =~ %r{href="(/assets/app\.[a-f0-9]{64}\.css)"}
355
- css = body($1)
356
- html.scan(/<script/).length.must_equal 1
357
- html =~ %r{src="(/assets/app\.head\.[a-f0-9]{64}\.js)"}
358
- js = body($1)
359
- css.must_match(/color: ?red/)
360
- css.must_match(/color: ?blue/)
361
- js.must_include('console.log')
362
- end
363
-
364
- [[:sha256, 64, 44], [:sha384, 96, 64], [:sha512, 128, 88]].each do |algo, hex_length, base64_length|
365
- it "should handle :sri option for subresource integrity #{algo} when compiling assets" do
366
- app.plugin :assets, :sri=>algo
367
- app.compile_assets
368
- html = body('/test')
369
- html.scan(/<link/).length.must_equal 1
370
- html =~ %r|et" integrity="#{algo}-([^"]+)"|
371
- css_hash = $1
372
- css_hash.length.must_equal base64_length
373
- html =~ %r|href="(/assets/app\.[a-f0-9]{#{hex_length}}\.css)"|
374
- css = body($1)
375
- [Digest.const_get(algo.to_s.upcase).digest(css)].pack('m').tr("\n", "").must_equal css_hash
376
- html.scan(/<script/).length.must_equal 1
377
- html =~ %r|pt" integrity="#{algo}-([^"]+)"|
378
- js_hash = $1
379
- js_hash.length.must_equal base64_length
380
- html =~ %r|src="(/assets/app\.head\.[a-f0-9]{#{hex_length}}\.js)"|
381
- js = body($1)
382
- [Digest.const_get(algo.to_s.upcase).digest(js)].pack('m').tr("\n", "").must_equal js_hash
383
- css.must_match(/color: ?red/)
384
- css.must_match(/color: ?blue/)
385
- js.must_include('console.log')
386
- end
387
- end
388
-
389
- it "should handle :sri=>nil option for to disable subresource integrity when compiling assets" do
390
- app.plugin :assets, :sri=>nil
391
- app.compile_assets
392
- html = body('/test')
393
- html.scan(/<link/).length.must_equal 1
394
- html.scan(/<script/).length.must_equal 1
395
- html.wont_match %r|et" integrity="|
396
- html =~ %r|href="(/assets/app\.[a-f0-9]{64}\.css)"|
397
- css = body($1)
398
- html =~ %r|src="(/assets/app\.head\.[a-f0-9]{64}\.js)"|
399
- js = body($1)
400
- css.must_match(/color: ?red/)
401
- css.must_match(/color: ?blue/)
402
- js.must_include('console.log')
403
- end
404
-
405
- it 'should handle linking to compiled assets when a compiled asset host is used' do
406
- app.plugin :assets, :compiled_asset_host=>'https://cdn.example.com'
407
- app.compile_assets
408
- html = body('/test')
409
- html.scan(/<link/).length.must_equal 1
410
- html.must_match %r{href="https://cdn\.example\.com/assets/app\.[a-f0-9]{64}\.css"}
411
- html.scan(/<script/).length.must_equal 1
412
- html.must_match %r{src="https://cdn\.example\.com/assets/app\.head\.[a-f0-9]{64}\.js"}
413
- end
414
-
415
- it 'should handle compiling assets, linking to them, and accepting requests for them when :gzip is set' do
416
- app.plugin :assets, :gzip=>true
417
- app.compile_assets
418
- html = body('/test')
419
- html.scan(/<link/).length.must_equal 1
420
- html =~ %r{href="(/assets/app\.[a-f0-9]{64}\.css)"}
421
- css_path = $1
422
- html.scan(/<script/).length.must_equal 1
423
- html =~ %r{src="(/assets/app\.head\.[a-f0-9]{64}\.js)"}
424
- js_path = $1
425
-
426
- css = body(css_path)
427
- js = body(js_path)
428
- css.must_match(/color: ?red/)
429
- css.must_match(/color: ?blue/)
430
- js.must_include('console.log')
431
-
432
- css = gunzip(body(css_path, 'HTTP_ACCEPT_ENCODING'=>'deflate, gzip'))
433
- js = gunzip(body(js_path, 'HTTP_ACCEPT_ENCODING'=>'deflate, gzip'))
434
- css.must_match(/color: ?red/)
435
- css.must_match(/color: ?blue/)
436
- js.must_include('console.log')
437
- end
438
-
439
- it 'should handle compiling assets, linking to them, and accepting requests for them when :add_script_name app option is used' do
440
- app.opts[:add_script_name] = true
441
- app.plugin :assets
442
- app.compile_assets
443
- html = body('/test', 'SCRIPT_NAME'=>'/foo')
444
- html =~ %r{href="/foo(/assets/app\.[a-f0-9]{64}\.css)"}
445
- css = body($1)
446
- html.scan(/<script/).length.must_equal 1
447
- html =~ %r{src="/foo(/assets/app\.head\.[a-f0-9]{64}\.js)"}
448
- js = body($1)
449
- css.must_match(/color: ?red/)
450
- css.must_match(/color: ?blue/)
451
- js.must_include('console.log')
452
- end
453
-
454
- it 'should handle compiling assets, linking to them, and accepting requests for them, with different options' do
455
- app.plugin :assets, :compiled_path=>nil, :js_dir=>'assets/js', :css_dir=>'assets/css', :prefix=>'a',
456
- :public=>'spec/assets', :path=>'spec', :compiled_js_route=>'foo', :compiled_css_route=>'bar'
457
- app.compile_assets
458
- html = body('/test')
459
- html.scan(/<link/).length.must_equal 1
460
- html =~ %r{href="(/a/bar/app\.[a-f0-9]{64}\.css)"}
461
- css = body($1)
462
- html.scan(/<script/).length.must_equal 1
463
- html =~ %r{src="(/a/foo/app\.head\.[a-f0-9]{64}\.js)"}
464
- js = body($1)
465
- css.must_match(/color: ?red/)
466
- css.must_match(/color: ?blue/)
467
- js.must_include('console.log')
468
- end
469
-
470
- it 'should handle rendering assets, linking to them, and accepting requests for them when not compiling with a multi-level hash' do
471
- app.plugin :assets, :path=>'spec', :js_dir=>nil, :css_dir=>nil, :compiled_js_dir=>nil, :compiled_css_dir=>nil,
472
- :css=>{:assets=>{:css=>%w'app.scss raw.css'}}, :js=>{:assets=>{:js=>{:head=>'app.js'}}}
473
- app.compile_assets
474
- app.route do |r|
475
- r.assets
476
- r.is 'test' do
477
- "#{assets([:css, :assets, :css])}\n#{assets([:js, :assets, :js, :head])}"
478
- end
479
- end
480
- html = body('/test')
481
- html.scan(/<link/).length.must_equal 1
482
- html =~ %r{href="(/assets/app\.assets\.css\.[a-f0-9]{64}\.css)"}
483
- css = body($1)
484
- html.scan(/<script/).length.must_equal 1
485
- html =~ %r{src="(/assets/app\.assets\.js\.head\.[a-f0-9]{64}\.js)"}
486
- js = body($1)
487
- css.must_match(/color: ?red/)
488
- css.must_match(/color: ?blue/)
489
- js.must_include('console.log')
490
- end
491
-
492
- it 'should handle rendering assets, linking to them, and accepting requests for them when not compiling with a multi-level hash when :add_script_name app option is used' do
493
- app.opts[:add_script_name] = true
494
- app.plugin :assets, :path=>'spec', :js_dir=>nil, :css_dir=>nil, :compiled_js_dir=>nil, :compiled_css_dir=>nil,
495
- :css=>{:assets=>{:css=>%w'app.scss raw.css'}}, :js=>{:assets=>{:js=>{:head=>'app.js'}}}
496
- app.compile_assets
497
- app.route do |r|
498
- r.assets
499
- r.is 'test' do
500
- "#{assets([:css, :assets, :css])}\n#{assets([:js, :assets, :js, :head])}"
501
- end
502
- end
503
- html = body('/test', 'SCRIPT_NAME'=>'/foo')
504
- html.scan(/<link/).length.must_equal 1
505
- html =~ %r{href="/foo(/assets/app\.assets\.css\.[a-f0-9]{64}\.css)"}
506
- css = body($1)
507
- html.scan(/<script/).length.must_equal 1
508
- html =~ %r{src="/foo(/assets/app\.assets\.js\.head\.[a-f0-9]{64}\.js)"}
509
- js = body($1)
510
- css.must_match(/color: ?red/)
511
- css.must_match(/color: ?blue/)
512
- js.must_include('console.log')
513
- end
514
-
515
- it 'should handle :group_subdirs => false when compiling' do
516
- app.plugin :assets, :path=>'spec', :js_dir=>nil, :css_dir=>nil, :compiled_js_dir=>nil, :compiled_css_dir=>nil, :group_subdirs=>false,
517
- :css=>{:assets=>{:css=>%w'assets/css/app.scss assets/css/raw.css'}}, :js=>{:assets=>{:js=>{:head=>'assets/js/head/app.js'}}}
518
- app.compile_assets
519
- app.route do |r|
520
- r.assets
521
- r.is 'test' do
522
- "#{assets([:css, :assets, :css])}\n#{assets([:js, :assets, :js, :head])}"
523
- end
524
- end
525
- html = body('/test')
526
- html.scan(/<link/).length.must_equal 1
527
- html =~ %r{href="(/assets/app\.assets\.css\.[a-f0-9]{64}\.css)"}
528
- css = body($1)
529
- html.scan(/<script/).length.must_equal 1
530
- html =~ %r{src="(/assets/app\.assets\.js\.head\.[a-f0-9]{64}\.js)"}
531
- js = body($1)
532
- css.must_match(/color: ?red/)
533
- css.must_match(/color: ?blue/)
534
- js.must_include('console.log')
535
- end
536
-
537
- it 'should handle automatically creating directories when compiling assets' do
538
- app.plugin :assets, :public=>'spec/public'
539
- app.compile_assets
540
- html = body('/test')
541
- html.scan(/<link/).length.must_equal 1
542
- html =~ %r{href="(/assets/app\.[a-f0-9]{64}\.css)"}
543
- css = body($1)
544
- html.scan(/<script/).length.must_equal 1
545
- html =~ %r{src="(/assets/app\.head\.[a-f0-9]{64}\.js)"}
546
- js = body($1)
547
- css.must_match(/color: ?red/)
548
- css.must_match(/color: ?blue/)
549
- js.must_include('console.log')
550
- end
551
-
552
- it 'should handle compiling only css assets' do
553
- app.compile_assets(:css)
554
- html = body('/test')
555
- html.scan(/<link/).length.must_equal 1
556
- html =~ %r{href="(/assets/app\.[a-f0-9]{64}\.css)"}
557
- css = body($1)
558
- html.scan(/<script/).length.must_equal 0
559
- css.must_match(/color: ?red/)
560
- css.must_match(/color: ?blue/)
561
- end
562
-
563
- it 'should handle compiling only js assets' do
564
- app.compile_assets(:js)
565
- html = body('/test')
566
- html.scan(/<link/).length.must_equal 0
567
- html.scan(/<script/).length.must_equal 1
568
- html =~ %r{src="(/assets/app\.head\.[a-f0-9]{64}\.js)"}
569
- js = body($1)
570
- js.must_include('console.log')
571
- end
572
-
573
- it 'should handle compiling asset subfolders' do
574
- app.compile_assets([:js, :head])
575
- html = body('/test')
576
- html.scan(/<link/).length.must_equal 0
577
- html.scan(/<script/).length.must_equal 1
578
- html =~ %r{src="(/assets/app\.head\.[a-f0-9]{64}\.js)"}
579
- js = body($1)
580
- js.must_include('console.log')
581
- end
582
-
583
- it 'should handle compiling assets when only a single asset type is present' do
584
- app.plugin :assets, :css=>nil
585
- app.compile_assets
586
- html = body('/test')
587
- html.scan(/<link/).length.must_equal 0
588
- html.scan(/<script/).length.must_equal 1
589
- html =~ %r{src="(/assets/app\.head\.[a-f0-9]{64}\.js)"}
590
- js = body($1)
591
- js.must_include('console.log')
592
- end
593
-
594
- it 'should handle compiling assets when an empty array is used' do
595
- app.plugin :assets, :css=>[]
596
- app.compile_assets
597
- html = body('/test')
598
- html.scan(/<link/).length.must_equal 0
599
- html.scan(/<script/).length.must_equal 1
600
- html =~ %r{src="(/assets/app\.head\.[a-f0-9]{64}\.js)"}
601
- js = body($1)
602
- js.must_include('console.log')
603
- end
604
-
605
- it '#assets must_include attributes given' do
606
- app.allocate.assets([:js, :head], 'a'=>'b').must_equal '<script type="text/javascript" a="b" src="/assets/js/head/app.js"></script>'
607
- end
608
-
609
- it '#assets should escape attribute values given' do
610
- app.allocate.assets([:js, :head], 'a'=>'b"e').must_equal '<script type="text/javascript" a="b&quot;e" src="/assets/js/head/app.js"></script>'
611
- end
612
-
613
- it 'requests for assets should return 304 if the asset has not been modified' do
614
- loc = '/assets/js/head/app.js'
615
- lm = header('Last-Modified', loc)
616
- status(loc, 'HTTP_IF_MODIFIED_SINCE'=>lm).must_equal 304
617
- body(loc, 'HTTP_IF_MODIFIED_SINCE'=>lm).must_equal ''
618
- end
619
-
620
- it 'requests for assets should not return 304 if the asset has been modified' do
621
- loc = '/assets/js/head/app.js'
622
- lm = header('Last-Modified', loc)
623
- File.utime(js_atime, js_mtime+1, js_file)
624
- status(loc, 'HTTP_IF_MODIFIED_SINCE'=>lm).must_equal 200
625
- body(loc, 'HTTP_IF_MODIFIED_SINCE'=>lm).must_include('console.log')
626
- end
627
-
628
- it 'requests for assets should return 304 if the dependency of an asset has not been modified' do
629
- app.plugin :assets, :dependencies=>{js_file=>css_file}
630
- loc = '/assets/js/head/app.js'
631
- lm = header('Last-Modified', loc)
632
- status(loc, 'HTTP_IF_MODIFIED_SINCE'=>lm).must_equal 304
633
- body(loc, 'HTTP_IF_MODIFIED_SINCE'=>lm).must_equal ''
634
- end
635
-
636
- it 'requests for assets should return 200 if the dependency of an asset has been modified' do
637
- app.plugin :assets, :dependencies=>{js_file=>css_file}
638
- loc = '/assets/js/head/app.js'
639
- lm = header('Last-Modified', loc)
640
- File.utime(css_atime, [css_mtime+2, js_mtime+2].max, css_file)
641
- status(loc, 'HTTP_IF_MODIFIED_SINCE'=>lm).must_equal 200
642
- body(loc, 'HTTP_IF_MODIFIED_SINCE'=>lm).must_include('console.log')
643
- end
644
-
645
- it 'should do a terminal match for assets' do
646
- status('/assets/css/app.scss/foo').must_equal 404
647
- end
648
-
649
- it 'should only allow files that you specify' do
650
- status('/assets/css/no_access.css').must_equal 404
651
- end
652
-
653
- it 'should not add routes for empty asset types' do
654
- app.plugin :assets, :css=>nil
655
- a = app::RodaRequest.assets_matchers
656
- a.length.must_equal 1
657
- a.first.length.must_equal 2
658
- a.first.first.must_equal :js
659
- 'assets/js/head/app.js'.must_match a.first.last
660
- 'assets/js/head/app2.js'.wont_match a.first.last
661
- end
662
-
663
- it 'should not add routes if no asset types' do
664
- app.plugin :assets, :js=>nil, :css=>nil
665
- app::RodaRequest.assets_matchers.must_equal []
666
- end
667
-
668
- it 'should support :postprocessor option' do
669
- postprocessor = lambda do |file, type, content|
670
- "file=#{file} type=#{type} tc=#{type.class} #{content.sub('color', 'font')}"
671
- end
672
-
673
- app.plugin :assets, :path=>'spec', :js_dir=>nil, :css_dir=>nil, :prefix=>nil,
674
- :postprocessor=>postprocessor,
675
- :css=>{:assets=>{:css=>%w'app.scss'}}
676
- app.route do |r|
677
- r.assets
678
- r.is 'test' do
679
- "#{assets([:css, :assets, :css])}"
680
- end
681
- end
682
- html = body('/test')
683
- html.scan(/<link/).length.must_equal 1
684
- html =~ %r{href="(/assets/css/app\.scss)"}
685
- css = body($1)
686
- css.must_match(/app\.scss/)
687
- css.must_match(/type=css/)
688
- css.must_match(/tc=Symbol/)
689
- css.must_match(/font: red;/)
690
- end
691
-
692
- it 'should support :precompiled option' do
693
- app.plugin :assets, :precompiled=>metadata_file
694
- File.exist?(metadata_file).must_equal false
695
- app.allocate.assets([:js, :head]).must_equal '<script type="text/javascript" src="/assets/js/head/app.js"></script>'
696
-
697
- app.compile_assets
698
- File.exist?(metadata_file).must_equal true
699
- app.allocate.assets([:js, :head]).must_match %r{src="(/assets/app\.head\.[a-f0-9]{64}\.js)"}
700
-
701
- app.plugin :assets, :compiled=>false, :precompiled=>false
702
- app.allocate.assets([:js, :head]).must_equal '<script type="text/javascript" src="/assets/js/head/app.js"></script>'
703
-
704
- app.plugin :assets, :precompiled=>metadata_file
705
- app.allocate.assets([:js, :head]).must_match %r{src="(/assets/app\.head\.[a-f0-9]{64}\.js)"}
706
- end
707
-
708
- it 'should work correctly with json plugin when r.assets is the last method called' do
709
- app.plugin :assets
710
- app.plugin :json
711
- app.route do |r|
712
- r.assets
713
- end
714
- status.must_equal 404
715
- end
716
- end
717
-
718
- describe 'assets plugin' do
719
- it "app :root option affects :views default" do
720
- app.plugin :assets
721
- app.assets_opts[:path].must_equal File.join(Dir.pwd, 'assets')
722
- app.assets_opts[:js_path].must_equal File.join(Dir.pwd, 'assets/js/')
723
- app.assets_opts[:css_path].must_equal File.join(Dir.pwd, 'assets/css/')
724
-
725
- app.opts[:root] = '/foo'
726
- app.plugin :assets
727
- # Work around for Windows
728
- app.assets_opts[:path].sub(/\A\w:/, '').must_equal '/foo/assets'
729
- app.assets_opts[:js_path].sub(/\A\w:/, '').must_equal '/foo/assets/js/'
730
- app.assets_opts[:css_path].sub(/\A\w:/, '').must_equal '/foo/assets/css/'
731
-
732
- app.opts[:root] = '/foo/bar'
733
- app.plugin :assets
734
- app.assets_opts[:path].sub(/\A\w:/, '').must_equal '/foo/bar/assets'
735
- app.assets_opts[:js_path].sub(/\A\w:/, '').must_equal '/foo/bar/assets/js/'
736
- app.assets_opts[:css_path].sub(/\A\w:/, '').must_equal '/foo/bar/assets/css/'
737
-
738
- app.opts[:root] = nil
739
- app.plugin :assets
740
- app.assets_opts[:path].must_equal File.join(Dir.pwd, 'assets')
741
- app.assets_opts[:js_path].must_equal File.join(Dir.pwd, 'assets/js/')
742
- app.assets_opts[:css_path].must_equal File.join(Dir.pwd, 'assets/css/')
743
- end
744
- end
745
- end