rad_core 0.0.13

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 (258) hide show
  1. data/Rakefile +10 -0
  2. data/lib/rad/controller/abstract_controller/micelaneous.rb +31 -0
  3. data/lib/rad/controller/abstract_controller/render.rb +160 -0
  4. data/lib/rad/controller/abstract_controller/responder.rb +17 -0
  5. data/lib/rad/controller/abstract_controller.rb +64 -0
  6. data/lib/rad/controller/controller_context.rb +15 -0
  7. data/lib/rad/controller/http_controller.rb +48 -0
  8. data/lib/rad/controller/processors/controller_caller.rb +28 -0
  9. data/lib/rad/controller/processors/controller_error_handling.rb +51 -0
  10. data/lib/rad/controller/processors/controller_logger.rb +12 -0
  11. data/lib/rad/controller.rb +28 -0
  12. data/lib/rad/conveyor/conveyor.rb +74 -0
  13. data/lib/rad/conveyor/conveyors.rb +20 -0
  14. data/lib/rad/conveyor/params.rb +14 -0
  15. data/lib/rad/conveyor/processor.rb +68 -0
  16. data/lib/rad/conveyor/processors/conveyor_logger.rb +25 -0
  17. data/lib/rad/conveyor/workspace.rb +36 -0
  18. data/lib/rad/conveyor.rb +29 -0
  19. data/lib/rad/environment/config.rb +111 -0
  20. data/lib/rad/environment/dependency_resolver.rb +107 -0
  21. data/lib/rad/environment/environment.rb +29 -0
  22. data/lib/rad/environment/files_helper.rb +55 -0
  23. data/lib/rad/environment/logger.rb +21 -0
  24. data/lib/rad/environment.rb +55 -0
  25. data/lib/rad/html/flash.rb +42 -0
  26. data/lib/rad/html/helpers/basic_html_helper.rb +83 -0
  27. data/lib/rad/html/helpers/flash_helper.rb +5 -0
  28. data/lib/rad/html/helpers/form_helper.rb +115 -0
  29. data/lib/rad/html/helpers/html_helper.rb +5 -0
  30. data/lib/rad/html/helpers/javascript_helper.rb +18 -0
  31. data/lib/rad/html/helpers/model_helper.rb +135 -0
  32. data/lib/rad/html/include_into_controller.rb +0 -0
  33. data/lib/rad/html/processors/prepare_flash.rb +26 -0
  34. data/lib/rad/html/processors/scoped_params.rb +26 -0
  35. data/lib/rad/html.rb +26 -0
  36. data/lib/rad/http/http.rb +21 -0
  37. data/lib/rad/http/http_adapter.rb +36 -0
  38. data/lib/rad/http/middleware/static_files.rb +21 -0
  39. data/lib/rad/http/processors/evaluate_format.rb +22 -0
  40. data/lib/rad/http/processors/http_logger.rb +15 -0
  41. data/lib/rad/http/processors/http_writer.rb +30 -0
  42. data/lib/rad/http/processors/prepare_params.rb +22 -0
  43. data/lib/rad/http/support/rack/fixes.rb +36 -0
  44. data/lib/rad/http/support/rack/rack_adapter.rb +67 -0
  45. data/lib/rad/http/support/rack/request.rb +42 -0
  46. data/lib/rad/http/support/rack/response.rb +86 -0
  47. data/lib/rad/http.rb +48 -0
  48. data/lib/rad/integration/controller_micelaneous_helper.rb +19 -0
  49. data/lib/rad/integration/router/abstract_routing_helper.rb +22 -0
  50. data/lib/rad/integration/router/controller_routing_helper.rb +58 -0
  51. data/lib/rad/integration/router/view_routing_helper.rb +104 -0
  52. data/lib/rad/integration.rb +30 -0
  53. data/lib/rad/mail/letter.rb +30 -0
  54. data/lib/rad/mail/mail_controller.rb +31 -0
  55. data/lib/rad/mail/mailer.rb +23 -0
  56. data/lib/rad/mail/processors/letter_builder.rb +36 -0
  57. data/lib/rad/mail.rb +15 -0
  58. data/lib/rad/profiles/mail.rb +16 -0
  59. data/lib/rad/profiles/web.rb +68 -0
  60. data/lib/rad/profiles/web_require.rb +5 -0
  61. data/lib/rad/remote/processors/remote_caller.rb +54 -0
  62. data/lib/rad/remote/processors/remote_logger.rb +13 -0
  63. data/lib/rad/remote/remote.rb +15 -0
  64. data/lib/rad/remote.rb +9 -0
  65. data/lib/rad/router/core/configurator.rb +25 -0
  66. data/lib/rad/router/core/core_routing_helper.rb +41 -0
  67. data/lib/rad/router/core/default_format_processor.rb +12 -0
  68. data/lib/rad/router/core/processors/router.rb +29 -0
  69. data/lib/rad/router/core/router.rb +271 -0
  70. data/lib/rad/router/core/simple_router.rb +23 -0
  71. data/lib/rad/router/routers/abstract_router.rb +62 -0
  72. data/lib/rad/router/routers/alias_router.rb +113 -0
  73. data/lib/rad/router/routers/restful_router.rb +113 -0
  74. data/lib/rad/router.rb +29 -0
  75. data/lib/rad/spec/controller.rb +41 -0
  76. data/lib/rad/spec/environment.rb +51 -0
  77. data/lib/rad/spec/http.rb +93 -0
  78. data/lib/rad/spec/mail.rb +31 -0
  79. data/lib/rad/spec/remote.rb +9 -0
  80. data/lib/rad/spec/router.rb +18 -0
  81. data/lib/rad/spec/template.rb +12 -0
  82. data/lib/rad/spec/view.rb +10 -0
  83. data/lib/rad/spec/xhtml.rb +33 -0
  84. data/lib/rad/spec.rb +11 -0
  85. data/lib/rad/support/active_support/locales/en/actionpack.yml +154 -0
  86. data/lib/rad/support/active_support/locales/en/activesupport.yml +36 -0
  87. data/lib/rad/support/active_support/micelaneous.rb +2 -0
  88. data/lib/rad/support/active_support/time.rb +105 -0
  89. data/lib/rad/support/active_support.rb +49 -0
  90. data/lib/rad/support/addressable.rb +45 -0
  91. data/lib/rad/support/buffered_logger.rb +44 -0
  92. data/lib/rad/support/callbacks.rb +168 -0
  93. data/lib/rad/support/exception.rb +31 -0
  94. data/lib/rad/support/filters.rb +34 -0
  95. data/lib/rad/support/format.rb +17 -0
  96. data/lib/rad/support/hacks_and_fixes.rb +23 -0
  97. data/lib/rad/support/micon.rb +13 -0
  98. data/lib/rad/support/mime.rb +13 -0
  99. data/lib/rad/support/module.rb +48 -0
  100. data/lib/rad/support/rson.rb +53 -0
  101. data/lib/rad/support/ruby_ext_with_active_support.rb +4 -0
  102. data/lib/rad/support/string.rb +26 -0
  103. data/lib/rad/support.rb +63 -0
  104. data/lib/rad/template/support/tilt.rb +68 -0
  105. data/lib/rad/template/support/tilt_fixes.rb +17 -0
  106. data/lib/rad/template/template.rb +250 -0
  107. data/lib/rad/template/template_context.rb +62 -0
  108. data/lib/rad/template.rb +25 -0
  109. data/lib/rad_core/gems.rb +31 -0
  110. data/readme.md +33 -0
  111. data/spec/controller/abstract_controller_spec/views/OperationsOrderSpec/action.erb +1 -0
  112. data/spec/controller/abstract_controller_spec/views/ViewVariablesSpec/action.erb +11 -0
  113. data/spec/controller/abstract_controller_spec.rb +132 -0
  114. data/spec/controller/controller_context_spec/views/ItemSpec/actions.erb +4 -0
  115. data/spec/controller/controller_context_spec/views/ItemSpec/show.erb +0 -0
  116. data/spec/controller/controller_context_spec/views/ItemSpec/update.erb +0 -0
  117. data/spec/controller/controller_context_spec/views/NamespaceSpec/ClassSpec/show.erb +0 -0
  118. data/spec/controller/controller_context_spec/views/PageSpec/actions.erb +3 -0
  119. data/spec/controller/controller_context_spec/views/PageSpec/show.erb +0 -0
  120. data/spec/controller/controller_context_spec/views/namespace_spec/class_spec/update.erb +0 -0
  121. data/spec/controller/controller_context_spec.rb +123 -0
  122. data/spec/controller/controller_helper_spec/views/HelperMethodSpec/action.erb +1 -0
  123. data/spec/controller/controller_helper_spec/views/HelperSpec/action.erb +1 -0
  124. data/spec/controller/controller_helper_spec.rb +53 -0
  125. data/spec/controller/controller_render_spec/views/AlreadyRenderedSpec/action.erb +1 -0
  126. data/spec/controller/controller_render_spec/views/AlreadyRenderedSpec/custom_template.erb +1 -0
  127. data/spec/controller/controller_render_spec/views/AnotherActionSpec/another_action.erb +1 -0
  128. data/spec/controller/controller_render_spec/views/AnotherLayout/action.erb +1 -0
  129. data/spec/controller/controller_render_spec/views/ForbidPartialAsActionSpec/_action.erb +1 -0
  130. data/spec/controller/controller_render_spec/views/FormatSpec/action.html.erb +1 -0
  131. data/spec/controller/controller_render_spec/views/FormatSpec/action.js.erb +1 -0
  132. data/spec/controller/controller_render_spec/views/LayoutFiltersSpec/action_with_layout.erb +1 -0
  133. data/spec/controller/controller_render_spec/views/LayoutFiltersSpec/action_without_layout.erb +1 -0
  134. data/spec/controller/controller_render_spec/views/LayoutSpec/action.erb +1 -0
  135. data/spec/controller/controller_render_spec/views/MultipleActions/actions.haml +7 -0
  136. data/spec/controller/controller_render_spec/views/layouts/admin.erb +1 -0
  137. data/spec/controller/controller_render_spec/views/layouts/app.html.erb +1 -0
  138. data/spec/controller/controller_render_spec/views/layouts/app.js.erb +1 -0
  139. data/spec/controller/controller_render_spec/views/rem ExplicitRenderSpec/action.erb +1 -0
  140. data/spec/controller/controller_render_spec/views/rem ExplicitRenderSpec/another_action.erb +1 -0
  141. data/spec/controller/controller_render_spec/views/some_template.erb +1 -0
  142. data/spec/controller/controller_render_spec/views/standalone.html.erb +1 -0
  143. data/spec/controller/controller_render_spec.rb +217 -0
  144. data/spec/controller/error_handling_spec/views/diferrent_error_handling_spec/a.erb +1 -0
  145. data/spec/controller/error_handling_spec/views/diferrent_error_handling_spec/b.erb +1 -0
  146. data/spec/controller/error_handling_spec/views/diferrent_error_handling_spec/c.erb +1 -0
  147. data/spec/controller/error_handling_spec.rb +117 -0
  148. data/spec/controller/http_controller_spec.rb +130 -0
  149. data/spec/controller/spec_helper.rb +19 -0
  150. data/spec/conveyor/conveyor_spec.rb +124 -0
  151. data/spec/conveyor/spec_helper.rb +3 -0
  152. data/spec/environment/config_spec/config.default.yml +3 -0
  153. data/spec/environment/config_spec/config.development.yml +3 -0
  154. data/spec/environment/config_spec/config.yml +5 -0
  155. data/spec/environment/config_spec.rb +30 -0
  156. data/spec/environment/environment_spec/path1/file1 +0 -0
  157. data/spec/environment/environment_spec/path1/some_folder/some_file +0 -0
  158. data/spec/environment/environment_spec/path2/file2 +0 -0
  159. data/spec/environment/environment_spec/path2/some_folder/some_file +0 -0
  160. data/spec/environment/environment_spec.rb +65 -0
  161. data/spec/environment/logger_spec.rb +19 -0
  162. data/spec/environment/minimal_app_spec/app.rb +1 -0
  163. data/spec/environment/minimal_app_spec.rb +25 -0
  164. data/spec/environment/spec_helper.rb +1 -0
  165. data/spec/environment/standard_app_spec/app/lib/app/init.rb +3 -0
  166. data/spec/environment/standard_app_spec/plugin_a/lib/plugin_a/init.rb +1 -0
  167. data/spec/environment/standard_app_spec/plugin_b/lib/emptygit +0 -0
  168. data/spec/environment/standard_app_spec.rb +48 -0
  169. data/spec/html/basic_html_helper_spec.rb +29 -0
  170. data/spec/html/form_helper_spec.rb +63 -0
  171. data/spec/html/javascript_helper_spec.rb +15 -0
  172. data/spec/html/model_helper_spec.rb +81 -0
  173. data/spec/html/scoped_params_spec.rb +15 -0
  174. data/spec/html/spec_helper.rb +28 -0
  175. data/spec/http/http_spec/app/lib/app/init.rb +10 -0
  176. data/spec/http/http_spec/app/runtime/public/emptygit +0 -0
  177. data/spec/http/http_spec/plugin_a/lib/plugin_a/init.rb +0 -0
  178. data/spec/http/http_spec/plugin_b/lib/plugin_b/init.rb +5 -0
  179. data/spec/http/http_spec/plugin_b/static/emptygit +0 -0
  180. data/spec/http/http_spec.rb +51 -0
  181. data/spec/http/micelaneous_spec.rb +13 -0
  182. data/spec/http/spec_helper.rb +5 -0
  183. data/spec/integration/basic_spec/views/smoke_test_spec/action.erb +1 -0
  184. data/spec/integration/basic_spec.rb +79 -0
  185. data/spec/integration/controller_routing_helper_spec.rb +84 -0
  186. data/spec/integration/flash_spec.rb +206 -0
  187. data/spec/integration/spec_helper.rb +5 -0
  188. data/spec/integration/spec_helper_spec.rb +63 -0
  189. data/spec/integration/view_routing_helper_spec.rb +134 -0
  190. data/spec/mail/mail_controller_spec/views/body_template_spec/signup.erb +1 -0
  191. data/spec/mail/mail_controller_spec.rb +61 -0
  192. data/spec/mail/spec_helper.rb +7 -0
  193. data/spec/remote/remote_spec.rb +75 -0
  194. data/spec/remote/spec_helper.rb +17 -0
  195. data/spec/router/alias_router_spec.rb +98 -0
  196. data/spec/router/basic_spec.rb +111 -0
  197. data/spec/router/configurator_spec.rb +18 -0
  198. data/spec/router/integration_spec.rb +42 -0
  199. data/spec/router/persistent_params_spec.rb +65 -0
  200. data/spec/router/restful_router_spec.rb +120 -0
  201. data/spec/router/routing_helper_spec.rb +55 -0
  202. data/spec/router/spec_helper.rb +20 -0
  203. data/spec/support/callbacks_spec.rb +157 -0
  204. data/spec/support/filters_spec.rb +60 -0
  205. data/spec/support/spec_helper.rb +4 -0
  206. data/spec/template/spec_helper.rb +6 -0
  207. data/spec/template/template_spec/file.erb +1 -0
  208. data/spec/template/template_spec/views/basic/custom_context.erb +1 -0
  209. data/spec/template/template_spec/views/basic/extension.erb +1 -0
  210. data/spec/template/template_spec/views/basic/general.html.erb +5 -0
  211. data/spec/template/template_spec/views/basic/non_existing_format.html.erb +0 -0
  212. data/spec/template/template_spec/views/format/format.erb +1 -0
  213. data/spec/template/template_spec/views/format/format.html.erb +1 -0
  214. data/spec/template/template_spec/views/format/format.js.erb +1 -0
  215. data/spec/template/template_spec/views/format_for_partials/_form.html.erb +1 -0
  216. data/spec/template/template_spec/views/format_for_partials/dialog.js.erb +1 -0
  217. data/spec/template/template_spec/views/layout/basic/content.erb +1 -0
  218. data/spec/template/template_spec/views/layout/basic/layout.erb +1 -0
  219. data/spec/template/template_spec/views/layout/content_for/content.erb +3 -0
  220. data/spec/template/template_spec/views/layout/content_for/layout.erb +3 -0
  221. data/spec/template/template_spec/views/layout/format/content.html.erb +1 -0
  222. data/spec/template/template_spec/views/layout/format/content.js.erb +1 -0
  223. data/spec/template/template_spec/views/layout/format/layout.html.erb +1 -0
  224. data/spec/template/template_spec/views/layout/format/layout.js.erb +1 -0
  225. data/spec/template/template_spec/views/layout/nested_yield/a.erb +1 -0
  226. data/spec/template/template_spec/views/layout/nested_yield/layout.erb +1 -0
  227. data/spec/template/template_spec/views/layout/nested_yield/layout_b.erb +1 -0
  228. data/spec/template/template_spec/views/layout/same_context/a.erb +1 -0
  229. data/spec/template/template_spec/views/layout/same_context/b.erb +1 -0
  230. data/spec/template/template_spec/views/layout/same_context/layout.erb +1 -0
  231. data/spec/template/template_spec/views/nested/format/a.erb +1 -0
  232. data/spec/template/template_spec/views/nested/format/b.erb +1 -0
  233. data/spec/template/template_spec/views/nested/relative/a.erb +1 -0
  234. data/spec/template/template_spec/views/nested/relative/b.erb +1 -0
  235. data/spec/template/template_spec/views/nested/relative/c.erb +1 -0
  236. data/spec/template/template_spec/views/nested/shared/c.erb +1 -0
  237. data/spec/template/template_spec/views/nesting_format/_edit.html.erb +1 -0
  238. data/spec/template/template_spec/views/nesting_format/_form.html.erb +1 -0
  239. data/spec/template/template_spec/views/nesting_format/dialog.js.erb +1 -0
  240. data/spec/template/template_spec/views/other/template.erb +1 -0
  241. data/spec/template/template_spec/views/prefixes/_underscored.erb +1 -0
  242. data/spec/template/template_spec/views/prefixes/without_prefix.erb +1 -0
  243. data/spec/template/template_spec.rb +204 -0
  244. data/spec/template/tilt_spec/views/concat_and_capture.erb +1 -0
  245. data/spec/template/tilt_spec/views/concat_and_capture.haml +3 -0
  246. data/spec/template/tilt_spec/views/encoding/erb.erb +1 -0
  247. data/spec/template/tilt_spec/views/encoding/haml.haml +1 -0
  248. data/spec/template/tilt_spec/views/errors.erb +3 -0
  249. data/spec/template/tilt_spec/views/errors.haml +3 -0
  250. data/spec/template/tilt_spec/views/mixed_templates/broken_erb_concat_erb.erb +4 -0
  251. data/spec/template/tilt_spec/views/mixed_templates/broken_erb_concat_haml.haml +1 -0
  252. data/spec/template/tilt_spec/views/mixed_templates/broken_haml_concat_erb.erb +1 -0
  253. data/spec/template/tilt_spec/views/mixed_templates/broken_haml_concat_haml.haml +2 -0
  254. data/spec/template/tilt_spec/views/nested_capture_and_concat.haml +3 -0
  255. data/spec/template/tilt_spec/views/ugly.haml +3 -0
  256. data/spec/template/tilt_spec/views/yield.erb +1 -0
  257. data/spec/template/tilt_spec.rb +98 -0
  258. metadata +531 -0
