mr 0.35.2

Sign up to get free protection for your applications and to get access to all the features.
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,106 @@
1
+ require 'assert'
2
+ require 'mr/fake_record'
3
+
4
+ require 'much-plugin'
5
+
6
+ module MR::FakeRecord
7
+
8
+ class UnitTests < Assert::Context
9
+ desc "MR::FakeRecord"
10
+ setup do
11
+ @module = MR::FakeRecord
12
+ end
13
+ subject{ @module }
14
+
15
+ should "use much-plugin" do
16
+ assert_includes MuchPlugin, subject
17
+ end
18
+
19
+ should "extend the persistence transaction methods mixin" do
20
+ metaclass = class << subject; self; end
21
+ assert_includes MR::FakeRecord::Persistence::TransactionMethods, metaclass
22
+ end
23
+
24
+ end
25
+
26
+ class MixedInTests < UnitTests
27
+ desc "when mixed in"
28
+ setup do
29
+ @fake_record_class = Class.new do
30
+ include MR::FakeRecord
31
+ attribute :name, :string
32
+ attribute :active, :boolean
33
+ end
34
+ end
35
+ subject{ @fake_record_class }
36
+
37
+ should have_imeths :model_class
38
+
39
+ should "be an MR record" do
40
+ assert_includes MR::Record, subject
41
+ end
42
+
43
+ should "include the associations, attributes and persistence mixins" do
44
+ assert_includes MR::FakeRecord::Associations, subject
45
+ assert_includes MR::FakeRecord::Attributes, subject
46
+ assert_includes MR::FakeRecord::Persistence, subject
47
+ end
48
+
49
+ should "allow reading and writing it's model class using `model_class`" do
50
+ assert_nil subject.model_class
51
+ model_class = Class.new
52
+ subject.model_class(model_class)
53
+ assert_equal model_class, subject.model_class
54
+ end
55
+
56
+ should "allow passing attributes to it's initialize" do
57
+ fake_record = subject.new(:name => 'test')
58
+ assert_equal 'test', fake_record.name
59
+ end
60
+
61
+ end
62
+
63
+ class InitTests < MixedInTests
64
+ desc "and init"
65
+ setup do
66
+ @fake_record = @fake_record_class.new({
67
+ :name => 'test',
68
+ :active => true
69
+ })
70
+ @fake_record.save!
71
+ end
72
+ subject{ @fake_record }
73
+
74
+ should have_imeths :==, :eql?, :hash, :inspect
75
+
76
+ should "return a readable inspect" do
77
+ object_hex = (subject.object_id << 1).to_s(16)
78
+ expected = "#<#{subject.class}:0x#{object_hex} @active=true " \
79
+ "@id=#{subject.id} @name=\"test\">"
80
+ assert_equal expected, subject.inspect
81
+ end
82
+
83
+ should "be comparable" do
84
+ same_fake_record = @fake_record_class.new(:id => @fake_record.id)
85
+ assert_equal same_fake_record, subject
86
+ other_fake_record = @fake_record_class.new.tap(&:save!)
87
+ assert_not_equal other_fake_record, subject
88
+ end
89
+
90
+ should "demeter its fixnum hash value to its id" do
91
+ assert_equal subject.id.hash, subject.hash
92
+ end
93
+
94
+ should "ensure it's attribute changed methods work after an empty save" do
95
+ assert_not_nil subject.name
96
+ assert_true subject.active
97
+ subject.save! # empty save, nothing was changed
98
+ subject.name = nil # set a previously set attribute to `nil`
99
+ subject.active = true # set it to what it previous was
100
+ assert subject.name_changed?
101
+ assert_not subject.active_changed?
102
+ end
103
+
104
+ end
105
+
106
+ end
@@ -0,0 +1,75 @@
1
+ require 'assert'
2
+ require 'mr/json_field/fake_record'
3
+
4
+ require 'much-plugin'
5
+ require 'mr/json_field'
6
+ require 'mr/model'
7
+
8
+ module MR::JsonField::FakeRecord
9
+
10
+ class UnitTests < Assert::Context
11
+ desc "MR::JsonField::FakeRecord"
12
+ subject{ MR::JsonField::FakeRecord }
13
+
14
+ should "use much-plugin" do
15
+ assert_includes MuchPlugin, subject
16
+ end
17
+
18
+ end
19
+
20
+ class MixinTests < UnitTests
21
+ desc "when mixed in"
22
+ setup do
23
+ @fake_record_class = Class.new do
24
+ include MR::JsonField::FakeRecord
25
+ attribute :hash_data_json, :text
26
+ attribute :array_data_json, :text
27
+ end
28
+ end
29
+ subject{ @fake_record_class }
30
+
31
+ end
32
+
33
+ class InitTests < MixinTests
34
+ desc "and init"
35
+ setup do
36
+ @model_class = Class.new do
37
+ include MR::Model
38
+ field_accessor :hash_data_json, :array_data_json
39
+
40
+ include MR::JsonField
41
+ json_field :hash_data
42
+ json_field :array_data
43
+ end
44
+ @fake_record_class.model_class(@model_class)
45
+
46
+ @fake_record = @fake_record_class.new
47
+ @model = @fake_record.model
48
+ end
49
+ subject{ @fake_record }
50
+
51
+ should "sync all of its json fields on save" do
52
+ @model.hash_data = { Factory.string => Factory.string }
53
+ @model.array_data = Factory.integer(3).times.map{ Factory.string }
54
+
55
+ # since we used the writer the fields and their source should be equal
56
+ assert_equal @model.hash_data, MR::JsonField.decode(subject.hash_data_json)
57
+ assert_equal @model.array_data, MR::JsonField.decode(subject.array_data_json)
58
+
59
+ @model.hash_data[Factory.string] = Factory.string
60
+ @model.array_data << Factory.string
61
+ # since we modified the fields and didn't use the writer, their source
62
+ # should not be equal
63
+ assert_not_equal @model.hash_data, MR::JsonField.decode(subject.hash_data_json)
64
+ assert_not_equal @model.array_data, MR::JsonField.decode(subject.array_data_json)
65
+
66
+ subject.save!
67
+
68
+ # now that the callback has been run they should be equal once again
69
+ assert_equal @model.hash_data, MR::JsonField.decode(subject.hash_data_json)
70
+ assert_equal @model.array_data, MR::JsonField.decode(subject.array_data_json)
71
+ end
72
+
73
+ end
74
+
75
+ end
@@ -0,0 +1,80 @@
1
+ require 'assert'
2
+ require 'mr/json_field/record'
3
+
4
+ require 'ardb/record_spy'
5
+ require 'much-plugin'
6
+ require 'mr/json_field'
7
+ require 'mr/model'
8
+
9
+ module MR::JsonField::Record
10
+
11
+ class UnitTests < Assert::Context
12
+ desc "MR::JsonField::Record"
13
+ subject{ MR::JsonField::Record }
14
+
15
+ should "use much-plugin" do
16
+ assert_includes MuchPlugin, subject
17
+ end
18
+
19
+ end
20
+
21
+ class MixinTests < UnitTests
22
+ desc "when mixed in"
23
+ setup do
24
+ @record_class = Ardb::RecordSpy.new do
25
+ include MR::JsonField::Record
26
+ attr_accessor :hash_data_json, :array_data_json
27
+ end
28
+ end
29
+ subject{ @record_class }
30
+
31
+ should "add a before save callback" do
32
+ callback = subject.callbacks.find{ |c| c.type == :before_save }
33
+ assert_equal :json_field_sync_all_json_fields_on_save, callback.args.first
34
+ end
35
+
36
+ end
37
+
38
+ class InitTests < MixinTests
39
+ desc "and init"
40
+ setup do
41
+ @model_class = Class.new do
42
+ include MR::Model
43
+ field_accessor :hash_data_json, :array_data_json
44
+
45
+ include MR::JsonField
46
+ json_field :hash_data
47
+ json_field :array_data
48
+ end
49
+ @record_class.model_class = @model_class
50
+
51
+ @record = @record_class.new
52
+ @model = @record.model
53
+ end
54
+ subject{ @record }
55
+
56
+ should "sync all of its json fields on save" do
57
+ @model.hash_data = { Factory.string => Factory.string }
58
+ @model.array_data = Factory.integer(3).times.map{ Factory.string }
59
+
60
+ # since we used the writer the fields and their source should be equal
61
+ assert_equal @model.hash_data, MR::JsonField.decode(subject.hash_data_json)
62
+ assert_equal @model.array_data, MR::JsonField.decode(subject.array_data_json)
63
+
64
+ @model.hash_data[Factory.string] = Factory.string
65
+ @model.array_data << Factory.string
66
+ # since we modified the fields and didn't use the writer, their source
67
+ # should not be equal
68
+ assert_not_equal @model.hash_data, MR::JsonField.decode(subject.hash_data_json)
69
+ assert_not_equal @model.array_data, MR::JsonField.decode(subject.array_data_json)
70
+
71
+ subject.instance_eval{ json_field_sync_all_json_fields_on_save }
72
+
73
+ # now that the callback has been run they should be equal once again
74
+ assert_equal @model.hash_data, MR::JsonField.decode(subject.hash_data_json)
75
+ assert_equal @model.array_data, MR::JsonField.decode(subject.array_data_json)
76
+ end
77
+
78
+ end
79
+
80
+ end
@@ -0,0 +1,302 @@
1
+ require 'assert'
2
+ require 'mr/json_field'
3
+
4
+ require 'much-plugin'
5
+
6
+ module MR::JsonField
7
+
8
+ class UnitTests < Assert::Context
9
+ desc "MR::JsonField"
10
+ setup do
11
+ @module = MR::JsonField
12
+
13
+ @orig_encoder = @module.encoder
14
+ @orig_decoder = @module.decoder
15
+ end
16
+ teardown do
17
+ @module.encoder = @orig_encoder
18
+ @module.decoder = @orig_decoder
19
+ end
20
+ subject{ @module }
21
+
22
+ should have_imeths :encoder, :encoder=
23
+ should have_imeths :decoder, :decoder=
24
+ should have_imeths :encode, :decode
25
+
26
+ should "use much-plugin" do
27
+ assert_includes MuchPlugin, subject
28
+ end
29
+
30
+ should "know its default encoder and decoder" do
31
+ value = { Factory.string => Factory.string }
32
+
33
+ exp = JSON.dump(value)
34
+ assert_equal exp, DEFAULT_ENCODER.call(value)
35
+
36
+ encoded_value = exp
37
+ exp = JSON.load(encoded_value)
38
+ assert_equal exp, DEFAULT_DECODER.call(encoded_value)
39
+ end
40
+
41
+ should "default its encoder and decoder" do
42
+ assert_equal DEFAULT_ENCODER, subject.encoder
43
+ assert_equal DEFAULT_DECODER, subject.decoder
44
+ end
45
+
46
+ should "use its encoder/decoder when encoding/decoding" do
47
+ value = { Factory.string => Factory.string }
48
+
49
+ exp = subject.encoder.call(value)
50
+ assert_equal exp, subject.encode(value)
51
+
52
+ encoded_value = exp
53
+ exp = subject.decoder.call(encoded_value)
54
+ assert_equal exp, subject.decode(encoded_value)
55
+ end
56
+
57
+ should "allow specifying a custom encoder/decoder" do
58
+ subject.encoder = proc{ |v| v.to_s }
59
+ subject.decoder = proc{ |v| v.to_i }
60
+
61
+ value = Factory.integer
62
+ assert_equal value.to_s, subject.encode(value)
63
+
64
+ value = Factory.integer.to_s
65
+ assert_equal value.to_i, subject.decode(value)
66
+ end
67
+
68
+ end
69
+
70
+ class MixedInSetupTests < UnitTests
71
+ setup do
72
+ @json_field_class = Class.new do
73
+ include MR::JsonField
74
+ attr_accessor :test_data_json, :custom_data_source
75
+ end
76
+ end
77
+
78
+ end
79
+
80
+ class MixedInTests < MixedInSetupTests
81
+ desc "when mixed in"
82
+ subject{ @json_field_class }
83
+
84
+ should have_imeths :json_field, :json_field_reader, :json_field_writer
85
+ should have_imeths :json_field_readers, :json_field_writers
86
+ should have_imeths :json_field_accessors, :json_field_source_fields
87
+
88
+ should "not have any json field accessors or source fields by default" do
89
+ assert_equal [], subject.json_field_readers
90
+ assert_equal [], subject.json_field_writers
91
+ assert_equal [], subject.json_field_accessors
92
+ assert_equal [], subject.json_field_source_fields
93
+ end
94
+
95
+ should "allow adding a json field reader" do
96
+ subject.json_field_reader 'test_data'
97
+ instance = subject.new
98
+
99
+ assert_respond_to 'test_data', instance
100
+ assert_equal ['test_data'], subject.json_field_readers
101
+ assert_equal ['test_data_json'], subject.json_field_source_fields
102
+ assert_equal [], subject.json_field_writers
103
+ assert_equal [], subject.json_field_accessors
104
+ end
105
+
106
+ should "allow adding a json field reader with a custom source" do
107
+ subject.json_field_reader 'custom_data', :source => 'custom_data_source'
108
+ instance = subject.new
109
+
110
+ assert_respond_to 'custom_data', instance
111
+ assert_equal ['custom_data'], subject.json_field_readers
112
+ assert_equal ['custom_data_source'], subject.json_field_source_fields
113
+ assert_equal [], subject.json_field_writers
114
+ assert_equal [], subject.json_field_accessors
115
+ end
116
+
117
+ should "allow adding a json field writer" do
118
+ subject.json_field_writer 'test_data'
119
+ instance = subject.new
120
+
121
+ assert_respond_to 'test_data=', instance
122
+ assert_equal ['test_data'], subject.json_field_writers
123
+ assert_equal ['test_data_json'], subject.json_field_source_fields
124
+ assert_equal [], subject.json_field_readers
125
+ assert_equal [], subject.json_field_accessors
126
+ end
127
+
128
+ should "allow adding a json field writer with a custom source" do
129
+ subject.json_field_writer 'custom_data', :source => 'custom_data_source'
130
+ instance = subject.new
131
+
132
+ assert_respond_to 'custom_data=', instance
133
+ assert_equal ['custom_data'], subject.json_field_writers
134
+ assert_equal ['custom_data_source'], subject.json_field_source_fields
135
+ assert_equal [], subject.json_field_readers
136
+ assert_equal [], subject.json_field_accessors
137
+ end
138
+
139
+ should "allow adding a json field accessor" do
140
+ subject.json_field 'test_data'
141
+ instance = subject.new
142
+
143
+ assert_respond_to 'test_data', instance
144
+ assert_respond_to 'test_data=', instance
145
+ exp = ['test_data']
146
+ assert_equal exp, subject.json_field_readers
147
+ assert_equal exp, subject.json_field_writers
148
+ assert_equal exp, subject.json_field_accessors
149
+ assert_equal ['test_data_json'], subject.json_field_source_fields
150
+ end
151
+
152
+ should "allow adding a json field accessor with a custom source" do
153
+ subject.json_field 'custom_data', :source => 'custom_data_source'
154
+ instance = subject.new
155
+
156
+ assert_respond_to 'custom_data', instance
157
+ assert_respond_to 'custom_data=', instance
158
+ exp = ['custom_data']
159
+ assert_equal exp, subject.json_field_readers
160
+ assert_equal exp, subject.json_field_writers
161
+ assert_equal exp, subject.json_field_accessors
162
+ assert_equal ['custom_data_source'], subject.json_field_source_fields
163
+ end
164
+
165
+ should "know it has an accessor if a reader and writer are added separately" do
166
+ subject.json_field_reader 'test_data'
167
+ subject.json_field_writer 'test_data'
168
+ instance = subject.new
169
+
170
+ assert_equal ['test_data'], subject.json_field_accessors
171
+ assert_equal ['test_data_json'], subject.json_field_source_fields
172
+ end
173
+
174
+ should "allow using symbols when adding json fields" do
175
+ subject.json_field :test_data
176
+ subject.json_field_reader :custom_data, :source => :custom_data_source
177
+ subject.json_field_writer :custom_data, :source => :custom_data_source
178
+ instance = subject.new
179
+
180
+ assert_respond_to :test_data, instance
181
+ assert_respond_to :test_data=, instance
182
+ assert_respond_to :custom_data, instance
183
+ assert_respond_to :custom_data=, instance
184
+ exp = ['test_data', 'custom_data']
185
+ assert_equal exp, subject.json_field_readers
186
+ assert_equal exp, subject.json_field_writers
187
+ assert_equal exp, subject.json_field_accessors
188
+ exp = ['test_data_json', 'custom_data_source']
189
+ assert_equal exp, subject.json_field_source_fields
190
+ end
191
+
192
+ should "error if the source matches the field name" do
193
+ name = Factory.string
194
+ assert_raises(ArgumentError) do
195
+ subject.json_field_reader(name, :source => name)
196
+ end
197
+ assert_raises(ArgumentError) do
198
+ subject.json_field_writer(name, :source => name)
199
+ end
200
+ assert_raises(ArgumentError) do
201
+ subject.json_field(name, :source => name)
202
+ end
203
+ end
204
+
205
+ end
206
+
207
+ class InitTests < MixedInTests
208
+ desc "and init"
209
+ setup do
210
+ @value = [
211
+ Factory.string,
212
+ Factory.integer,
213
+ Factory.boolean,
214
+ Factory.integer(3).times{ Factory.integer },
215
+ { Factory.string => Factory.string }
216
+ ].sample
217
+
218
+ @json_field_class.json_field :test_data
219
+ @json_field_class.json_field :custom_data, :source => :custom_data_source
220
+
221
+ @instance = @json_field_class.new
222
+ end
223
+ subject{ @instance }
224
+
225
+ should "allow reading/writing json fields" do
226
+ assert_nil subject.test_data
227
+ assert_nil subject.test_data_json
228
+ assert_nil subject.custom_data
229
+ assert_nil subject.custom_data_source
230
+
231
+ subject.test_data = @value
232
+ subject.custom_data = @value
233
+
234
+ exp = MR::JsonField.encode(@value)
235
+ assert_equal exp, subject.test_data_json
236
+ assert_equal exp, subject.custom_data_source
237
+ assert_equal @value, subject.test_data
238
+ assert_equal @value, subject.custom_data
239
+ end
240
+
241
+ should "cache read/written values" do
242
+ subject.test_data = @value
243
+ subject.custom_data = @value
244
+
245
+ result = subject.test_data
246
+ assert_same result, subject.test_data
247
+ result = subject.custom_data
248
+ assert_same result, subject.custom_data
249
+ end
250
+
251
+ should "allow reading/writing `nil` values" do
252
+ subject.test_data = @value
253
+ subject.custom_data = @value
254
+
255
+ assert_nothing_raised{ subject.test_data = nil }
256
+ assert_nil subject.test_data
257
+ assert_nothing_raised{ subject.custom_data = nil }
258
+ assert_nil subject.custom_data
259
+ end
260
+
261
+ should "raise an invalid json error when reading invalid JSON" do
262
+ subject.test_data_json = Factory.string
263
+ subject.custom_data_source = Factory.string
264
+
265
+ assert_raises(InvalidJSONError){ subject.test_data }
266
+ assert_raises(InvalidJSONError){ subject.custom_data }
267
+ end
268
+
269
+ should "raise an invalid json error when writing invalid JSON" do
270
+ Assert.stub(MR::JsonField.encoder, :call){ raise RuntimeError }
271
+
272
+ assert_raises(InvalidJSONError){ subject.test_data = Factory.string }
273
+ assert_raises(InvalidJSONError){ subject.custom_data = Factory.string }
274
+ end
275
+
276
+ end
277
+
278
+ class TestHelpersTests < MixedInSetupTests
279
+ include MR::JsonField::TestHelpers
280
+
281
+ desc "TestHelpers"
282
+ setup do
283
+ @json_field_class.json_field :test_data
284
+ @json_field_class.json_field :custom_data, :source => :custom_data_source
285
+
286
+ @instance = @json_field_class.new
287
+ end
288
+ subject{ @instance }
289
+
290
+ should "provide helpers for testing that a class has json fields" do
291
+ assert_json_field subject, :test_data
292
+ assert_json_field_reader subject, :test_data
293
+ assert_json_field_writer subject, :test_data
294
+
295
+ assert_json_field subject, :custom_data, :source => :custom_data_source
296
+ assert_json_field_reader subject, :custom_data, :source => :custom_data_source
297
+ assert_json_field_writer subject, :custom_data, :source => :custom_data_source
298
+ end
299
+
300
+ end
301
+
302
+ end