rad_core 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
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