@@ -0,0 +1,271 @@
1
+ module Rad
2
+ class Router
3
+ inject(
4
+ config: :config,
5
+ workspace: :workspace
6
+ )
7
+
8
+ attr_reader :routes, :format_processor
9
+
10
+ def initialize class_variable, routes = {default_router: SimpleRouter.new}, format_processor = DefaultFormatProcessor.new
11
+ @class_variable, @format_processor = class_variable, format_processor
12
+ @routes = Dictionary.new
13
+ routes.each do |k, v|
14
+ k.must_be.present
15
+ v.must_be.present
16
+ v.must.respond_to(:decode)
17
+ v.must.respond_to(:encode)
18
+
19
+ @routes[k] = v
20
+ end
21
+ end
22
+
23
+ def skip path_regexp=nil
24
+ @skip ||= []
25
+ if path_regexp
26
+ path_regexp.must_be.a Regexp
27
+ @skip << path_regexp unless @skip.include? path_regexp
28
+ else
29
+ @skip
30
+ end
31
+ end
32
+
33
+ def url_for *args
34
+ if args.first.is_a?(Class)
35
+ args.size.must_be.in 2..3
36
+ klass, method, options = args
37
+ url_for_class(klass, method, (options || {}))
38
+ else
39
+ first = args.first.to_s
40
+ if first !~ /^\//
41
+ args.size.must_be.in 1..2
42
+ method, options = args
43
+ url_for_class(nil, method, (options || {}))
44
+ else
45
+ args.size.must_be.in 1..2
46
+ path, options = args
47
+ url_for_path(path, (options || {}))
48
+ end
49
+ end
50
+ end
51
+
52
+ def decode path, params
53
+ path.first.must == '/'
54
+ # params = params.to_openobject
55
+
56
+ throw :skip, true if skip.any?{|path_regexp| path_regexp =~ path}
57
+
58
+ path, format = format_processor.remove_format path if format_processor
59
+
60
+ result = nil
61
+ routes.each do |name, route|
62
+ result = route.decode path, params
63
+ break if result
64
+ end
65
+
66
+ raise "no route for '#{safe_workspace.path}' request!" unless result
67
+
68
+ klass, method, params = result
69
+ method ||= config.default_method
70
+ params.must_be.defined
71
+ method.must_be.a Symbol
72
+
73
+ raise "Invalid route! No method '#{method}' for #{klass}!" unless klass.instance_methods.include? method
74
+ raise "Invalid route! You try to call protected method '#{method}' for '#{path}'!" unless klass.public_instance_methods.include? method
75
+
76
+ return klass, method, params
77
+ end
78
+
79
+ def encode klass, method, params = {}
80
+ klass.must_be.defined
81
+ method.must_be.a Symbol
82
+ params = params.clone
83
+ # method, params = method, params.to_openobject
84
+
85
+ format = params.delete(:format)
86
+
87
+ raise "Invalid route! No method '#{method}' for #{klass}!" unless klass.method_defined? method
88
+ raise "Invalid route! You try to call protected method '#{method}' for '#{klass}'!" unless klass.method_defined? method
89
+
90
+ inject_persistent_params! params
91
+
92
+ result = nil
93
+ routes.each do |name, route|
94
+ result = route.encode klass, method, params
95
+ break if result
96
+ end
97
+
98
+ raise "no route for '#{klass}.#{method}'!" unless result
99
+
100
+ path, params = result
101
+ path.must_be.defined
102
+ params.must_be.defined
103
+
104
+ path = format_processor.add_format path, format if format_processor and format
105
+
106
+ return path, params
107
+ end
108
+
109
+ def encode_method route_method
110
+ # method = method
111
+ route_method.must_be.present
112
+
113
+ result = nil
114
+ routes.each do |name, route|
115
+ result = route.respond_to :encode_method, route_method
116
+ break if result
117
+ end
118
+
119
+ raise "no route for '#{route_method}' route method!" unless result
120
+
121
+ klass, method = result
122
+ klass.must_be.defined
123
+ method.must_be.defined
124
+ return klass, method
125
+ end
126
+ cache_method_with_params_in_production :encode_method
127
+
128
+ def persist_params &block
129
+ if block
130
+ before = safe_workspace.persist_params?
131
+ begin
132
+ safe_workspace[:persist_params] = true
133
+ block.call
134
+ ensure
135
+ safe_workspace.delete :persist_params unless before
136
+ end
137
+ else
138
+ safe_workspace[:persist_params] = true
139
+ end
140
+ end
141
+
142
+ def dont_persist_params &block
143
+ if block
144
+ before = safe_workspace.persist_params?
145
+ begin
146
+ safe_workspace.delete :persist_params
147
+ block.call
148
+ ensure
149
+ safe_workspace[:persist_params] = true if before
150
+ end
151
+ else
152
+ safe_workspace.delete :persist_params
153
+ end
154
+ end
155
+
156
+ def persist_params?
157
+ safe_workspace.persist_params?
158
+ end
159
+
160
+ def persistent_params; @persistent_params ||= [] end
161
+
162
+ def url_for_path path, params
163
+ # params = params.to_openobject
164
+
165
+ # special params
166
+ url = if params.include? :url_root
167
+ (params.delete(:url_root) || "") + path
168
+ else
169
+ config.url_root! + path
170
+ end
171
+ host, port = params.delete(:host), params.delete(:port)
172
+ format = params.delete(:format)
173
+
174
+ # json
175
+ params = {json: params.to_json} if params.delete :as_json #and !params.empty?
176
+
177
+ # format
178
+ if format
179
+ params[:format] = format
180
+ url.marks.format = format.to_s
181
+ end
182
+
183
+ # Delete 'nil' parameters
184
+ to_delete = []
185
+ params.each{|k, v| to_delete << k if v.nil?}
186
+ to_delete.each{|k| params.delete k}
187
+
188
+ # build url
189
+ delimiter = path.include?('?') ? '&' : '?'
190
+ url << "#{delimiter}#{params.to_query}" unless params.empty?
191
+
192
+ if host.blank?
193
+ url
194
+ else
195
+ %{http://#{host}#{":#{port}" unless port.blank?}#{url}}
196
+ end
197
+ end
198
+
199
+ def url_for_class klass, method, params
200
+ klass ||= current_class
201
+ # params = params.to_openobject
202
+
203
+ # special params
204
+ format = params[:format]
205
+
206
+ path, params = encode klass, method, params
207
+ url = url_for_path path, params
208
+
209
+ url.marks.format = format.to_s if format
210
+
211
+ url
212
+ end
213
+
214
+ protected
215
+ # sometimes we need access to routes outside of conveyor :cycle,
216
+ # for example in spec routing helpers, in that case we just ignore workspace and it's variables
217
+ def safe_workspace
218
+ if Micon.active? :cycle
219
+ workspace
220
+ else
221
+ Workspace.new
222
+ end
223
+ end
224
+
225
+ def current_class; safe_workspace[@class_variable] end
226
+
227
+ DONOT_PERSIST = [:_, :_method]
228
+
229
+ def inject_persistent_params! params
230
+ persist = params.delete(:persist)
231
+
232
+ # global persistent params
233
+ unless cached_global_persistend_params = safe_workspace.cached_global_persistend_params
234
+ cached_global_persistend_params, workspace_params = {}, safe_workspace.params
235
+ if workspace_params
236
+ persistent_params.collect!{|k| k}
237
+
238
+ workspace_params.each do |k, v|
239
+ cached_global_persistend_params[k] = v if persistent_params.include?(k)
240
+ end
241
+
242
+ safe_workspace.cached_global_persistend_params = cached_global_persistend_params
243
+ end
244
+ end
245
+
246
+ cached_global_persistend_params.each do |k, v|
247
+ params[k] = v unless params.include? k
248
+ end
249
+
250
+ # underscored persistent params
251
+ if persist_params?
252
+ unless cached_persistend_params = safe_workspace.cached_persistend_params
253
+ cached_persistend_params, workspace_params = {}, safe_workspace.params
254
+
255
+ if workspace_params
256
+ workspace_params.each do |k, v|
257
+ cached_persistend_params[k] = v if (k =~ /^_/) and !DONOT_PERSIST.include?(k)
258
+ end
259
+
260
+ safe_workspace.cached_persistend_params = cached_persistend_params
261
+ end
262
+ end
263
+
264
+ cached_persistend_params.each do |k, v|
265
+ params[k] = v unless params.include? k
266
+ end
267
+ end
268
+ end
269
+
270
+ end
271
+ end
@@ -0,0 +1,23 @@
1
+ module Rad
2
+ class SimpleRouter
3
+ inject logger: :logger
4
+
5
+ def encode klass, method, params
6
+ path = "/#{klass.name.underscore}/#{method}"
7
+ return path, params
8
+ end
9
+
10
+ def decode path, params
11
+ parts = path[1..-1].split '/'
12
+ if parts.size >= 2
13
+ method = parts.pop.to_sym
14
+
15
+ class_path = parts.join('/')
16
+ class_name = class_path.camelize
17
+ klass = class_name.constantize
18
+
19
+ return klass, method, params
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,62 @@
1
+ module Rad
2
+ module AbstractRouter
3
+
4
+ protected
5
+ def parse_url_root options
6
+ url_root = options.delete(:url_root)
7
+ url_root.must =~ /^\/.+/ if url_root
8
+ url_root
9
+ end
10
+
11
+ def parse_prefix options
12
+ prefix = options.delete(:prefix)
13
+ if prefix
14
+ prefix.must_not_be.empty
15
+ prefix.must_be.a Array
16
+ prefix = prefix.collect do |item|
17
+ item = Array(item)
18
+ item.size.must_be.in 1..2
19
+ item << item.first.to_s if item.size < 2
20
+ item.first.must_be.a Symbol
21
+ item.last.must_be.a String
22
+ item
23
+ end
24
+ end
25
+ prefix
26
+ end
27
+
28
+ def encode_prefix_params! path, params, meta
29
+ if prefix = meta[:prefix]
30
+ parts = []
31
+ prefix.each do |name, als|
32
+ parts << als
33
+ parts << (params.delete(name) || raise("not provided :#{name} prefix!")) # TODO 3 add url_escape
34
+ end
35
+ "/#{parts.join('/')}#{path}"
36
+ else
37
+ path
38
+ end
39
+ end
40
+
41
+ def encode_url_root! path, meta
42
+ if url_root = meta[:url_root]
43
+ "#{url_root}#{path}"
44
+ else
45
+ path
46
+ end
47
+ end
48
+
49
+ def decode_prefix_params! parts, params, meta
50
+ if prefix = meta[:prefix]
51
+ prefix.reverse.each do |name, als|
52
+ params[name] = parts.pop || raise("not provided :#{name} prefix!")
53
+ raise("incorrect url for :#{name} prefix!") unless parts.pop == als
54
+ end
55
+ end
56
+ end
57
+
58
+ def decode_url_root! parts, meta
59
+ raise "invalid :url_root!" if meta[:url_root] and meta[:url_root] != "/#{parts.join('/')}"
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,113 @@
1
+ module Rad
2
+ class AliasRouter
3
+ include AbstractRouter
4
+
5
+ class TreeHash < Hash
6
+ attr_accessor :meta
7
+ end
8
+
9
+ def initialize
10
+ @route_methods, @paths, @classes = {}, TreeHash.new, {}
11
+ end
12
+
13
+ def add als, options = {}
14
+ # parsing options
15
+ # als, options = als.to_s, options.to_openobject
16
+ als = als.to_s
17
+ als.must =~ /^\//
18
+ klass = options.delete(:class) || raise("no class!")
19
+ method = options.delete(:method) || raise("no method!")
20
+ method = method.must_be.a Symbol
21
+ url_root = parse_url_root options
22
+ prefix = parse_prefix options
23
+ raise "unknown options :#{options.to_h.keys.join(': ')}!" unless options.empty?
24
+ raise "you can't use '/' alias with :url_root!" if als == '/' and url_root
25
+
26
+ # logic
27
+ meta = {
28
+ class: klass,
29
+ method: method,
30
+ path: als,
31
+ url_root: url_root,
32
+ prefix: prefix
33
+ }
34
+
35
+ route_methods["#{als[1..-1]}_path"] = meta
36
+
37
+ (classes[klass] ||= {})[method] = meta
38
+
39
+
40
+ parts = als[1..-1].split('/')
41
+ parts << '' if parts.empty?
42
+
43
+ tree_iterator = paths
44
+ parts.reverse.each do |part|
45
+ tree_iterator = (tree_iterator[part] ||= TreeHash.new)
46
+ raise "alias '#{als}' conflicted with another alias!" if tree_iterator.meta
47
+ end
48
+ tree_iterator.meta = meta
49
+ end
50
+
51
+ def encode klass, method, params
52
+ if meta = classes[klass].try(:[], method)
53
+ path = meta[:path]
54
+
55
+ path = encode_prefix_params! path, params, meta
56
+ path = encode_url_root! path, meta
57
+
58
+ return path, params
59
+ else
60
+ nil
61
+ end
62
+ end
63
+
64
+ def decode path, params
65
+ parts = path[1..-1].split('/')
66
+ parts << '' if parts.empty?
67
+
68
+ tree_iterator = paths
69
+
70
+ # checking for first part
71
+ part = parts.pop
72
+ tree_iterator = tree_iterator[part]
73
+ return nil unless tree_iterator
74
+
75
+ # checking for exact match
76
+ while part = parts.pop
77
+ tmp = tree_iterator[part]
78
+ unless tmp
79
+ parts << part
80
+ break
81
+ end
82
+ tree_iterator = tmp
83
+ end
84
+
85
+ meta = tree_iterator.meta
86
+
87
+ decode_prefix_params! parts, params, meta
88
+ decode_url_root! parts, meta
89
+
90
+ return meta[:class], meta[:method], params
91
+ end
92
+
93
+ def encode_method route_method
94
+ if meta = route_methods[route_method]
95
+ return meta[:class], meta[:method]
96
+ else
97
+ nil
98
+ end
99
+ end
100
+
101
+ protected
102
+ attr_accessor :paths, :route_methods, :classes
103
+ end
104
+ end
105
+
106
+
107
+ Rad::Routes::Configurator.class_eval do
108
+ def alias *args, &block
109
+ alias_router = @router.routes[:alias_router]
110
+ raise "There's no AliasRouter (use config to add it)!" unless alias_router
111
+ alias_router.add *args, &block
112
+ end
113
+ end
@@ -0,0 +1,113 @@
1
+ module Rad
2
+ class RestfulRouter
3
+ include AbstractRouter
4
+
5
+ def initialize
6
+ @resources, @classes = {}, {}
7
+ end
8
+
9
+ def add resource, options = {}
10
+ # parsing options
11
+ resource = resource.to_s
12
+ resource.must_not =~ /\//
13
+ raise "resource should be in plural form!" unless resource.pluralize == resource
14
+ klass = options.delete(:class) || raise("no class!")
15
+ url_root = parse_url_root options
16
+ prefix = parse_prefix options
17
+ raise "unknown options :#{options.to_h.keys.join(': ')}!" unless options.empty?
18
+
19
+ # logic
20
+ meta = {
21
+ class: klass,
22
+ resource: resource,
23
+ url_root: url_root,
24
+ prefix: prefix
25
+ }
26
+
27
+ resources.must_not.include(resource.pluralize)
28
+ classes.must_not.include(klass)
29
+ resources[resource.pluralize] = meta
30
+ resources[resource.singularize] = meta
31
+ classes[klass] = meta
32
+ end
33
+
34
+ def encode klass, method, params
35
+ meta = classes[klass]
36
+ return nil unless meta
37
+
38
+ path = if id = params.delete(:id)
39
+ "/#{meta[:resource]}/#{id}/#{method}"
40
+ else
41
+ "/#{meta[:resource]}/#{method}"
42
+ end
43
+
44
+ path = encode_prefix_params! path, params, meta
45
+ path = encode_url_root! path, meta
46
+
47
+ [path, params]
48
+ end
49
+
50
+ def decode path, params
51
+ decode_as_object_resource(path, params) || decode_as_static_resource(path, params)
52
+ end
53
+
54
+ def encode_method route_method
55
+ token = route_method.sub(/_path$/, '')
56
+
57
+ resources.each do |name, meta|
58
+ if i = token.rindex(name)
59
+ route_method.size == i + name.size and route_method[(i-1)..(i-1)] == '_'
60
+ return meta[:class], route_method[0..(i-2)].to_sym
61
+ end
62
+ end
63
+
64
+ return nil
65
+ end
66
+
67
+ protected
68
+ attr_accessor :resources, :classes
69
+
70
+ def decode_as_object_resource path, params
71
+ parts = path[1..-1].split('/')
72
+ return nil unless parts.size >= 3
73
+
74
+ method, id, klass = parts.pop.to_sym, parts.pop, parts.pop
75
+ meta = resources[klass]
76
+ return nil unless meta
77
+
78
+ return nil if parts.size != (meta[:url_root] ? 1 : 0) + (meta[:prefix] ? meta[:prefix].size * 2 : 0)
79
+
80
+ decode_prefix_params! parts, params, meta
81
+ decode_url_root! parts, meta
82
+
83
+ params[:id] = id
84
+
85
+ return meta[:class], method, params
86
+ end
87
+
88
+ def decode_as_static_resource path, params
89
+ parts = path[1..-1].split('/')
90
+ return nil unless parts.size >= 2
91
+
92
+ method, klass = parts.pop.to_sym, parts.pop
93
+ meta = resources[klass]
94
+ return nil unless meta
95
+
96
+ return nil if parts.size != (meta[:url_root] ? 1 : 0) + (meta[:prefix] ? meta[:prefix].size * 2 : 0)
97
+
98
+ decode_prefix_params! parts, params, meta
99
+ decode_url_root! parts, meta
100
+
101
+ return meta[:class], method, params
102
+ end
103
+ end
104
+ end
105
+
106
+
107
+ Rad::Routes::Configurator.class_eval do
108
+ def resource *args, &block
109
+ restful_router = @router.routes[:restful_router]
110
+ raise "There's no RestfulRouter (use config to add it)!" unless restful_router
111
+ restful_router.add *args, &block
112
+ end
113
+ end
data/lib/rad/router.rb ADDED
@@ -0,0 +1,29 @@
1
+ require 'rad/conveyor'
2
+
3
+ %w(
4
+ configurator
5
+ simple_router
6
+ router
7
+ default_format_processor
8
+
9
+ core_routing_helper
10
+
11
+ processors/router
12
+ ).each{|f| require "rad/router/core/#{f}"}
13
+
14
+ # {AliasRouter: 'alias_router', RestfulRouter: 'restful_router'}.each do |klass, path|
15
+ # Rad.autoload klass, "rad/router/routers/#{path}"
16
+ # end
17
+ %w(
18
+ abstract_router
19
+ alias_router
20
+ restful_router
21
+ ).each{|f| require "rad/router/routers/#{f}"}
22
+
23
+ Rad::Config::DEFAULTS.merge!(
24
+ default_path: '/'
25
+ )
26
+
27
+ Rad.metaclass do
28
+ delegate :routes, to: Rad::Routes::Configurator
29
+ end
@@ -0,0 +1,41 @@
1
+ require 'rad/spec/environment'
2
+
3
+ rspec do
4
+ attr_accessor :response, :workspace
5
+
6
+ def self.with_controller
7
+ before :each do
8
+ self.response = nil
9
+ end
10
+ end
11
+
12
+ def ccall klass, method, params = {}, workspace_variables = {}, &block
13
+ self.response = Rad::Response.new
14
+ workspace_variables = {
15
+ class: klass, method_name: method, params: Rad::Params.new(params), response: response
16
+ }.merge(workspace_variables)
17
+
18
+ if block
19
+ rad.conveyors.web.call workspace_variables do |c|
20
+ self.workspace = rad.workspace
21
+
22
+ block.call c
23
+ end
24
+ else
25
+ self.workspace = rad.conveyors.web.call workspace_variables
26
+ end
27
+
28
+ if Rad.const_defined?(:HttpController) and klass and klass.is?(::Rad::HttpController)
29
+ response.content_type.must_be.present
30
+ response.status.must_be.present
31
+ end
32
+
33
+ workspace.content
34
+ end
35
+ end
36
+
37
+ Rad::AbstractController.class_eval do
38
+ def render_ok
39
+ render inline: 'ok'
40
+ end
41
+ end
@@ -0,0 +1,51 @@
1
+ require 'rspec_ext'
2
+
3
+ rspec do
4
+ def self.swap_metadata scope = :all
5
+ old_metadata = nil
6
+
7
+ before scope do
8
+ old_metadata = Micon.metadata
9
+ Micon.swap_metadata old_metadata.deep_clone
10
+ end
11
+
12
+ after scope do
13
+ Micon.swap_metadata old_metadata
14
+ end
15
+ end
16
+
17
+ def self.with_environment options = {}, &block
18
+ options = options.to_openobject
19
+ runtime_dir = options.delete(:runtime_dir) || './tmp'
20
+ scope = options.delete(:before) || :each
21
+ environment = options.delete(:environment) || :test
22
+ raise "Invalid options :#{options.to_hash.keys.join(', :')}!" unless options.empty?
23
+
24
+ swap_metadata
25
+
26
+ before scope do
27
+ rad.clear
28
+ Micon.after :config do |config|
29
+ config.set! environment: environment, runtime_dir: runtime_dir
30
+ end
31
+
32
+ block.call if block
33
+
34
+ silence_logger!
35
+ # Rad.initialize_plugin runtime_dir, environment
36
+ end
37
+
38
+ after scope do
39
+ rad.clear
40
+ end
41
+ end
42
+
43
+ inject(
44
+ config: :config,
45
+ logger: :logger
46
+ )
47
+
48
+ def silence_logger!
49
+ self.logger = Logger.new nil
50
+ end
51
+ end