mr 0.35.2

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 (115) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/Gemfile +13 -0
  4. data/LICENSE +22 -0
  5. data/README.md +29 -0
  6. data/bench/all.rb +4 -0
  7. data/bench/factory.rb +68 -0
  8. data/bench/fake_record.rb +174 -0
  9. data/bench/model.rb +201 -0
  10. data/bench/read_model.rb +191 -0
  11. data/bench/results/factory.txt +21 -0
  12. data/bench/results/fake_record.txt +37 -0
  13. data/bench/results/model.txt +44 -0
  14. data/bench/results/read_model.txt +46 -0
  15. data/bench/setup.rb +132 -0
  16. data/lib/mr.rb +11 -0
  17. data/lib/mr/after_commit.rb +49 -0
  18. data/lib/mr/after_commit/fake_record.rb +39 -0
  19. data/lib/mr/after_commit/record.rb +48 -0
  20. data/lib/mr/after_commit/record_procs_methods.rb +82 -0
  21. data/lib/mr/factory.rb +82 -0
  22. data/lib/mr/factory/config.rb +240 -0
  23. data/lib/mr/factory/model_factory.rb +103 -0
  24. data/lib/mr/factory/model_stack.rb +28 -0
  25. data/lib/mr/factory/read_model_factory.rb +104 -0
  26. data/lib/mr/factory/record_factory.rb +130 -0
  27. data/lib/mr/factory/record_stack.rb +219 -0
  28. data/lib/mr/fake_query.rb +53 -0
  29. data/lib/mr/fake_record.rb +58 -0
  30. data/lib/mr/fake_record/associations.rb +257 -0
  31. data/lib/mr/fake_record/attributes.rb +168 -0
  32. data/lib/mr/fake_record/persistence.rb +116 -0
  33. data/lib/mr/json_field.rb +180 -0
  34. data/lib/mr/json_field/fake_record.rb +31 -0
  35. data/lib/mr/json_field/record.rb +38 -0
  36. data/lib/mr/model.rb +67 -0
  37. data/lib/mr/model/associations.rb +161 -0
  38. data/lib/mr/model/configuration.rb +67 -0
  39. data/lib/mr/model/fields.rb +177 -0
  40. data/lib/mr/model/persistence.rb +79 -0
  41. data/lib/mr/query.rb +126 -0
  42. data/lib/mr/read_model.rb +83 -0
  43. data/lib/mr/read_model/data.rb +38 -0
  44. data/lib/mr/read_model/fields.rb +218 -0
  45. data/lib/mr/read_model/query_expression.rb +188 -0
  46. data/lib/mr/read_model/querying.rb +214 -0
  47. data/lib/mr/read_model/set_querying.rb +82 -0
  48. data/lib/mr/read_model/subquery.rb +98 -0
  49. data/lib/mr/record.rb +35 -0
  50. data/lib/mr/test_helpers.rb +229 -0
  51. data/lib/mr/type_converter.rb +85 -0
  52. data/lib/mr/version.rb +3 -0
  53. data/log/.gitkeep +0 -0
  54. data/mr.gemspec +29 -0
  55. data/test/helper.rb +21 -0
  56. data/test/support/db.rb +10 -0
  57. data/test/support/factory.rb +13 -0
  58. data/test/support/factory/area.rb +6 -0
  59. data/test/support/factory/comment.rb +14 -0
  60. data/test/support/factory/image.rb +6 -0
  61. data/test/support/factory/user.rb +6 -0
  62. data/test/support/models/area.rb +58 -0
  63. data/test/support/models/comment.rb +60 -0
  64. data/test/support/models/image.rb +53 -0
  65. data/test/support/models/user.rb +96 -0
  66. data/test/support/read_model/querying.rb +150 -0
  67. data/test/support/read_models/comment_with_user_data.rb +27 -0
  68. data/test/support/read_models/set_data.rb +49 -0
  69. data/test/support/read_models/subquery_data.rb +41 -0
  70. data/test/support/read_models/user_with_area_data.rb +15 -0
  71. data/test/support/schema.rb +39 -0
  72. data/test/support/setup_test_db.rb +10 -0
  73. data/test/system/factory/model_factory_tests.rb +87 -0
  74. data/test/system/factory/model_stack_tests.rb +30 -0
  75. data/test/system/factory/record_factory_tests.rb +84 -0
  76. data/test/system/factory/record_stack_tests.rb +51 -0
  77. data/test/system/factory_tests.rb +32 -0
  78. data/test/system/read_model_tests.rb +199 -0
  79. data/test/system/with_model_tests.rb +275 -0
  80. data/test/unit/after_commit/fake_record_tests.rb +110 -0
  81. data/test/unit/after_commit/record_procs_methods_tests.rb +177 -0
  82. data/test/unit/after_commit/record_tests.rb +134 -0
  83. data/test/unit/after_commit_tests.rb +113 -0
  84. data/test/unit/factory/config_tests.rb +651 -0
  85. data/test/unit/factory/model_factory_tests.rb +473 -0
  86. data/test/unit/factory/model_stack_tests.rb +97 -0
  87. data/test/unit/factory/read_model_factory_tests.rb +195 -0
  88. data/test/unit/factory/record_factory_tests.rb +446 -0
  89. data/test/unit/factory/record_stack_tests.rb +549 -0
  90. data/test/unit/factory_tests.rb +213 -0
  91. data/test/unit/fake_query_tests.rb +137 -0
  92. data/test/unit/fake_record/associations_tests.rb +585 -0
  93. data/test/unit/fake_record/attributes_tests.rb +265 -0
  94. data/test/unit/fake_record/persistence_tests.rb +239 -0
  95. data/test/unit/fake_record_tests.rb +106 -0
  96. data/test/unit/json_field/fake_record_tests.rb +75 -0
  97. data/test/unit/json_field/record_tests.rb +80 -0
  98. data/test/unit/json_field_tests.rb +302 -0
  99. data/test/unit/model/associations_tests.rb +346 -0
  100. data/test/unit/model/configuration_tests.rb +92 -0
  101. data/test/unit/model/fields_tests.rb +278 -0
  102. data/test/unit/model/persistence_tests.rb +114 -0
  103. data/test/unit/model_tests.rb +137 -0
  104. data/test/unit/query_tests.rb +300 -0
  105. data/test/unit/read_model/data_tests.rb +56 -0
  106. data/test/unit/read_model/fields_tests.rb +416 -0
  107. data/test/unit/read_model/query_expression_tests.rb +381 -0
  108. data/test/unit/read_model/querying_tests.rb +613 -0
  109. data/test/unit/read_model/set_querying_tests.rb +149 -0
  110. data/test/unit/read_model/subquery_tests.rb +242 -0
  111. data/test/unit/read_model_tests.rb +187 -0
  112. data/test/unit/record_tests.rb +45 -0
  113. data/test/unit/test_helpers_tests.rb +431 -0
  114. data/test/unit/type_converter_tests.rb +207 -0
  115. metadata +285 -0
