jat 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/README.md +21 -0
  4. data/jat.gemspec +37 -0
  5. data/lib/jat/attribute.rb +85 -0
  6. data/lib/jat/config.rb +38 -0
  7. data/lib/jat/plugins/_activerecord_preloads/_activerecord_preloads.rb +29 -0
  8. data/lib/jat/plugins/_activerecord_preloads/lib/preloader.rb +89 -0
  9. data/lib/jat/plugins/_json_api_activerecord/_json_api_activerecord.rb +22 -0
  10. data/lib/jat/plugins/_json_api_activerecord/lib/preloads.rb +84 -0
  11. data/lib/jat/plugins/_preloads/_preloads.rb +53 -0
  12. data/lib/jat/plugins/_preloads/lib/format_user_preloads.rb +52 -0
  13. data/lib/jat/plugins/_preloads/lib/preloads_with_path.rb +78 -0
  14. data/lib/jat/plugins/cache/cache.rb +39 -0
  15. data/lib/jat/plugins/camel_lower/camel_lower.rb +18 -0
  16. data/lib/jat/plugins/json_api/json_api.rb +207 -0
  17. data/lib/jat/plugins/json_api/lib/construct_traversal_map.rb +91 -0
  18. data/lib/jat/plugins/json_api/lib/map.rb +54 -0
  19. data/lib/jat/plugins/json_api/lib/params/fields/parse.rb +27 -0
  20. data/lib/jat/plugins/json_api/lib/params/fields/validate.rb +55 -0
  21. data/lib/jat/plugins/json_api/lib/params/fields.rb +23 -0
  22. data/lib/jat/plugins/json_api/lib/params/include/parse.rb +55 -0
  23. data/lib/jat/plugins/json_api/lib/params/include/validate.rb +29 -0
  24. data/lib/jat/plugins/json_api/lib/params/include.rb +49 -0
  25. data/lib/jat/plugins/json_api/lib/presenters/document_links_presenter.rb +48 -0
  26. data/lib/jat/plugins/json_api/lib/presenters/document_meta_presenter.rb +48 -0
  27. data/lib/jat/plugins/json_api/lib/presenters/jsonapi_presenter.rb +48 -0
  28. data/lib/jat/plugins/json_api/lib/presenters/links_presenter.rb +48 -0
  29. data/lib/jat/plugins/json_api/lib/presenters/meta_presenter.rb +48 -0
  30. data/lib/jat/plugins/json_api/lib/presenters/relationship_links_presenter.rb +53 -0
  31. data/lib/jat/plugins/json_api/lib/presenters/relationship_meta_presenter.rb +53 -0
  32. data/lib/jat/plugins/json_api/lib/response.rb +239 -0
  33. data/lib/jat/plugins/json_api/lib/traversal_map.rb +34 -0
  34. data/lib/jat/plugins/simple_api/lib/construct_traversal_map.rb +45 -0
  35. data/lib/jat/plugins/simple_api/lib/map.rb +29 -0
  36. data/lib/jat/plugins/simple_api/lib/params/parse.rb +68 -0
  37. data/lib/jat/plugins/simple_api/lib/response.rb +134 -0
  38. data/lib/jat/plugins/simple_api/simple_api.rb +65 -0
  39. data/lib/jat/plugins/to_str/to_str.rb +44 -0
  40. data/lib/jat/plugins.rb +39 -0
  41. data/lib/jat/presenter.rb +51 -0
  42. data/lib/jat/utils/enum_deep_dup.rb +29 -0
  43. data/lib/jat/utils/enum_deep_freeze.rb +19 -0
  44. data/lib/jat.rb +66 -144
  45. data/test/lib/jat/attribute_test.rb +142 -0
  46. data/test/lib/jat/config_test.rb +57 -0
  47. data/test/lib/jat/plugins/_activerecord_preloads/_activerecord_preloads_test.rb +40 -0
  48. data/test/lib/jat/plugins/_activerecord_preloads/lib/preloader_test.rb +98 -0
  49. data/test/lib/jat/plugins/_json_api_activerecord/_json_api_activerecord_test.rb +29 -0
  50. data/test/lib/jat/plugins/_json_api_activerecord/lib/preloads_test.rb +191 -0
  51. data/test/lib/jat/plugins/_preloads/_preloads_test.rb +68 -0
  52. data/test/lib/jat/plugins/_preloads/lib/format_user_preloads_test.rb +47 -0
  53. data/test/lib/jat/plugins/_preloads/lib/preloads_with_path_test.rb +33 -0
  54. data/test/lib/jat/plugins/cache/cache_test.rb +82 -0
  55. data/test/lib/jat/plugins/camel_lower/camel_lower_test.rb +78 -0
  56. data/test/lib/jat/plugins/json_api/json_api_test.rb +154 -0
  57. data/test/lib/jat/plugins/json_api/lib/construct_traversal_map_test.rb +119 -0
  58. data/test/lib/jat/plugins/json_api/lib/map_test.rb +117 -0
  59. data/test/lib/jat/plugins/json_api/lib/params/fields/parse_test.rb +24 -0
  60. data/test/lib/jat/plugins/json_api/lib/params/fields/validate_test.rb +47 -0
  61. data/test/lib/jat/plugins/json_api/lib/params/fields_test.rb +37 -0
  62. data/test/lib/jat/plugins/json_api/lib/params/include/parse_test.rb +46 -0
  63. data/test/lib/jat/plugins/json_api/lib/params/include/validate_test.rb +51 -0
  64. data/test/lib/jat/plugins/json_api/lib/params/include_test.rb +41 -0
  65. data/test/lib/jat/plugins/json_api/lib/presenters/document_links_presenter_test.rb +69 -0
  66. data/test/lib/jat/plugins/json_api/lib/presenters/document_meta_presenter_test.rb +69 -0
  67. data/test/lib/jat/plugins/json_api/lib/presenters/jsonapi_presenter_test.rb +69 -0
  68. data/test/lib/jat/plugins/json_api/lib/presenters/links_presenter_test.rb +69 -0
  69. data/test/lib/jat/plugins/json_api/lib/presenters/meta_presenter_test.rb +69 -0
  70. data/test/lib/jat/plugins/json_api/lib/presenters/relationship_links_presenter_test.rb +75 -0
  71. data/test/lib/jat/plugins/json_api/lib/presenters/relationship_meta_presenter_test.rb +75 -0
  72. data/test/lib/jat/plugins/json_api/lib/response_test.rb +489 -0
  73. data/test/lib/jat/plugins/json_api/lib/traversal_map_test.rb +58 -0
  74. data/test/lib/jat/plugins/simple_api/lib/construct_traversal_map_test.rb +100 -0
  75. data/test/lib/jat/plugins/simple_api/lib/map_test.rb +56 -0
  76. data/test/lib/jat/plugins/simple_api/lib/params/parse_test.rb +71 -0
  77. data/test/lib/jat/plugins/simple_api/lib/response_test.rb +342 -0
  78. data/test/lib/jat/plugins/simple_api/simple_api_test.rb +81 -0
  79. data/test/lib/jat/plugins/to_str/to_str_test.rb +52 -0
  80. data/test/lib/jat/presenter_test.rb +61 -0
  81. data/test/lib/jat/utils/enum_deep_dup_test.rb +31 -0
  82. data/test/lib/jat/utils/enum_deep_freeze_test.rb +28 -0
  83. data/test/lib/jat_test.rb +120 -0
  84. data/test/lib/plugin_test.rb +49 -0
  85. data/test/support/activerecord.rb +24 -0
  86. data/test/test_helper.rb +16 -0
  87. data/test/test_plugin.rb +59 -0
  88. metadata +240 -11
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ describe "Jat::Plugins::SimpleApi::Params::Parse" do
6
+ before do
7
+ Jat::Plugins.load_plugin :simple_api
8
+ end
9
+
10
+ def parse(str)
11
+ Jat::Plugins::SimpleApi::Params::Parse.new(str).parse
12
+ end
13
+
14
+ it "returns empty hash when nil provided" do
15
+ assert_equal({}, parse(nil))
16
+ end
17
+
18
+ it "returns empty hash when empty string provided" do
19
+ assert_equal({}, parse(""))
20
+ end
21
+
22
+ it "parses single field" do
23
+ assert_equal({id: {}}, parse("id"))
24
+ end
25
+
26
+ it "parses multiple fields" do
27
+ assert_equal({id: {}, name: {}}, parse("id,name"))
28
+ end
29
+
30
+ it "parses single resource with single field" do
31
+ assert_equal({users: {id: {}}}, parse("users(id)"))
32
+ end
33
+
34
+ it "parses fields started with open PAREN" do
35
+ assert_equal({users: {id: {}}}, parse("(users(id))"))
36
+ end
37
+
38
+ it "parses single resource with multiple fields" do
39
+ assert_equal({users: {id: {}, name: {}}}, parse("users(id,name)"))
40
+ end
41
+
42
+ it "parses multiple resources with fields" do
43
+ fields = "id,posts(title,text),news(title,text)"
44
+ resp = {
45
+ id: {},
46
+ posts: {title: {}, text: {}},
47
+ news: {title: {}, text: {}}
48
+ }
49
+
50
+ assert_equal(resp, parse(fields))
51
+ end
52
+
53
+ it "parses included resources" do
54
+ fields = "id,posts(title,text,comments(author(name),comment))"
55
+ resp = {
56
+ id: {},
57
+ posts: {
58
+ title: {},
59
+ text: {},
60
+ comments: {
61
+ author: {
62
+ name: {}
63
+ },
64
+ comment: {}
65
+ }
66
+ }
67
+ }
68
+
69
+ assert_equal(resp, parse(fields))
70
+ end
71
+ end
@@ -0,0 +1,342 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ describe "Jat::Plugins::SimpleApi::Response" do
6
+ let(:base_class) { Class.new(Jat) { plugin :simple_api } }
7
+
8
+ it "returns empty hash when nothing to serialize" do
9
+ empty_serializer = Class.new(base_class)
10
+
11
+ assert_equal({}, empty_serializer.to_h(nil))
12
+ end
13
+
14
+ it "returns correct structure with meta" do
15
+ empty_serializer = Class.new(base_class)
16
+
17
+ assert_equal({meta: {any: :thing}}, empty_serializer.to_h(nil, meta: {any: :thing}))
18
+ end
19
+
20
+ it "returns correct structure with data" do
21
+ str_serializer = Class.new(base_class) do
22
+ attribute(:id) { |_| "STRING" }
23
+ end
24
+
25
+ assert_equal({id: "STRING"}, str_serializer.to_h("STRING"))
26
+ end
27
+
28
+ it "returns correct structure when parameter `many` defined manually" do
29
+ str_serializer = Class.new(base_class) do
30
+ attribute(:id) { |obj| obj[:foo] }
31
+ end
32
+
33
+ # By default hash is interpreted as `many: true` as it is Enumerable
34
+ obj = {foo: :bar}
35
+ context = {many: false}
36
+
37
+ assert_equal({id: :bar}, str_serializer.to_h(obj, context))
38
+ end
39
+
40
+ it "returns correct structure with array data" do
41
+ str_serializer = Class.new(base_class) do
42
+ attribute(:id) { |obj| obj }
43
+ end
44
+
45
+ assert_equal(
46
+ [{id: "1"}, {id: "2"}],
47
+ str_serializer.to_h(%w[1 2])
48
+ )
49
+ end
50
+
51
+ it "raises error when trying to add meta to response without root key" do
52
+ str_serializer = Class.new(base_class) do
53
+ attribute(:id) { |obj| obj }
54
+ end
55
+
56
+ error = assert_raises(Jat::Error) { str_serializer.to_h("1", meta: {foo: :bar}) }
57
+ assert_equal "Response must have a root key to add metadata", error.message
58
+
59
+ error = assert_raises(Jat::Error) { str_serializer.to_h(["1"], meta: {foo: :bar}) }
60
+ assert_equal "Response must have a root key to add metadata", error.message
61
+ end
62
+
63
+ it "returns correct structure with array data" do
64
+ str_serializer = Class.new(base_class) do
65
+ attribute(:id) { |obj| obj }
66
+ end
67
+
68
+ assert_equal(
69
+ [{id: "1"}, {id: "2"}],
70
+ str_serializer.to_h(%w[1 2])
71
+ )
72
+ end
73
+
74
+ it "returns correct structure with one object with root key" do
75
+ str_serializer = Class.new(base_class) do
76
+ root(:digit)
77
+ attribute(:id) { |obj| obj }
78
+ end
79
+
80
+ assert_equal({digit: {id: "1"}}, str_serializer.to_h("1"))
81
+ end
82
+
83
+ it "returns correct structure with list with root key" do
84
+ str_serializer = Class.new(base_class) do
85
+ root(:digits)
86
+ attribute(:id) { |obj| obj }
87
+ end
88
+
89
+ assert_equal(
90
+ {digits: [{id: "1"}, {id: "2"}]},
91
+ str_serializer.to_h(%w[1 2])
92
+ )
93
+ end
94
+
95
+ it "returns correct structures root_for_one and root_for_many keys" do
96
+ str_serializer = Class.new(base_class) do
97
+ root(:not_used)
98
+ root_for_one(:digit)
99
+ root_for_many(:digits)
100
+ attribute(:id) { |obj| obj }
101
+ end
102
+
103
+ assert_equal({digit: {id: "1"}}, str_serializer.to_h("1"))
104
+ assert_equal({digits: [{id: "1"}]}, str_serializer.to_h(["1"]))
105
+ end
106
+
107
+ it "returns correct structures when root is overwritten" do
108
+ str_serializer = Class.new(base_class) do
109
+ root(:root)
110
+ root_for_one(:root)
111
+ root_for_many(:root)
112
+ attribute(:id) { |obj| obj }
113
+ end
114
+
115
+ assert_equal({foo: {id: "1"}}, str_serializer.to_h("1", root: :foo))
116
+ assert_equal({foo: [{id: "1"}]}, str_serializer.to_h(["1"], root: :foo))
117
+ end
118
+
119
+ it "returns correct structure with data and meta" do
120
+ str_serializer = Class.new(base_class) do
121
+ root(:root)
122
+ config[:meta] = {version: "1.2.3"}
123
+
124
+ attribute(:id) { |obj| obj }
125
+ end
126
+
127
+ assert_equal(
128
+ {root: {id: "1"}, meta: {any: :thing, version: "1.2.3"}},
129
+ str_serializer.to_h("1", meta: {any: :thing})
130
+ )
131
+
132
+ assert_equal(
133
+ {root: [{id: "1"}], meta: {any: :thing, version: "1.2.3"}},
134
+ str_serializer.to_h(["1"], meta: {any: :thing})
135
+ )
136
+ end
137
+
138
+ it "returns correct structure with data multiple attributes" do
139
+ str_serializer = Class.new(base_class) do
140
+ attribute(:id) { |obj| obj }
141
+ attribute :length
142
+ end
143
+
144
+ assert_equal({id: "1", length: 1}, str_serializer.to_h("1"))
145
+ end
146
+
147
+ it "returns correct structure with has-one relationship" do
148
+ int_serializer = Class.new(base_class) do
149
+ attribute(:id) { |obj| obj }
150
+ end
151
+
152
+ str_serializer = Class.new(base_class) do
153
+ attribute(:id) { |obj| obj[0] }
154
+ attribute :length, serializer: int_serializer, exposed: true
155
+ end
156
+
157
+ assert_equal({id: "S", length: {id: 6}}, str_serializer.to_h("STRING"))
158
+ end
159
+
160
+ it "returns correct structure when children serializer defined as lambda" do
161
+ int_serializer = Class.new(base_class) do
162
+ attribute(:id) { |obj| obj }
163
+ end
164
+
165
+ str_serializer = Class.new(base_class) do
166
+ attribute(:id) { |obj| obj[0] }
167
+ attribute :length, serializer: -> { int_serializer }, exposed: true
168
+ end
169
+
170
+ assert_equal({id: "S", length: {id: 6}}, str_serializer.to_h("STRING"))
171
+ end
172
+
173
+ it "does not return has-one relationship when not exposed" do
174
+ int_serializer = Class.new(base_class) do
175
+ attribute(:id) { |obj| obj }
176
+ end
177
+
178
+ str_serializer = Class.new(base_class) do
179
+ attribute(:id) { |obj| obj[0] }
180
+ attribute :length, serializer: int_serializer, exposed: false
181
+ end
182
+
183
+ assert_equal({id: "S"}, str_serializer.to_h("STRING"))
184
+ end
185
+
186
+ it "returns nil as empty has-one relationship" do
187
+ int_serializer = Class.new(base_class)
188
+
189
+ str_serializer = Class.new(base_class) do
190
+ attribute(:id) { |obj| obj[0] }
191
+ attribute(:length, serializer: int_serializer, exposed: true) { |_obj| nil }
192
+ end
193
+
194
+ assert_equal(
195
+ {id: "S", length: nil},
196
+ str_serializer.to_h("STRING")
197
+ )
198
+ end
199
+
200
+ it "returns correct structure with has-one relationship with attributes" do
201
+ int_serializer = Class.new(base_class) do
202
+ attribute(:id) { |obj| obj }
203
+ attribute(:next) { |obj| obj + 1 }
204
+ end
205
+
206
+ str_serializer = Class.new(base_class) do
207
+ attribute(:id) { |obj| obj[0] }
208
+ attribute :length, serializer: int_serializer, exposed: true
209
+ end
210
+
211
+ assert_equal(
212
+ {id: "S", length: {id: 6, next: 7}},
213
+ str_serializer.to_h("STRING")
214
+ )
215
+ end
216
+
217
+ it "returns empty array as empty has-many relationship" do
218
+ chr_serializer = Class.new(base_class)
219
+ str_serializer = Class.new(base_class) do
220
+ attribute(:id) { |_obj| "id" }
221
+ attribute :chars, serializer: chr_serializer, many: true, exposed: true
222
+ end
223
+
224
+ assert_equal({id: "id", chars: []}, str_serializer.to_h(""))
225
+ end
226
+
227
+ it "returns correct structure with has-many relationship" do
228
+ chr_serializer = Class.new(base_class) do
229
+ attribute(:id) { |obj| obj }
230
+ end
231
+
232
+ str_serializer = Class.new(base_class) do
233
+ attribute(:id) { |obj| obj[0] }
234
+ attribute :chars, serializer: chr_serializer, many: true, exposed: true
235
+ end
236
+
237
+ assert_equal(
238
+ {id: "a", chars: [{id: "a"}, {id: "b"}]},
239
+ str_serializer.to_h("ab")
240
+ )
241
+ end
242
+
243
+ it "automatically checks if nested relationship is enumerable or single object" do
244
+ chr_serializer = Class.new(base_class) do
245
+ attribute(:id) { |obj| obj }
246
+ end
247
+
248
+ int_serializer = Class.new(base_class) do
249
+ attribute(:id) { |obj| obj }
250
+ end
251
+
252
+ str_serializer = Class.new(base_class) do
253
+ attribute(:id) { |obj| obj[0] }
254
+ attribute :chars, serializer: chr_serializer, exposed: true, many: true
255
+ attribute :length, serializer: int_serializer, exposed: true, many: false
256
+ end
257
+
258
+ assert_equal(
259
+ {id: "a", chars: [{id: "a"}, {id: "b"}], length: {id: 2}},
260
+ str_serializer.to_h("ab")
261
+ )
262
+ end
263
+
264
+ it "returns correct structure with has-many relationship with attributes" do
265
+ chr_serializer = Class.new(base_class) do
266
+ attribute(:id) { |obj| obj }
267
+ attribute :next
268
+ end
269
+
270
+ str_serializer = Class.new(base_class) do
271
+ attribute(:id) { |obj| obj[0] }
272
+ attribute :chars, serializer: chr_serializer, many: true, exposed: true
273
+ end
274
+
275
+ assert_equal(
276
+ {id: "a", chars: [{id: "a", next: "b"}, {id: "b", next: "c"}]},
277
+ str_serializer.to_h("ab")
278
+ )
279
+ end
280
+
281
+ it "accepts fields" do
282
+ # All fields are not exposed in this serializers,
283
+ # We will show only attributes provided in `fields` param
284
+ chr_serializer = Class.new(base_class) do
285
+ attribute(:id, exposed: false) { |obj| obj }
286
+ attribute :next, exposed: false
287
+ end
288
+
289
+ str_serializer = Class.new(base_class) do
290
+ attribute(:id, exposed: false) { |obj| obj }
291
+ attribute :chars, serializer: chr_serializer, many: true, exposed: false
292
+ end
293
+
294
+ assert_equal(
295
+ {chars: [{next: "b"}, {next: "c"}]},
296
+ str_serializer.to_h("ab", params: {fields: "chars(next)"})
297
+ )
298
+ end
299
+
300
+ it "does not overwrite manually added meta" do
301
+ str_serializer = Class.new(base_class) do
302
+ root(:root)
303
+ config[:meta] = {version: "1.2.3"}
304
+
305
+ attribute(:id) { |obj| obj }
306
+ end
307
+
308
+ assert_equal(
309
+ {root: {id: "1"}, meta: {version: "2.0.0"}},
310
+ str_serializer.to_h("1", meta: {version: "2.0.0"})
311
+ )
312
+ end
313
+
314
+ it "allows to provide lambda as meta key" do
315
+ str_serializer = Class.new(base_class) do
316
+ root(:root)
317
+ config[:meta] = {
318
+ obj: ->(obj, _context) { obj },
319
+ context: ->(_obj, context) { context },
320
+ time: ->(_obj, _context) { Time.new(2020, 1, 1) }
321
+ }
322
+
323
+ attribute(:id) { |obj| obj }
324
+ end
325
+
326
+ assert_equal(
327
+ {root: {id: "1"}, meta: {obj: "1", context: {foo: :bar}, time: Time.new(2020, 1, 1)}},
328
+ str_serializer.to_h("1", foo: :bar)
329
+ )
330
+ end
331
+
332
+ it "does not adds nil meta" do
333
+ str_serializer = Class.new(base_class) do
334
+ root(:root)
335
+ config[:meta] = {foo: nil, bar: proc {}}
336
+
337
+ attribute(:id) { |obj| obj }
338
+ end
339
+
340
+ assert_equal({root: {id: "1"}}, str_serializer.to_h("1", bazz: nil))
341
+ end
342
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ describe "Jat::Plugins::SimpleApi" do
6
+ before { @plugin = Jat::Plugins.load_plugin(:simple_api) }
7
+
8
+ let(:jat_class) do
9
+ new_class = Class.new(Jat)
10
+ new_class.plugin(plugin)
11
+ new_class.root :data
12
+ new_class.attribute :id, key: :itself
13
+ new_class
14
+ end
15
+
16
+ let(:plugin) { @plugin }
17
+
18
+ describe ".after_load" do
19
+ it "loads _json_api_activerecord plugin if activerecord option provided" do
20
+ jat_class = Class.new(Jat)
21
+ jat_class.expects(:plugin).with(:_json_api_activerecord, activerecord: true)
22
+
23
+ Jat::Plugins.after_load(plugin, jat_class, activerecord: true)
24
+ end
25
+ end
26
+
27
+ describe "InstanceMethods" do
28
+ let(:jat) { jat_class.new("JAT", {}) }
29
+
30
+ describe "#to_h" do
31
+ it "returns response in a simple-api format" do
32
+ expected_result = {data: {id: "JAT"}}
33
+ assert_equal expected_result, jat.to_h
34
+ end
35
+ end
36
+
37
+ describe "#traversal_map" do
38
+ it "returns memorized traversal_map hash" do
39
+ assert_equal jat.traversal_map.class, Hash
40
+ assert_same jat.traversal_map, jat.traversal_map
41
+ end
42
+ end
43
+ end
44
+
45
+ describe "ClassMethods" do
46
+ describe ".inherited" do
47
+ it "inherits root" do
48
+ child = Class.new(jat_class)
49
+ assert_equal :data, child.root
50
+ end
51
+ end
52
+
53
+ describe ".root" do
54
+ it "saves and returns current root" do
55
+ assert_equal :data, jat_class.root
56
+ end
57
+
58
+ it "symbolizes root" do
59
+ jat_class.root "users"
60
+ assert_equal :users, jat_class.root
61
+ end
62
+ end
63
+
64
+ describe ".meta_key" do
65
+ it "returns default meta_key" do
66
+ assert_equal :meta, jat_class.meta_key
67
+ end
68
+
69
+ it "saves and returns meta key" do
70
+ jat_class.meta_key :metadata
71
+ assert_equal :metadata, jat_class.meta_key
72
+ assert_same jat_class.meta_key, jat_class.meta_key
73
+ end
74
+
75
+ it "symbolizes meta key" do
76
+ jat_class.meta_key "metadata"
77
+ assert_equal :metadata, jat_class.meta_key
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ describe "Jat::Plugins::ToStr" do
6
+ let(:jat_class) do
7
+ new_class = Class.new(Jat)
8
+ new_class.plugin(:to_str)
9
+ new_class.class_exec do
10
+ def to_h
11
+ {object => context}
12
+ end
13
+ end
14
+
15
+ new_class
16
+ end
17
+
18
+ describe "Jat" do
19
+ describe ".to_str" do
20
+ it "returns json string of to_h" do
21
+ assert_equal '{"obj":"ctx"}', jat_class.to_str("obj", "ctx")
22
+ end
23
+
24
+ it "returns json string of to_h with default empty hash context" do
25
+ assert_equal '{"obj":{}}', jat_class.to_str("obj")
26
+ end
27
+
28
+ it "returns result serialized with given in config serializer" do
29
+ jat_class.config[:to_str] = ->(data) { data.inspect }
30
+ assert_equal '{"obj"=>"ctx"}', jat_class.to_str("obj", "ctx")
31
+ end
32
+
33
+ it "accepts to_str config option when loading plugin" do
34
+ new_class = Class.new(Jat)
35
+ new_class.plugin(:to_str, to_str: ->(data) { data.inspect })
36
+ new_class.class_exec do
37
+ def to_h
38
+ {object => context}
39
+ end
40
+ end
41
+
42
+ assert_equal '{"obj"=>"ctx"}', new_class.to_str("obj", "ctx")
43
+ end
44
+ end
45
+
46
+ describe "#to_str" do
47
+ it "returns json string of to_h" do
48
+ assert_equal '{"obj":"ctx"}', jat_class.new("obj", "ctx").to_str
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ describe Jat::Presenter do
6
+ let(:jat_class) { Class.new(Jat) }
7
+ let(:presenter_class) { jat_class::Presenter }
8
+
9
+ describe ".jat_class=" do
10
+ it "assigns @jat_class" do
11
+ presenter_class.jat_class = :foo
12
+ assert_equal :foo, presenter_class.instance_variable_get(:@jat_class)
13
+ end
14
+ end
15
+
16
+ describe ".jat_class" do
17
+ it "returns self @jat_class" do
18
+ assert_same jat_class, presenter_class.instance_variable_get(:@jat_class)
19
+ assert_same jat_class, presenter_class.jat_class
20
+ end
21
+ end
22
+
23
+ describe ".inspect" do
24
+ it "returns self name" do
25
+ assert_equal "#{jat_class}::Presenter", presenter_class.inspect
26
+ end
27
+ end
28
+
29
+ describe ".add_method" do
30
+ let(:presenter) { presenter_class.new("OBJECT", "CONTEXT") }
31
+
32
+ it "adds method by providing block without variables" do
33
+ presenter_class.add_method(:foo, proc { [object, context] })
34
+ assert_equal %w[OBJECT CONTEXT], presenter.foo
35
+ end
36
+
37
+ it "adds method by providing block with one variables" do
38
+ presenter_class.add_method(:foo, proc { |obj| [obj, object, context] })
39
+ assert_equal %w[OBJECT OBJECT CONTEXT], presenter.foo
40
+ end
41
+
42
+ it "adds method by providing block with two variables" do
43
+ presenter_class.add_method(:foo, proc { |obj, ctx| [obj, ctx, object, context] })
44
+ assert_equal %w[OBJECT CONTEXT OBJECT CONTEXT], presenter.foo
45
+ end
46
+
47
+ it "raises error when block has more than two variables" do
48
+ error = assert_raises(Jat::Error) { presenter_class.add_method(:foo, proc { |_a, _b, _c| }) }
49
+ assert_equal "Invalid block arguments count", error.message
50
+ end
51
+ end
52
+
53
+ describe "#initialize" do
54
+ it "initializes object presenter with provided object and context" do
55
+ presenter = presenter_class.new("OBJ", "CTX")
56
+
57
+ assert_equal "OBJ", presenter.object
58
+ assert_equal "CTX", presenter.context
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ describe Jat::EnumDeepDup do
6
+ describe ".call" do
7
+ it "makes deep dup of hash" do
8
+ hash = {key1: {key11: {key111: :value111}}, key2: [{key22: {key222: :value222}}]}
9
+ dup = Jat::EnumDeepDup.call(hash)
10
+
11
+ assert_equal hash, dup
12
+
13
+ refute_same hash, dup
14
+ refute_same hash[:key1], dup[:key1]
15
+ refute_same hash[:key1][:key11], dup[:key1][:key11]
16
+
17
+ refute_same hash[:key2], dup[:key2]
18
+ refute_same hash[:key2][0], dup[:key2][0]
19
+ refute_same hash[:key2][0][:key22], dup[:key2][0][:key22]
20
+ end
21
+
22
+ it "does not duplicates non-enumerable objects" do
23
+ hash = {key1: Jat, key2: [-> {}]}
24
+ dup = Jat::EnumDeepDup.call(hash)
25
+
26
+ assert_equal hash, dup
27
+ assert_same hash[:key1], dup[:key1]
28
+ assert_same hash[:key2][0], dup[:key2][0]
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ describe Jat::EnumDeepFreeze do
6
+ describe ".call" do
7
+ it "deeply freezes provided hash" do
8
+ hash = {key1: {key11: {key111: :value111}}, key2: [{key22: {key222: :value222}}]}
9
+ Jat::EnumDeepFreeze.call(hash)
10
+
11
+ assert hash.frozen?
12
+ assert hash[:key1].frozen?
13
+ assert hash[:key1][:key11].frozen?
14
+
15
+ assert hash[:key2].frozen?
16
+ assert hash[:key2][0].frozen?
17
+ assert hash[:key2][0][:key22].frozen?
18
+ end
19
+
20
+ it "does not freezes non-enumerable objects" do
21
+ hash = {key1: Jat, key2: [-> {}]}
22
+ Jat::EnumDeepFreeze.call(hash)
23
+
24
+ refute hash[:key1].frozen?
25
+ refute hash[:key2][0].frozen?
26
+ end
27
+ end
28
+ end