roda 3.28.0 → 3.29.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.
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