much-rails 0.0.1 → 0.2.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 (101) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -1
  3. data/lib/much-rails.rb +85 -0
  4. data/lib/much-rails/action.rb +415 -0
  5. data/lib/much-rails/action/base_command_result.rb +22 -0
  6. data/lib/much-rails/action/base_result.rb +14 -0
  7. data/lib/much-rails/action/base_router.rb +474 -0
  8. data/lib/much-rails/action/controller.rb +100 -0
  9. data/lib/much-rails/action/head_result.rb +18 -0
  10. data/lib/much-rails/action/redirect_to_result.rb +18 -0
  11. data/lib/much-rails/action/render_result.rb +25 -0
  12. data/lib/much-rails/action/router.rb +101 -0
  13. data/lib/much-rails/action/send_data_result.rb +18 -0
  14. data/lib/much-rails/action/send_file_result.rb +18 -0
  15. data/lib/much-rails/action/unprocessable_entity_result.rb +37 -0
  16. data/lib/much-rails/assets.rb +54 -0
  17. data/lib/much-rails/boolean.rb +7 -0
  18. data/lib/much-rails/call_method.rb +27 -0
  19. data/lib/much-rails/call_method_callbacks.rb +122 -0
  20. data/lib/much-rails/change_action.rb +83 -0
  21. data/lib/much-rails/change_action_result.rb +59 -0
  22. data/lib/much-rails/config.rb +55 -0
  23. data/lib/much-rails/date.rb +50 -0
  24. data/lib/much-rails/decimal.rb +7 -0
  25. data/lib/much-rails/destroy_action.rb +32 -0
  26. data/lib/much-rails/destroy_service.rb +67 -0
  27. data/lib/much-rails/has_slug.rb +7 -0
  28. data/lib/much-rails/input_value.rb +19 -0
  29. data/lib/much-rails/json.rb +29 -0
  30. data/lib/much-rails/layout.rb +142 -0
  31. data/lib/much-rails/layout/helper.rb +25 -0
  32. data/lib/much-rails/mixin.rb +7 -0
  33. data/lib/much-rails/not_given.rb +7 -0
  34. data/lib/much-rails/rails_routes.rb +29 -0
  35. data/lib/much-rails/railtie.rb +39 -0
  36. data/lib/much-rails/records.rb +5 -0
  37. data/lib/much-rails/records/always_destroyable.rb +30 -0
  38. data/lib/much-rails/records/not_destroyable.rb +30 -0
  39. data/lib/much-rails/records/validate_destroy.rb +92 -0
  40. data/lib/much-rails/result.rb +7 -0
  41. data/lib/much-rails/save_action.rb +32 -0
  42. data/lib/much-rails/save_service.rb +68 -0
  43. data/lib/much-rails/service.rb +18 -0
  44. data/lib/much-rails/service_validation_errors.rb +41 -0
  45. data/lib/much-rails/time.rb +28 -0
  46. data/lib/much-rails/version.rb +3 -1
  47. data/lib/much-rails/view_models.rb +3 -0
  48. data/lib/much-rails/view_models/breadcrumb.rb +11 -0
  49. data/lib/much-rails/wrap_and_call_method.rb +41 -0
  50. data/lib/much-rails/wrap_method.rb +45 -0
  51. data/much-rails.gemspec +20 -4
  52. data/test/helper.rb +20 -2
  53. data/test/support/actions/show.rb +11 -0
  54. data/test/support/config/routes/test.rb +3 -0
  55. data/test/support/factory.rb +2 -0
  56. data/test/support/fake_action_controller.rb +63 -0
  57. data/test/unit/action/base_command_result_tests.rb +43 -0
  58. data/test/unit/action/base_result_tests.rb +22 -0
  59. data/test/unit/action/base_router_tests.rb +530 -0
  60. data/test/unit/action/controller_tests.rb +110 -0
  61. data/test/unit/action/head_result_tests.rb +24 -0
  62. data/test/unit/action/redirect_to_result_tests.rb +24 -0
  63. data/test/unit/action/render_result_tests.rb +43 -0
  64. data/test/unit/action/router_tests.rb +252 -0
  65. data/test/unit/action/send_data_result_tests.rb +24 -0
  66. data/test/unit/action/send_file_result_tests.rb +24 -0
  67. data/test/unit/action/unprocessable_entity_result_tests.rb +51 -0
  68. data/test/unit/action_tests.rb +400 -0
  69. data/test/unit/assets_tests.rb +127 -0
  70. data/test/unit/boolean_tests.rb +17 -0
  71. data/test/unit/call_method_callbacks_tests.rb +176 -0
  72. data/test/unit/call_method_tests.rb +62 -0
  73. data/test/unit/change_action_result_tests.rb +113 -0
  74. data/test/unit/change_action_tests.rb +260 -0
  75. data/test/unit/config_tests.rb +68 -0
  76. data/test/unit/date_tests.rb +55 -0
  77. data/test/unit/decimal_tests.rb +17 -0
  78. data/test/unit/destroy_action_tests.rb +83 -0
  79. data/test/unit/destroy_service_tests.rb +238 -0
  80. data/test/unit/has_slug_tests.rb +17 -0
  81. data/test/unit/input_value_tests.rb +34 -0
  82. data/test/unit/json_tests.rb +55 -0
  83. data/test/unit/layout_tests.rb +155 -0
  84. data/test/unit/mixin_tests.rb +17 -0
  85. data/test/unit/much-rails_tests.rb +82 -4
  86. data/test/unit/not_given_tests.rb +17 -0
  87. data/test/unit/rails_routes_tests.rb +28 -0
  88. data/test/unit/records/always_destroyable_tests.rb +43 -0
  89. data/test/unit/records/not_destroyable_tests.rb +40 -0
  90. data/test/unit/records/validate_destroy_tests.rb +252 -0
  91. data/test/unit/result_tests.rb +17 -0
  92. data/test/unit/save_action_tests.rb +83 -0
  93. data/test/unit/save_service_tests.rb +264 -0
  94. data/test/unit/service_tests.rb +33 -0
  95. data/test/unit/service_validation_errors_tests.rb +107 -0
  96. data/test/unit/time_tests.rb +58 -0
  97. data/test/unit/view_models/breadcrumb_tests.rb +53 -0
  98. data/test/unit/wrap_and_call_method_tests.rb +163 -0
  99. data/test/unit/wrap_method_tests.rb +112 -0
  100. metadata +356 -7
  101. data/test/unit/.keep +0 -0
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "assert"
4
+ require "much-rails/action/controller"
5
+
6
+ require "test/support/actions/show"
7
+ require "test/support/fake_action_controller"
8
+
9
+ module MuchRails::Action::Controller
10
+ class UnitTests < Assert::Context
11
+ desc "MuchRails::Action::Controller"
12
+ subject{ unit_module }
13
+
14
+ let(:unit_module){ MuchRails::Action::Controller }
15
+
16
+ should "include MuchRails::Mixin" do
17
+ assert_that(subject).includes(MuchRails::Mixin)
18
+ end
19
+
20
+ should "know its constants" do
21
+ assert_that(subject::DEFAULT_ACTION_CLASS_FORMAT).equals(:any)
22
+ end
23
+ end
24
+
25
+ class ReceiverTests < UnitTests
26
+ desc "receiver"
27
+ subject{ receiver_class }
28
+
29
+ let(:receiver_class) do
30
+ Class.new{ include FakeActionController }
31
+ end
32
+ end
33
+
34
+ class ReceiverInitTests < ReceiverTests
35
+ desc "when init"
36
+ subject{ receiver_class.new(params1) }
37
+
38
+ let(:params1) do
39
+ {
40
+ MuchRails::Action::Router::ACTION_CLASS_PARAM_NAME => "Actions::Show",
41
+ controller: "actions",
42
+ action: "show",
43
+ nested: {
44
+ value: "VALUE 1",
45
+ },
46
+ }
47
+ end
48
+
49
+ should have_readers :much_rails_action_class
50
+
51
+ should have_imeths(
52
+ MuchRails::Action::Router::CONTROLLER_CALL_ACTION_METHOD_NAME,
53
+ )
54
+ should have_imeths(
55
+ MuchRails::Action::Router::CONTROLLER_NOT_FOUND_METHOD_NAME,
56
+ )
57
+ should have_imeths :much_rails_action_class_name
58
+ should have_imeths :much_rails_action_class_format
59
+ should have_imeths :much_rails_action_params
60
+ should have_imeths :require_much_rails_action_class
61
+ should have_imeths :permit_all_much_rails_action_params
62
+
63
+ should "know its attributes" do
64
+ assert_that(subject.much_rails_action_class_name)
65
+ .equals("::Actions::Show")
66
+
67
+ assert_that(subject.much_rails_action_class_format)
68
+ .equals(unit_module::DEFAULT_ACTION_CLASS_FORMAT)
69
+
70
+ assert_that(subject.much_rails_action_params)
71
+ .equals(
72
+ nested: { value: "VALUE 1" },
73
+ value: "VALUE 1",
74
+ )
75
+
76
+ assert_that(subject.much_rails_action_class).equals(Actions::Show)
77
+
78
+ Actions::Show.format(:html)
79
+ receiver = receiver_class.new(params1)
80
+ assert_that(receiver.much_rails_action_class_format).equals(:html)
81
+ Actions::Show.format(nil)
82
+ end
83
+ end
84
+
85
+ class ReceiverInitWithUnknownActionClassTests < ReceiverTests
86
+ desc "when init with an unknown action class"
87
+ subject{ receiver_class.new(params1) }
88
+
89
+ let(:params1) do
90
+ {
91
+ MuchRails::Action::Router::ACTION_CLASS_PARAM_NAME =>
92
+ "Actions::Unknown",
93
+ }
94
+ end
95
+
96
+ should "return not found when not raising response exceptions" do
97
+ Assert.stub(MuchRails.config.action, :raise_response_exceptions?){ false }
98
+
99
+ assert_that(subject.much_rails_action_class).is_nil
100
+ assert_that(subject.head_called_with).equals([:not_found])
101
+ end
102
+
103
+ should "raise an exception when raising response exceptions" do
104
+ Assert.stub(MuchRails.config.action, :raise_response_exceptions?){ true }
105
+
106
+ assert_that{ subject.much_rails_action_class }
107
+ .raises(MuchRails::Action::ActionError)
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "assert"
4
+ require "much-rails/action/head_result"
5
+
6
+ class MuchRails::Action::HeadResult
7
+ class UnitTests < Assert::Context
8
+ desc "MuchRails::Action::HeadResult"
9
+ subject{ unit_class }
10
+
11
+ let(:unit_class){ MuchRails::Action::HeadResult }
12
+ end
13
+
14
+ class InitTests < UnitTests
15
+ desc "when init"
16
+ subject{ unit_class.new(:ok) }
17
+
18
+ should "know its attributes" do
19
+ assert_that(subject.command_name).equals(:head)
20
+ assert_that(subject.command_args).equals([:ok])
21
+ assert_that(subject.head_args).equals(subject.command_args)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "assert"
4
+ require "much-rails/action/redirect_to_result"
5
+
6
+ class MuchRails::Action::RedirectToResult
7
+ class UnitTests < Assert::Context
8
+ desc "MuchRails::Action::RedirectToResult"
9
+ subject{ unit_class }
10
+
11
+ let(:unit_class){ MuchRails::Action::RedirectToResult }
12
+ end
13
+
14
+ class InitTests < UnitTests
15
+ desc "when init"
16
+ subject{ unit_class.new("URL") }
17
+
18
+ should "know its attributes" do
19
+ assert_that(subject.command_name).equals(:redirect_to)
20
+ assert_that(subject.command_args).equals(["URL"])
21
+ assert_that(subject.redirect_to_args).equals(subject.command_args)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "assert"
4
+ require "much-rails/action/render_result"
5
+
6
+ class MuchRails::Action::RenderResult
7
+ class UnitTests < Assert::Context
8
+ desc "MuchRails::Action::RenderResult"
9
+ subject{ unit_class }
10
+
11
+ let(:unit_class){ MuchRails::Action::RenderResult }
12
+ end
13
+
14
+ class InitTests < UnitTests
15
+ desc "when init"
16
+ subject{ unit_class.new(view_model1, **render_kargs1) }
17
+
18
+ let(:controller1){ FakeController.new }
19
+ let(:view_model1){ Object.new }
20
+ let(:render_kargs1) do
21
+ { something: "TEST_VALUE" }
22
+ end
23
+
24
+ should have_readers :render_view_model, :render_kargs
25
+
26
+ should "know its attributes" do
27
+ assert_that(subject.render_view_model).equals(view_model1)
28
+ assert_that(subject.render_kargs).equals(render_kargs1)
29
+
30
+ controller1.instance_exec(subject, &subject.execute_block)
31
+ assert_that(controller1.view).equals(view_model1)
32
+ assert_that(controller1.render_called_with).equals(render_kargs1)
33
+ end
34
+ end
35
+
36
+ class FakeController
37
+ attr_reader :view, :render_called_with
38
+
39
+ def render(**kargs)
40
+ @render_called_with = kargs
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,252 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "assert"
4
+ require "much-rails/action/router"
5
+
6
+ require "much-rails/rails_routes"
7
+
8
+ class MuchRails::Action::Router
9
+ class UnitTests < Assert::Context
10
+ desc "MuchRails::Action::Router"
11
+ subject{ unit_class }
12
+
13
+ let(:unit_class){ MuchRails::Action::Router }
14
+
15
+ let(:caller1){ ["TEST CALLER 1"] }
16
+
17
+ should have_imeths :url_class
18
+
19
+ should "be a BaseRouter" do
20
+ assert_that(subject < MuchRails::Action::BaseRouter).is_true
21
+ end
22
+
23
+ should "know its constants" do
24
+ assert_that(subject::DEFAULT_CONTROLLER_NAME).equals("application")
25
+ assert_that(subject::CONTROLLER_CALL_ACTION_METHOD_NAME)
26
+ .equals(:much_rails_call_action)
27
+ assert_that(subject::CONTROLLER_NOT_FOUND_METHOD_NAME)
28
+ .equals(:much_rails_not_found)
29
+ assert_that(subject::ACTION_CLASS_PARAM_NAME)
30
+ .equals(:much_rails_action_class_name)
31
+ assert_that(subject.url_class).equals(unit_class::URL)
32
+ end
33
+ end
34
+
35
+ class LoadTests < UnitTests
36
+ desc ".load"
37
+
38
+ setup do
39
+ Assert.stub(::Rails, :root){ Pathname.new(TEST_SUPPORT_PATH) }
40
+ end
41
+
42
+ should "eval the named routes file" do
43
+ router = unit_class.load(:test)
44
+ assert_that(router.url_set).is_not_empty
45
+ assert_that(router.url_set.fetch(:root).path).equals("/")
46
+ end
47
+
48
+ should "complain if no file name given" do
49
+ assert_that{ unit_class.load([nil, "", " "]) }.raises(ArgumentError)
50
+ end
51
+
52
+ should "complain if the named routes file can't be found" do
53
+ assert_that{ unit_class.load(:unknown) }.raises(ArgumentError)
54
+ end
55
+ end
56
+
57
+ class InitTests < UnitTests
58
+ desc "when init"
59
+ subject{ unit_class.new }
60
+
61
+ let(:controller_name1){ Factory.string }
62
+
63
+ should have_readers :controller_name, :draw
64
+
65
+ should "know its attributes" do
66
+ assert_that(subject.controller_name)
67
+ .equals(unit_class::DEFAULT_CONTROLLER_NAME)
68
+
69
+ router = unit_class.new(controller_name: controller_name1)
70
+ assert_that(router.controller_name).equals(controller_name1)
71
+ end
72
+
73
+ should "draw Rails Application routes" do
74
+ request_type_name = Factory.symbol
75
+ request_type_proc = ->(request){}
76
+ subject.request_type(request_type_name, &request_type_proc)
77
+ request_type_class_name = "Actions::Show"
78
+ url_name = Factory.symbol
79
+ url_path = Factory.url
80
+ subject.url(url_name, url_path)
81
+ default_class_name = "Actions::Show"
82
+
83
+ subject.get(
84
+ url_name,
85
+ default_class_name,
86
+ request_type_name => request_type_class_name,
87
+ )
88
+ subject.post(url_name, default_class_name)
89
+ subject.put(url_path, default_class_name)
90
+ subject.patch(url_name, default_class_name)
91
+ subject.delete(url_name, default_class_name)
92
+
93
+ url2_name = Factory.symbol
94
+ url2_path = Factory.url
95
+ subject.url(url2_name, url2_path)
96
+
97
+ application_routes = FakeApplicationRoutes.new
98
+ subject.draw(application_routes)
99
+
100
+ expected_draw_url_to =
101
+ "#{subject.controller_name}"\
102
+ "##{unit_class::CONTROLLER_NOT_FOUND_METHOD_NAME}"
103
+ expected_draw_route_to =
104
+ "#{subject.controller_name}"\
105
+ "##{unit_class::CONTROLLER_CALL_ACTION_METHOD_NAME}"
106
+ expected_default_defaults =
107
+ { unit_class::ACTION_CLASS_PARAM_NAME => default_class_name }
108
+
109
+ assert_that(application_routes.get_calls.size).equals(3)
110
+ assert_that(application_routes.get_calls[0].pargs).equals([url_path])
111
+ assert_that(application_routes.get_calls[0].kargs)
112
+ .equals(
113
+ to: expected_draw_route_to,
114
+ as: url_name,
115
+ defaults:
116
+ { unit_class::ACTION_CLASS_PARAM_NAME => request_type_class_name },
117
+ constraints: request_type_proc,
118
+ )
119
+ assert_that(application_routes.get_calls[1].pargs).equals([url_path])
120
+ assert_that(application_routes.get_calls[1].kargs)
121
+ .equals(
122
+ to: expected_draw_route_to,
123
+ as: url_name,
124
+ defaults: expected_default_defaults,
125
+ )
126
+ assert_that(application_routes.get_calls[2].pargs).equals([url2_path])
127
+ assert_that(application_routes.get_calls[2].kargs)
128
+ .equals(
129
+ to: expected_draw_url_to,
130
+ as: url2_name,
131
+ )
132
+
133
+ assert_that(application_routes.post_calls.size).equals(1)
134
+ assert_that(application_routes.post_calls.last.pargs).equals([url_path])
135
+ assert_that(application_routes.post_calls.last.kargs)
136
+ .equals(
137
+ to: expected_draw_route_to,
138
+ as: url_name,
139
+ defaults: expected_default_defaults,
140
+ )
141
+
142
+ assert_that(application_routes.put_calls.size).equals(1)
143
+ assert_that(application_routes.put_calls.last.pargs).equals([url_path])
144
+ assert_that(application_routes.put_calls.last.kargs)
145
+ .equals(
146
+ to: expected_draw_route_to,
147
+ as: nil,
148
+ defaults: expected_default_defaults,
149
+ )
150
+
151
+ assert_that(application_routes.patch_calls.size).equals(1)
152
+ assert_that(application_routes.patch_calls.last.pargs).equals([url_path])
153
+ assert_that(application_routes.patch_calls.last.kargs)
154
+ .equals(
155
+ to: expected_draw_route_to,
156
+ as: url_name,
157
+ defaults: expected_default_defaults,
158
+ )
159
+
160
+ assert_that(application_routes.delete_calls.size).equals(1)
161
+ assert_that(application_routes.delete_calls.last.pargs).equals([url_path])
162
+ assert_that(application_routes.delete_calls.last.kargs)
163
+ .equals(
164
+ to: expected_draw_route_to,
165
+ as: url_name,
166
+ defaults: expected_default_defaults,
167
+ )
168
+ end
169
+
170
+ should "complain when drawing a route with an unknown Action class" do
171
+ action_class_name = "Unknown::Action"
172
+ subject.get(Factory.url, action_class_name, called_from: caller1)
173
+ application_routes = FakeApplicationRoutes.new
174
+
175
+ exception =
176
+ assert_that{ subject.draw(application_routes) }.raises(NameError)
177
+ assert_that(exception.backtrace).equals(caller1)
178
+ end
179
+ end
180
+
181
+ class URLUnitTests < UnitTests
182
+ desc "URL"
183
+ subject{ url_class }
184
+
185
+ let(:url_class){ unit_class::URL }
186
+ end
187
+
188
+ class URLInitTests < URLUnitTests
189
+ desc "when init"
190
+ subject{ url_class.new(router1, url_path1, url_name1) }
191
+
192
+ setup do
193
+ Assert.stub_on_call(
194
+ MuchRails::RailsRoutes.instance,
195
+ :method_missing,
196
+ ) do |call|
197
+ @rails_routes_method_missing_call = call
198
+ "TEST PATH OR URL STRING"
199
+ end
200
+ end
201
+
202
+ let(:url_name1){ Factory.symbol }
203
+ let(:url_path1){ Factory.url }
204
+ let(:router1){ unit_class.new }
205
+
206
+ should have_imeths :path_for, :url_for
207
+
208
+ should "know its attributes" do
209
+ path_string = subject.path_for("TEST PATH ARGS")
210
+ assert_that(path_string).equals("TEST PATH OR URL STRING")
211
+ assert_that(@rails_routes_method_missing_call.args)
212
+ .equals(["#{url_name1}_path".to_sym, "TEST PATH ARGS"])
213
+
214
+ url_string = subject.url_for("TEST URL ARGS")
215
+ assert_that(url_string).equals("TEST PATH OR URL STRING")
216
+ assert_that(@rails_routes_method_missing_call.args)
217
+ .equals(["#{url_name1}_url".to_sym, "TEST URL ARGS"])
218
+ end
219
+ end
220
+
221
+ class FakeApplicationRoutes
222
+ attr_reader :get_calls, :post_calls, :put_calls, :patch_calls, :delete_calls
223
+
224
+ def initialize
225
+ @get_calls = []
226
+ @post_calls = []
227
+ @put_calls = []
228
+ @patch_calls = []
229
+ @delete_calls = []
230
+ end
231
+
232
+ def get(*args)
233
+ @get_calls << Assert::StubCall.new(*args)
234
+ end
235
+
236
+ def post(*args)
237
+ @post_calls << Assert::StubCall.new(*args)
238
+ end
239
+
240
+ def put(*args)
241
+ @put_calls << Assert::StubCall.new(*args)
242
+ end
243
+
244
+ def patch(*args)
245
+ @patch_calls << Assert::StubCall.new(*args)
246
+ end
247
+
248
+ def delete(*args)
249
+ @delete_calls << Assert::StubCall.new(*args)
250
+ end
251
+ end
252
+ end