much-rails 0.1.3 → 0.2.4

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.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MuchRails
4
- VERSION = "0.1.3"
4
+ VERSION = "0.2.4"
5
5
  end
data/much-rails.gemspec CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |gem|
29
29
 
30
30
  gem.add_dependency("activerecord", ["> 5.0", "< 7.0"])
31
31
  gem.add_dependency("activesupport", ["> 5.0", "< 7.0"])
32
- gem.add_dependency("dassets", ["~> 0.15.1"])
32
+ gem.add_dependency("dassets", ["~> 0.15.2"])
33
33
  gem.add_dependency("dassets-erubi", ["~> 0.1.1"])
34
34
  gem.add_dependency("dassets-sass", ["~> 0.5.1"])
35
35
  gem.add_dependency("much-boolean", ["~> 0.2.1"])
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "assert"
4
+ require "much-rails/abstract_class"
5
+
6
+ module MuchRails::AbstractClassTest
7
+ class UnitTests < Assert::Context
8
+ desc "MuchRails::AbstractClass"
9
+ subject{ unit_class }
10
+
11
+ let(:unit_class){ MuchRails::AbstractClass }
12
+
13
+ should "include MuchRails::Mixin" do
14
+ assert_that(subject).includes(MuchRails::Mixin)
15
+ end
16
+ end
17
+
18
+ class ReceiverTests < UnitTests
19
+ desc "receiver"
20
+ subject{ receiver_class }
21
+
22
+ let(:receiver_class) do
23
+ Class.new.tap{ |c| c.include unit_class }
24
+ end
25
+ let(:receiver_subclass) do
26
+ Class.new(receiver_class)
27
+ end
28
+
29
+ should have_accessor :abstract_class
30
+ should have_imeths :new, :abstract_class?
31
+
32
+ should "know if it is an abstract class or not" do
33
+ assert_that(subject.abstract_class?).equals(true)
34
+ assert_that(receiver_subclass.abstract_class?).equals(false)
35
+ end
36
+
37
+ should "prevent calling .new on the receiver" do
38
+ assert_that{ subject.new }.raises(NotImplementedError)
39
+ end
40
+
41
+ should "allow calling .new on subclasses of the receiver" do
42
+ assert_that(receiver_subclass.new).is_a?(subject)
43
+ end
44
+ end
45
+ end
@@ -80,13 +80,13 @@ class MuchRails::Action::BaseRouter
80
80
  end
81
81
 
82
82
  should "build path/URL strings for named URLs" do
83
- path_string = subject.path_for(:url1, "TEST PATH ARGS")
83
+ path_string = subject.path_for(:url1, test: "args")
84
84
  assert_that(path_string).equals("TEST PATH STRING")
85
- assert_that(@url_set_path_for_call.args).equals([:url1, "TEST PATH ARGS"])
85
+ assert_that(@url_set_path_for_call.args).equals([:url1, { test: "args" }])
86
86
 
87
- url_string = subject.url_for(:url1, "TEST URL ARGS")
87
+ url_string = subject.url_for(:url1, test: "args")
88
88
  assert_that(url_string).equals("TEST URL STRING")
89
- assert_that(@url_set_url_for_call.args).equals([:url1, "TEST URL ARGS"])
89
+ assert_that(@url_set_url_for_call.args).equals([:url1, { test: "args" }])
90
90
  end
91
91
 
92
92
  should "define request types" do
@@ -380,13 +380,13 @@ class MuchRails::Action::BaseRouter
380
380
 
381
381
  subject.add(:url1, Factory.url)
382
382
 
383
- path_string = subject.path_for(:url1, "TEST PATH ARGS")
383
+ path_string = subject.path_for(:url1, test: "args")
384
384
  assert_that(path_string).equals("TEST PATH STRING")
385
- assert_that(@url_path_for_call.args).equals(["TEST PATH ARGS"])
385
+ assert_that(@url_path_for_call.args).equals([{ test: "args" }])
386
386
 
387
- url_string = subject.url_for(:url1, "TEST URL ARGS")
387
+ url_string = subject.url_for(:url1, test: "args")
388
388
  assert_that(url_string).equals("TEST URL STRING")