@@ -0,0 +1,473 @@
1
+ require 'assert'
2
+ require 'mr/factory/model_factory'
3
+
4
+ require 'mr/factory/config'
5
+ require 'mr/factory/record_factory'
6
+ require 'mr/fake_record'
7
+ require 'mr/test_helpers'
8
+ require 'mr/model'
9
+ require 'mr/record'
10
+
11
+ class MR::Factory::ModelFactory
12
+
13
+ class UnitTests < Assert::Context
14
+ include MR::TestHelpers
15
+
16
+ desc "MR::Factory::ModelFactory"
17
+ setup do
18
+ @factory_class = MR::Factory::ModelFactory
19
+ end
20
+ subject{ @factory_class }
21
+
22
+ end
23
+
24
+ class InitTests < UnitTests
25
+ desc "when init"
26
+ setup do
27
+ @model_class = FakeTwoModel
28
+ @record_class = @model_class.record_class
29
+
30
+ @record_factory = nil
31
+ Assert.stub(MR::Factory::RecordFactory, :new) do |*args|
32
+ @record_factory ||= Assert.stub_send(MR::Factory::RecordFactory, :new, *args)
33
+ end
34
+
35
+ @factory = @factory_class.new(@model_class, @record_class)
36
+ end
37
+ subject{ @factory }
38
+
39
+ should have_readers :model_class, :record_class, :config
40
+ should have_imeths :model, :instance
41
+ should have_imeths :saved_model, :saved_instance
42
+ should have_imeths :stack, :instance_stack
43
+ should have_imeths :stack_model, :saved_stack, :saved_stack_model
44
+ should have_imeths :saved_dependencies_stack, :saved_deps_stack
45
+ should have_imeths :saved_dependencies_stack_model, :saved_deps_stack_model
46
+
47
+ should "instance eval any block it's initialized with" do
48
+ yielded = nil
49
+ factory = @factory_class.new(@model_class, @record_class){ yielded = self }
50
+ assert_equal factory, yielded
51
+ end
52
+
53
+ should "know its model class, record class, and config" do
54
+ assert_equal @model_class, subject.model_class
55
+ assert_equal @record_class, subject.record_class
56
+
57
+ assert_instance_of Config, subject.config
58
+ assert_equal subject.record_class, subject.config.record_class
59
+ end
60
+
61
+ should "build a record factory for its record class" do
62
+ assert_not_nil @record_factory
63
+ assert_equal @record_class, @record_factory.record_class
64
+ end
65
+
66
+ should "allow configuring a default association" do
67
+ associated_factory = @factory_class.new(FakeOneModel, FakeOneRecord)
68
+ association_name = Factory.boolean ? :fake_one : :fake_poly
69
+ factory = @factory_class.new(@model_class, @record_class) do
70
+ default_association(association_name, associated_factory, {
71
+ :force_in_stack => true
72
+ })
73
+ end
74
+
75
+ associated_model = associated_factory.model
76
+ Assert.stub(associated_factory, :model){ associated_model }
77
+
78
+ result = factory.config.build_associated_model(
79
+ association_name,
80
+ associated_factory.record_class
81
+ )
82
+ assert_same associated_model, result
83
+
84
+ assert_includes association_name, factory.config.force_in_stack_association_names
85
+ end
86
+
87
+ should "allow configuring default args" do
88
+ name = Factory.string
89
+ default_args_proc = proc{ set(:name, name) }
90
+ factory = @factory_class.new(@model_class, @record_class)
91
+
92
+ set_default_args_called_with = nil
93
+ Assert.stub(factory.config, :set_default_args) do |&block|
94
+ set_default_args_called_with = block
95
+ Assert.stub_send(factory.config, :set_default_args, &block)
96
+ end
97
+
98
+ factory.instance_eval{ default_args(&default_args_proc) }
99
+ assert_equal default_args_proc, set_default_args_called_with
100
+
101
+ model = factory.model
102
+ assert_equal name, model.name
103
+ end
104
+
105
+ end
106
+
107
+ class ModelMethodTests < InitTests
108
+ desc "model"
109
+ setup do
110
+ @built_record = nil
111
+ Assert.stub(@record_factory, :record) do |*args|
112
+ @built_record = Assert.stub_send(@record_factory, :record, *args)
113
+ end
114
+ end
115
+
116
+ should "return an instance of the model class" do
117
+ model = subject.model
118
+ assert_instance_of @model_class, model
119
+ assert_same @built_record, model.record
120
+ end
121
+
122
+ should "be aliased" do
123
+ model = subject.instance
124
+ assert_instance_of @model_class, model
125
+ assert_same @built_record, model.record
126
+ end
127
+
128
+ should "apply passed args to the model" do
129
+ name = Factory.string
130
+ model = subject.model(:name => name)
131
+ assert_equal name, model.name
132
+ end
133
+
134
+ should "apply default args to the model" do
135
+ name = Factory.string
136
+ subject.instance_eval{ default_args{ set(:name, name) } }
137
+ model = subject.model
138
+ assert_equal name, model.name
139
+ end
140
+
141
+ should "apply passed args over default args to the model" do
142
+ name = Factory.string
143
+ subject.instance_eval{ default_args{ set(:name, name) } }
144
+ new_name = Factory.string
145
+ model = subject.model(:name => new_name)
146
+ assert_equal new_name, model.name
147
+ end
148
+
149
+ end
150
+
151
+ class SavedModelMethodTests < InitTests
152
+ desc "saved_model"
153
+ setup do
154
+ @model_called_with = nil
155
+ @built_model = nil
156
+ Assert.stub(subject, :model) do |*args|
157
+ @model_called_with = args
158
+ @built_model = Assert.stub_send(subject, :model, *args)
159
+ end
160
+ end
161
+
162
+ should "build an instance of the model class and save it" do
163
+ saved_model = subject.saved_model
164
+ assert_equal [nil], @model_called_with
165
+ assert_same @built_model, saved_model
166
+ assert_false saved_model.new?
167
+ end
168
+
169
+ should "be aliased" do
170
+ saved_model = subject.saved_instance
171
+ assert_equal [nil], @model_called_with
172
+ assert_same @built_model, saved_model
173
+ assert_false saved_model.new?
174
+ end
175
+
176
+ should "allow passing args when building a saved model" do
177
+ args = { :name => Factory.string }
178
+ saved_model = subject.saved_model(args)
179
+ assert_equal [args], @model_called_with
180
+ end
181
+
182
+ should "reset the fake models save called flag" do
183
+ assert_not_model_saved subject.saved_model
184
+ end
185
+
186
+ end
187
+
188
+ class StackMethodTests < InitTests
189
+ desc "stack"
190
+ setup do
191
+ @model_called_with = nil
192
+ @built_model = nil
193
+ Assert.stub(subject, :model) do |*args|
194
+ @model_called_with = args
195
+ @built_model = Assert.stub_send(subject, :model, *args)
196
+ end
197
+ end
198
+
199
+ should "build a model stack" do
200
+ stack = subject.stack
201
+ assert_instance_of MR::Factory::ModelStack, stack
202
+ assert_equal [nil], @model_called_with
203
+ assert_same @built_model, stack.model
204
+ assert_same subject.config, stack.factory_config
205
+ end
206
+
207
+ should "be aliased" do
208
+ stack = subject.instance_stack
209
+ assert_instance_of MR::Factory::ModelStack, stack
210
+ assert_equal [nil], @model_called_with
211
+ assert_same @built_model, stack.model
212
+ assert_same subject.config, stack.factory_config
213
+ end
214
+
215
+ should "allow passing args when building a stack" do
216
+ args = { :name => Factory.string }
217
+ stack = subject.stack(args)
218
+ assert_equal [args], @model_called_with
219
+ end
220
+
221
+ end
222
+
223
+ class StackModelMethodTests < InitTests
224
+ desc "stack_model"
225
+ setup do
226
+ @stack_called_with = nil
227
+ @built_stack = nil
228
+ Assert.stub(subject, :stack) do |*args|
229
+ @stack_called_with = args
230
+ @built_stack = Assert.stub_send(subject, :stack, *args)
231
+ end
232
+ end
233
+
234
+ should "build a stack model" do
235
+ model = subject.stack_model
236
+ assert_equal [nil], @stack_called_with
237
+ assert_same @built_stack.model, model
238
+ end
239
+
240
+ should "allow passing args when building a stack model" do
241
+ args = { :name => Factory.string }
242
+ model = subject.stack_model(args)
243
+ assert_equal [args], @stack_called_with
244
+ end
245
+
246
+ end
247
+
248
+ class SavedStackMethodTests < InitTests
249
+ desc "saved_stack"
250
+ setup do
251
+ @stack_called_with = nil
252
+ @built_stack = nil
253
+ @stack_create_called = false
254
+ Assert.stub(subject, :stack) do |*args|
255
+ @stack_called_with = args
256
+ @built_stack = Assert.stub_send(subject, :stack, *args)
257
+ Assert.stub(@built_stack, :create) do
258
+ @stack_create_called = true
259
+ Assert.stub_send(@built_stack, :create)
260
+ end
261
+ @built_stack
262
+ end
263
+ end
264
+
265
+ should "build a saved stack" do
266
+ saved_stack = subject.saved_stack
267
+ assert_equal [nil], @stack_called_with
268
+ assert_same @built_stack, saved_stack
269
+ assert_true @stack_create_called
270
+ end
271
+
272
+ should "allow passing args when building a saved stack model" do
273
+ args = { :name => Factory.string }
274
+ saved_stack = subject.saved_stack(args)
275
+ assert_equal [args], @stack_called_with
276
+ end
277
+
278
+ end
279
+
280
+ class SavedStackModelMethodTests < InitTests
281
+ desc "saved_stack_model"
282
+ setup do
283
+ @saved_stack_called_with = nil
284
+ @built_saved_stack = nil
285
+ Assert.stub(subject, :saved_stack) do |*args|
286
+ @saved_stack_called_with = args
287
+ @built_saved_stack = Assert.stub_send(subject, :saved_stack, *args)
288
+ end
289
+ end
290
+
291
+ should "build a saved stack model" do
292
+ saved_model = subject.saved_stack_model
293
+ assert_equal [nil], @saved_stack_called_with
294
+ assert_same @built_saved_stack.model, saved_model
295
+ end
296
+
297
+ should "allow passing args when building a saved stack model" do
298
+ args = { :name => Factory.string }
299
+ saved_model = subject.saved_stack_model(args)
300
+ assert_equal [args], @saved_stack_called_with
301
+ end
302
+
303
+ end
304
+
305
+ class SavedDepsStackMethodTests < InitTests
306
+ desc "saved_dependencies_stack"
307
+ setup do
308
+ @stack_called_with = nil
309
+ @built_stack = nil
310
+ @stack_create_deps_called = false
311
+ Assert.stub(subject, :stack) do |*args|
312
+ @stack_called_with = args
313
+ @built_stack = Assert.stub_send(subject, :stack, *args)
314
+ Assert.stub(@built_stack, :create_deps) do
315
+ @stack_create_deps_called = true
316
+ Assert.stub_send(@built_stack, :create_deps)
317
+ end
318
+ @built_stack
319
+ end
320
+ end
321
+
322
+ should "build a saved dependencies stack" do
323
+ saved_deps_stack = subject.saved_dependencies_stack
324
+ assert_equal [nil], @stack_called_with
325
+ assert_same @built_stack, saved_deps_stack
326
+ assert_true @stack_create_deps_called
327
+ end
328
+
329
+ should "be aliased" do
330
+ saved_deps_stack = subject.saved_deps_stack
331
+ assert_equal [nil], @stack_called_with
332
+ assert_same @built_stack, saved_deps_stack
333
+ assert_true @stack_create_deps_called
334
+ end
335
+
336
+ should "allow passing args when building a saved dependencies stack" do
337
+ args = { :name => Factory.string }
338
+ saved_deps_stack = subject.saved_dependencies_stack(args)
339
+ assert_equal [args], @stack_called_with
340
+ end
341
+
342
+ end
343
+
344
+ class SavedDepsStackModelTests < InitTests
345
+ desc "saved_dependencies_stack_model"
346
+ setup do
347
+ @saved_deps_stack_called_with = nil
348
+ @built_saved_deps_stack = nil
349
+ Assert.stub(subject, :saved_deps_stack) do |*args|
350
+ @saved_deps_stack_called_with = args
351
+ @built_saved_deps_stack = Assert.stub_send(subject, :saved_deps_stack, *args)
352
+ end
353
+ end
354
+
355
+ should "know how to build a saved dependencies stack model" do
356
+ saved_deps_model = subject.saved_dependencies_stack_model
357
+ assert_equal [nil], @saved_deps_stack_called_with
358
+ assert_same @built_saved_deps_stack.model, saved_deps_model
359
+ end
360
+
361
+ should "be aliased" do
362
+ saved_deps_model = subject.saved_deps_stack_model
363
+ assert_equal [nil], @saved_deps_stack_called_with
364
+ assert_same @built_saved_deps_stack.model, saved_deps_model
365
+ end
366
+
367
+ should "allow passing args when building a saved dependencies stack model" do
368
+ args = { :name => Factory.string }
369
+ saved_deps_model = subject.saved_dependencies_stack_model(args)
370
+ assert_equal [args], @saved_deps_stack_called_with
371
+ assert_same @built_saved_deps_stack.model, saved_deps_model
372
+ end
373
+
374
+ end
375
+
376
+ class ConfigTests < UnitTests
377
+ desc "Config"
378
+ setup do
379
+ @config_class = Config
380
+ end
381
+ subject{ @config_class }
382
+
383
+ should "be a with-associations factory config" do
384
+ assert_includes MR::Factory::WithAssociationsConfig, subject
385
+ end
386
+
387
+ end
388
+
389
+ class ConfigInitTests < ConfigTests
390
+ desc "when init"
391
+ setup do
392
+ @record_class = FakeTwoRecord
393
+ @config = @config_class.new(@record_class)
394
+ end
395
+ subject{ @config }
396
+
397
+ should have_imeths :build_associated_model, :build_associated_record
398
+ should have_imeths :ar_association_for
399
+
400
+ should "know how to build an associated model and record" do
401
+ factory_for_called_with = []
402
+ built_factory = nil
403
+ model = nil
404
+ Assert.stub(subject, :factory_for) do |*args|
405
+ factory_for_called_with = args
406
+ built_factory = Assert.stub_send(subject, :factory_for, *args)
407
+ model = built_factory.model
408
+ Assert.stub(built_factory, :model){ model }
409
+ built_factory
410
+ end
411
+
412
+ association_name = Factory.boolean ? :fake_one : :fake_poly
413
+ assoc_record_class = FakeOneRecord
414
+ result = subject.build_associated_record(association_name, assoc_record_class)
415
+
416
+ assert_equal [association_name, assoc_record_class], factory_for_called_with
417
+ assert_instance_of MR::Factory::ModelFactory, built_factory
418
+ assert_equal assoc_record_class, built_factory.record_class
419
+ assert_equal assoc_record_class.model_class, built_factory.model_class
420
+
421
+ assert_same model, subject.build_associated_model(
422
+ association_name,
423
+ assoc_record_class
424
+ )
425
+ assert_same model.record, subject.build_associated_record(
426
+ association_name,
427
+ assoc_record_class
428
+ )
429
+ end
430
+
431
+ should "know how to get an activerecord association for a model" do
432
+ model = @record_class.model_class.new
433
+
434
+ exp = model.record.association(:fake_one)
435
+ assert_equal exp, subject.ar_association_for(model, :fake_one)
436
+
437
+ assert_nil subject.ar_association_for(model, Factory.string)
438
+ end
439
+
440
+ end
441
+
442
+ class FakeOneRecord
443
+ include MR::FakeRecord
444
+ end
445
+
446
+ class FakeTwoRecord
447
+ include MR::FakeRecord
448
+
449
+ attribute :name, :string
450
+ attribute :fake_poly_type, :string
451
+ attribute :fake_poly_id, :integer
452
+ attribute :fake_one_id, :integer
453
+
454
+ belongs_to :fake_poly, :polymorphic => true
455
+ belongs_to :fake_one, :class_name => FakeOneRecord.to_s
456
+ end
457
+
458
+ class FakeOneModel
459
+ include MR::Model
460
+ record_class FakeOneRecord
461
+ end
462
+
463
+ class FakeTwoModel
464
+ include MR::Model
465
+ record_class FakeTwoRecord
466
+
467
+ field_accessor :name, :fake_poly_type, :fake_poly_id, :fake_one_id
468
+
469
+ polymorphic_belongs_to :fake_poly
470
+ belongs_to :fake_one
471
+ end
472
+
473
+ end