jat 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +21 -0
- data/jat.gemspec +37 -0
- data/lib/jat/attribute.rb +85 -0
- data/lib/jat/config.rb +38 -0
- data/lib/jat/plugins/_activerecord_preloads/_activerecord_preloads.rb +29 -0
- data/lib/jat/plugins/_activerecord_preloads/lib/preloader.rb +89 -0
- data/lib/jat/plugins/_json_api_activerecord/_json_api_activerecord.rb +22 -0
- data/lib/jat/plugins/_json_api_activerecord/lib/preloads.rb +84 -0
- data/lib/jat/plugins/_preloads/_preloads.rb +53 -0
- data/lib/jat/plugins/_preloads/lib/format_user_preloads.rb +52 -0
- data/lib/jat/plugins/_preloads/lib/preloads_with_path.rb +78 -0
- data/lib/jat/plugins/cache/cache.rb +39 -0
- data/lib/jat/plugins/camel_lower/camel_lower.rb +18 -0
- data/lib/jat/plugins/json_api/json_api.rb +207 -0
- data/lib/jat/plugins/json_api/lib/construct_traversal_map.rb +91 -0
- data/lib/jat/plugins/json_api/lib/map.rb +54 -0
- data/lib/jat/plugins/json_api/lib/params/fields/parse.rb +27 -0
- data/lib/jat/plugins/json_api/lib/params/fields/validate.rb +55 -0
- data/lib/jat/plugins/json_api/lib/params/fields.rb +23 -0
- data/lib/jat/plugins/json_api/lib/params/include/parse.rb +55 -0
- data/lib/jat/plugins/json_api/lib/params/include/validate.rb +29 -0
- data/lib/jat/plugins/json_api/lib/params/include.rb +49 -0
- data/lib/jat/plugins/json_api/lib/presenters/document_links_presenter.rb +48 -0
- data/lib/jat/plugins/json_api/lib/presenters/document_meta_presenter.rb +48 -0
- data/lib/jat/plugins/json_api/lib/presenters/jsonapi_presenter.rb +48 -0
- data/lib/jat/plugins/json_api/lib/presenters/links_presenter.rb +48 -0
- data/lib/jat/plugins/json_api/lib/presenters/meta_presenter.rb +48 -0
- data/lib/jat/plugins/json_api/lib/presenters/relationship_links_presenter.rb +53 -0
- data/lib/jat/plugins/json_api/lib/presenters/relationship_meta_presenter.rb +53 -0
- data/lib/jat/plugins/json_api/lib/response.rb +239 -0
- data/lib/jat/plugins/json_api/lib/traversal_map.rb +34 -0
- data/lib/jat/plugins/simple_api/lib/construct_traversal_map.rb +45 -0
- data/lib/jat/plugins/simple_api/lib/map.rb +29 -0
- data/lib/jat/plugins/simple_api/lib/params/parse.rb +68 -0
- data/lib/jat/plugins/simple_api/lib/response.rb +134 -0
- data/lib/jat/plugins/simple_api/simple_api.rb +65 -0
- data/lib/jat/plugins/to_str/to_str.rb +44 -0
- data/lib/jat/plugins.rb +39 -0
- data/lib/jat/presenter.rb +51 -0
- data/lib/jat/utils/enum_deep_dup.rb +29 -0
- data/lib/jat/utils/enum_deep_freeze.rb +19 -0
- data/lib/jat.rb +66 -144
- data/test/lib/jat/attribute_test.rb +142 -0
- data/test/lib/jat/config_test.rb +57 -0
- data/test/lib/jat/plugins/_activerecord_preloads/_activerecord_preloads_test.rb +40 -0
- data/test/lib/jat/plugins/_activerecord_preloads/lib/preloader_test.rb +98 -0
- data/test/lib/jat/plugins/_json_api_activerecord/_json_api_activerecord_test.rb +29 -0
- data/test/lib/jat/plugins/_json_api_activerecord/lib/preloads_test.rb +191 -0
- data/test/lib/jat/plugins/_preloads/_preloads_test.rb +68 -0
- data/test/lib/jat/plugins/_preloads/lib/format_user_preloads_test.rb +47 -0
- data/test/lib/jat/plugins/_preloads/lib/preloads_with_path_test.rb +33 -0
- data/test/lib/jat/plugins/cache/cache_test.rb +82 -0
- data/test/lib/jat/plugins/camel_lower/camel_lower_test.rb +78 -0
- data/test/lib/jat/plugins/json_api/json_api_test.rb +154 -0
- data/test/lib/jat/plugins/json_api/lib/construct_traversal_map_test.rb +119 -0
- data/test/lib/jat/plugins/json_api/lib/map_test.rb +117 -0
- data/test/lib/jat/plugins/json_api/lib/params/fields/parse_test.rb +24 -0
- data/test/lib/jat/plugins/json_api/lib/params/fields/validate_test.rb +47 -0
- data/test/lib/jat/plugins/json_api/lib/params/fields_test.rb +37 -0
- data/test/lib/jat/plugins/json_api/lib/params/include/parse_test.rb +46 -0
- data/test/lib/jat/plugins/json_api/lib/params/include/validate_test.rb +51 -0
- data/test/lib/jat/plugins/json_api/lib/params/include_test.rb +41 -0
- data/test/lib/jat/plugins/json_api/lib/presenters/document_links_presenter_test.rb +69 -0
- data/test/lib/jat/plugins/json_api/lib/presenters/document_meta_presenter_test.rb +69 -0
- data/test/lib/jat/plugins/json_api/lib/presenters/jsonapi_presenter_test.rb +69 -0
- data/test/lib/jat/plugins/json_api/lib/presenters/links_presenter_test.rb +69 -0
- data/test/lib/jat/plugins/json_api/lib/presenters/meta_presenter_test.rb +69 -0
- data/test/lib/jat/plugins/json_api/lib/presenters/relationship_links_presenter_test.rb +75 -0
- data/test/lib/jat/plugins/json_api/lib/presenters/relationship_meta_presenter_test.rb +75 -0
- data/test/lib/jat/plugins/json_api/lib/response_test.rb +489 -0
- data/test/lib/jat/plugins/json_api/lib/traversal_map_test.rb +58 -0
- data/test/lib/jat/plugins/simple_api/lib/construct_traversal_map_test.rb +100 -0
- data/test/lib/jat/plugins/simple_api/lib/map_test.rb +56 -0
- data/test/lib/jat/plugins/simple_api/lib/params/parse_test.rb +71 -0
- data/test/lib/jat/plugins/simple_api/lib/response_test.rb +342 -0
- data/test/lib/jat/plugins/simple_api/simple_api_test.rb +81 -0
- data/test/lib/jat/plugins/to_str/to_str_test.rb +52 -0
- data/test/lib/jat/presenter_test.rb +61 -0
- data/test/lib/jat/utils/enum_deep_dup_test.rb +31 -0
- data/test/lib/jat/utils/enum_deep_freeze_test.rb +28 -0
- data/test/lib/jat_test.rb +120 -0
- data/test/lib/plugin_test.rb +49 -0
- data/test/support/activerecord.rb +24 -0
- data/test/test_helper.rb +16 -0
- data/test/test_plugin.rb +59 -0
- 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
|