389
- assert_that(@url_url_for_call.args).equals(["TEST URL ARGS"])
389
+ assert_that(@url_url_for_call.args).equals([{ test: "args" }])
390
390
  end
391
391
  end
392
392
 
@@ -450,8 +450,8 @@ class MuchRails::Action::BaseRouter
450
450
  assert_that(subject.path)
451
451
  .equals(base_url_class.url_path(router1, url_path1))
452
452
 
453
- assert_that{ subject.path_for("TEST ARGS") }.raises(NotImplementedError)
454
- assert_that{ subject.url_for("TEST ARGS") }.raises(NotImplementedError)
453
+ assert_that{ subject.path_for(test: "args") }.raises(NotImplementedError)
454
+ assert_that{ subject.url_for(test: "args") }.raises(NotImplementedError)
455
455
  end
456
456
  end
457
457
 
@@ -206,15 +206,15 @@ class MuchRails::Action::Router
206
206
  should have_imeths :path_for, :url_for
207
207
 
208
208
  should "know its attributes" do
209
- path_string = subject.path_for("TEST PATH ARGS")
209
+ path_string = subject.path_for(test: "args")
210
210
  assert_that(path_string).equals("TEST PATH OR URL STRING")
211
211
  assert_that(@rails_routes_method_missing_call.args)
212
- .equals(["#{url_name1}_path".to_sym, "TEST PATH ARGS"])
212
+ .equals(["#{url_name1}_path".to_sym, { test: "args" }])
213
213
 
214
- url_string = subject.url_for("TEST URL ARGS")
214
+ url_string = subject.url_for(test: "args")
215
215
  assert_that(url_string).equals("TEST PATH OR URL STRING")
216
216
  assert_that(@rails_routes_method_missing_call.args)
217
- .equals(["#{url_name1}_url".to_sym, "TEST URL ARGS"])
217
+ .equals(["#{url_name1}_url".to_sym, { test: "args" }])
218
218
  end
219
219
  end
220
220
 
@@ -23,7 +23,7 @@ module MuchRails::Assets
23
23
  setup do
24
24
  subject.reset
25
25
 
26
- in_development_env = Factory.boolean
26
+ in_development_env = true
27
27
  Assert.stub(FakeRails.env, :development?){ in_development_env }
28
28
  Assert.stub(FakeRails.env, :test?){ !in_development_env }
29
29
 
@@ -34,14 +34,11 @@ module MuchRails::Assets
34
34
  subject.configure_for_rails(FakeRails)
35
35
  end
36
36
 
37
- should "configure the fingerprint cache to use a memory cache" do
37
+ should "configure the fingerprint/content cache to use no cache" do
38
38
  assert_that(subject.config.fingerprint_cache)
39
- .is_instance_of(subject::MemCache)
40
- end
41
-
42
- should "configure the content cache to use a memory cache" do
39
+ .is_instance_of(subject::NoCache)
43
40
  assert_that(subject.config.content_cache)
44
- .is_instance_of(subject::MemCache)
41
+ .is_instance_of(subject::NoCache)
45
42
  end
46
43
 
47
44
  should "not configure a file store" do
@@ -49,16 +46,14 @@ module MuchRails::Assets
49
46
  .is_not_equal_to(FakeRails.root.join("public"))
50
47
  end
51
48
 
52
- should "configure the app's app/assets folder as a source" do
49
+ should "configure the app's app/assets/css folder as a source" do
53
50
  source =
54
51
  subject.config.sources.detect do |source|
55
- source.path == FakeRails.root.join("app", "assets").to_s
52
+ source.path == FakeRails.root.join("app", "assets", "css").to_s
56
53
  end
57
54
 
58
55
  assert_that(source).is_not_nil
59
- assert_that(source.engines["js"].size).equals(1)
60
- assert_that(source.engines["js"].first)
61
- .is_instance_of(subject::Erubi::Engine)
56
+ assert_that(source.base_path).equals("css")
62
57
  assert_that(source.engines["scss"].size).equals(2)
63
58
  assert_that(source.engines["scss"].first)
64
59
  .is_instance_of(subject::Erubi::Engine)
@@ -66,6 +61,41 @@ module MuchRails::Assets
66
61
  .is_instance_of(subject::Sass::Engine)
67
62
  end
68
63
 
64
+ should "configure the app's app/assets/img folder as a source" do
65
+ source =
66
+ subject.config.sources.detect do |source|
67
+ source.path == FakeRails.root.join("app", "assets", "img").to_s
68
+ end
69
+
70
+ assert_that(source).is_not_nil
71
+ assert_that(source.base_path).equals("img")
72
+ assert_that(source.engines.empty?).is_true
73
+ end
74
+
75
+ should "configure the app's app/assets/js folder as a source" do
76
+ source =
77
+ subject.config.sources.detect do |source|
78
+ source.path == FakeRails.root.join("app", "assets", "js").to_s
79
+ end
80
+
81
+ assert_that(source).is_not_nil
82
+ assert_that(source.base_path).equals("js")
83
+ assert_that(source.engines["js"].size).equals(1)
84
+ assert_that(source.engines["js"].first)
85
+ .is_instance_of(subject::Erubi::Engine)
86
+ end
87
+
88
+ should "configure the app's app/assets/vendor folder as a source" do
89
+ source =
90
+ subject.config.sources.detect do |source|
91
+ source.path == FakeRails.root.join("app", "assets", "vendor").to_s
92
+ end
93
+
94
+ assert_that(source).is_not_nil
95
+ assert_that(source.base_path).equals("vendor")
96
+ assert_that(source.engines.empty?).is_true
97
+ end
98
+
69
99
  should "initialize itself" do
70
100
  assert_that(@init_call).is_not_nil
71
101
  end
@@ -84,9 +114,11 @@ module MuchRails::Assets
84
114
  subject.configure_for_rails(FakeRails)
85
115
  end
86
116
 
87
- should "configure the content cache to use no cache" do
117
+ should "configure the fingerprint/content cache to use a memory cache" do
118
+ assert_that(subject.config.fingerprint_cache)
119
+ .is_instance_of(subject::MemCache)
88
120
  assert_that(subject.config.content_cache)
89
- .is_instance_of(subject::NoCache)
121
+ .is_instance_of(subject::MemCache)
90
122
  end
91
123
 
92
124
  should "configure a file store for the app's public folder" do
@@ -44,45 +44,189 @@ module MuchRails::DestroyService
44
44
  end
45
45
  end
46
46
 
47
- class DestructionInvalidErrorSetupTests < ReceiverTests
48
- desc "with a MuchRails::Records::ValidateDestroy::DestructionInvalid error"
47
+ class ReceiverInitTests < ReceiverTests
48
+ desc "when init"
49
+ subject{ receiver_class.new(exception: exception) }
50
+
51
+ let(:exception){ nil }
52
+ end
53
+
54
+ class ReceiverInitAroundCallCallbackTests < ReceiverInitTests
55
+ desc "around_call callback"
56
+ setup do
57
+ Assert.stub(
58
+ MuchRails::DestroyService::ValidationErrors,
59
+ :exception_classes,
60
+ ){ exception_classes }
61
+ Assert.stub_on_call(
62
+ MuchRails::DestroyService::ValidationErrors,
63
+ :result_for,
64
+ ) do |call|
65
+ @result_for_call = call
66
+ validation_error_result
67
+ end
68
+ end
69
+
70
+ let(:exception){ exceptions.sample }
71
+ let(:exceptions) do
72
+ [
73
+ RuntimeError.new(Factory.string),
74
+ ArgumentError.new(Factory.string),
75
+ MuchRails::Records::DestructionInvalid.new(FakeRecord.new),
76
+ ]
77
+ end
78
+ let(:exception_classes){ exceptions.map(&:class) }
79
+ let(:validation_error_result) do
80
+ MuchResult.failure(error: result_error_message)
81
+ end
82
+ let(:result_error_message){ Factory.string }
83
+
84
+ should "rescue raised exceptions and "\
85
+ "use the ValidationErrors to build a result" do
86
+ result = subject.call
87
+
88
+ assert_that(result.failure?).is_true
89
+ assert_that(result.error).equals(result_error_message)
90
+ end
91
+ end
92
+
93
+ class ValidationErrorsTests < UnitTests
94
+ desc "ValidationErrors"
95
+ subject{ unit_class::ValidationErrors }
96
+
97
+ should have_imeths :add, :exception_classes, :result_for
98
+ should have_imeths :service_validation_errors
99
+
100
+ should "know its ServiceValidationErrors" do
101
+ assert_that(subject.service_validation_errors)
102
+ .is_an_instance_of(MuchRails::ServiceValidationErrors)
103
+ assert_that(subject.service_validation_errors.exception_classes)
104
+ .includes(MuchRails::Records::DestructionInvalid)
105
+ end
106
+ end
107
+
108
+ class ValidationErrorsAddTests < ValidationErrorsTests
109
+ desc ".add"
110
+
111
+ setup do
112
+ Assert.stub_on_call(subject.service_validation_errors, :add) do |call|
113
+ @add_call = call
114
+ end
115
+ end
116
+
117
+ let(:exception_class){ StandardError }
118
+ let(:block){ proc{ MuchResult.failure } }
119
+
120
+ should "call #add on its ServiceValidationErrors" do
121
+ subject.add(exception_class, &block)
122
+ assert_that(@add_call.args).equals([exception_class])
123
+ assert_that(@add_call.block).is(block)
124
+ end
125
+ end
126
+
127
+ class ValidationErrorsExceptionClassesTests < ValidationErrorsTests
128
+ desc ".exception_classes"
129
+
49
130
  setup do
50
- Assert.stub(exception, :record){ record }
131
+ Assert.stub(
132
+ subject.service_validation_errors,
133
+ :exception_classes,
134
+ ){ exception_classes }
135
+ end
136
+
137
+ let(:exception_classes) do
138
+ [
139
+ StandardError,
140
+ ArgumentError,
141
+ ]
51
142
  end
52
143
 
53
- let(:exception) do
54
- MuchRails::Records::ValidateDestroy::DestructionInvalid.new
144
+ should "call #exception_classes on its ServiceValidationErrors" do
145
+ assert_that(subject.exception_classes).is(exception_classes)
55
146
  end
56
147
  end
57
148
 
58
- class ExceptionWithDestructionErrorMessagesTests <
59
- DestructionInvalidErrorSetupTests
60
- desc "with an exception record that has destruction_error_messages"
149
+ class ValidationErrorsResultForTests < ValidationErrorsTests
150
+ desc ".result_for"
61
151
 
62
- let(:record){ @fake_record ||= FakeRecord.new }
152
+ setup do
153
+ Assert.stub_on_call(
154
+ subject.service_validation_errors,
155
+ :result_for,
156
+ ) do |call|
157
+ @result_for_call = call
158
+ result_for_result
159
+ end
160
+ end
63
161
 
64
- should "return a failure result with the exception and validation_errors" do
65
- result = subject.call(exception: exception)
162
+ let(:exception){ StandardError.new(Factory.string) }
163
+ let(:result_for_result){ MuchResult.failure }
164
+
165
+ should "call #result_for on its ServiceValidationErrors" do
166
+ assert_that(subject.result_for(exception)).is(result_for_result)
167
+ assert_that(@result_for_call.args).equals([exception])
168
+ end
169
+ end
170
+
171
+ class ValidationErrorsResultForDestructionInvalidTests < ValidationErrorsTests
172
+ desc "when .result_for is passed an MuchRails::Records::DestructionInvalid"
173
+
174
+ let(:exception){ MuchRails::Records::DestructionInvalid.new(record) }
175
+ let(:record){ FakeRecord.new }
176
+
177
+ should "return a failure result with the record and validation errors" do
178
+ result = subject.result_for(exception)
66
179
 
67
180
  assert_that(result.failure?).is_true
68
181
  assert_that(result.exception).equals(exception)
69
- assert_that(result.validation_errors).equals(exception.destruction_errors)
182
+ assert_that(result.validation_errors).equals(exception.errors.to_h)
183
+ assert_that(result.validation_error_messages)
184
+ .equals(exception.error_full_messages.to_a)
70
185
  end
71
186
  end
72
187
 
73
- class ExceptionWithoutDestructionErrorMessagesTests <
74
- DestructionInvalidErrorSetupTests
75
- desc "with an exception record that has no destruction_error_messages"
188
+ class FailureResultTests < UnitTests
189
+ desc "FailureResult"
190
+ subject{ unit_class::FailureResult }
191
+
192
+ setup do
193
+ Assert.stub_tap_on_call(MuchResult, :failure) do |_, call|
194
+ @much_result_failure_call = call
195
+ end
196
+ end
76
197
 
77
- let(:record){ nil }
198
+ let(:exception){ StandardError.new(Factory.string) }
199
+ let(:validation_errors){ { Factory.symbol => Factory.string } }
200
+ let(:custom_value){ Factory.string }
78
201
 
79
- should "return a failure result with the exception and empty "\
80
- "validation_errors" do
81
- result = subject.call(exception: exception)
202
+ should have_imeths :new
82
203
 
204
+ should "use MuchResult.failure to build a result" do
205
+ result =
206
+ subject.new(
207
+ exception: exception,
208
+ validation_errors: validation_errors,
209
+ custom: custom_value,
210
+ )
83
211
  assert_that(result.failure?).is_true
84
- assert_that(result.exception).equals(exception)
85
- assert_that(result.validation_errors).equals({})
212
+ assert_that(@much_result_failure_call.kargs)
213
+ .equals(
214
+ exception: exception,
215
+ validation_errors: validation_errors,
216
+ custom: custom_value,
217
+ )
218
+ end
219
+
220
+ should "raise an error without an exception or validation errors" do
221
+ assert_that{
222
+ subject.new(validation_errors: validation_errors)
223
+ }.raises(ArgumentError)
224
+ end
225
+
226
+ should "raise an error without an exception or validation errors" do
227
+ assert_that{
228
+ subject.new(exception: exception)
229
+ }.raises(ArgumentError)
86
230
  end
87
231
  end
88
232
 
@@ -23,10 +23,51 @@ module MuchRails
23
23
  desc ".config"
24
24
  subject{ unit_class.config }
25
25
 
26
- should have_imeths :action
26
+ should have_imeths :action, :layout
27
+ should have_imeths :add_save_service_validation_error
28
+ should have_imeths :add_destroy_service_validation_error
27
29
 
28
30
  should "be configured as expected" do
29
31
  assert_that(subject.action).is_not_nil
32
+ assert_that(subject.layout).is_not_nil
33
+ end
34
+ end
35
+
36
+ class ConfigServiceValidationErrorTests < ConfigTests
37
+ setup do
38
+ Assert.stub_on_call(
39
+ MuchRails::SaveService::ValidationErrors,
40
+ :add,
41
+ ) do |call|
42
+ @save_service_validation_errors_add_call = call
43
+ end
44
+ Assert.stub_on_call(
45
+ MuchRails::DestroyService::ValidationErrors,
46
+ :add,
47
+ ) do |call|
48
+ @destroy_service_validation_errors_add_call = call
49
+ end
50
+ end
51
+
52
+ let(:exception_class){ StandardError }
53
+ let(:block){ proc{ MuchResult.failure } }
54
+
55
+ should "know how to add an exception class "\
56
+ "to the save service validation errors" do
57
+ subject.add_save_service_validation_error(exception_class, &block)
58
+ assert_that(@save_service_validation_errors_add_call.args)
59
+ .equals([exception_class])
60
+ assert_that(@save_service_validation_errors_add_call.block)
61
+ .is(block)
62
+ end
63
+
64
+ should "know how to add an exception class "\
65
+ "to the destroy service validation errors" do
66
+ subject.add_destroy_service_validation_error(exception_class, &block)
67
+ assert_that(@destroy_service_validation_errors_add_call.args)
68
+ .equals([exception_class])
69
+ assert_that(@destroy_service_validation_errors_add_call.block)
70
+ .is(block)
30
71
  end
31
72
  end
32
73