restorm 1.0.0

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 (76) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +31 -0
  5. data/.rubocop_todo.yml +232 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +55 -0
  8. data/.yardopts +2 -0
  9. data/CONTRIBUTING.md +26 -0
  10. data/Gemfile +10 -0
  11. data/HER_README.md +1065 -0
  12. data/LICENSE +7 -0
  13. data/README.md +7 -0
  14. data/Rakefile +11 -0
  15. data/UPGRADE.md +101 -0
  16. data/gemfiles/Gemfile.activemodel-4.2 +6 -0
  17. data/gemfiles/Gemfile.activemodel-5.0 +6 -0
  18. data/gemfiles/Gemfile.activemodel-5.1 +6 -0
  19. data/gemfiles/Gemfile.activemodel-5.2 +6 -0
  20. data/gemfiles/Gemfile.faraday-1.0 +6 -0
  21. data/lib/restorm/api.rb +121 -0
  22. data/lib/restorm/collection.rb +13 -0
  23. data/lib/restorm/errors.rb +29 -0
  24. data/lib/restorm/json_api/model.rb +42 -0
  25. data/lib/restorm/middleware/accept_json.rb +18 -0
  26. data/lib/restorm/middleware/first_level_parse_json.rb +37 -0
  27. data/lib/restorm/middleware/json_api_parser.rb +37 -0
  28. data/lib/restorm/middleware/parse_json.rb +22 -0
  29. data/lib/restorm/middleware/second_level_parse_json.rb +37 -0
  30. data/lib/restorm/middleware.rb +12 -0
  31. data/lib/restorm/model/associations/association.rb +128 -0
  32. data/lib/restorm/model/associations/association_proxy.rb +44 -0
  33. data/lib/restorm/model/associations/belongs_to_association.rb +95 -0
  34. data/lib/restorm/model/associations/has_many_association.rb +100 -0
  35. data/lib/restorm/model/associations/has_one_association.rb +79 -0
  36. data/lib/restorm/model/associations.rb +141 -0
  37. data/lib/restorm/model/attributes.rb +322 -0
  38. data/lib/restorm/model/base.rb +33 -0
  39. data/lib/restorm/model/deprecated_methods.rb +61 -0
  40. data/lib/restorm/model/http.rb +119 -0
  41. data/lib/restorm/model/introspection.rb +67 -0
  42. data/lib/restorm/model/nested_attributes.rb +45 -0
  43. data/lib/restorm/model/orm.rb +299 -0
  44. data/lib/restorm/model/parse.rb +223 -0
  45. data/lib/restorm/model/paths.rb +125 -0
  46. data/lib/restorm/model/relation.rb +209 -0
  47. data/lib/restorm/model.rb +75 -0
  48. data/lib/restorm/version.rb +3 -0
  49. data/lib/restorm.rb +19 -0
  50. data/restorm.gemspec +29 -0
  51. data/spec/api_spec.rb +120 -0
  52. data/spec/collection_spec.rb +41 -0
  53. data/spec/json_api/model_spec.rb +169 -0
  54. data/spec/middleware/accept_json_spec.rb +11 -0
  55. data/spec/middleware/first_level_parse_json_spec.rb +63 -0
  56. data/spec/middleware/json_api_parser_spec.rb +52 -0
  57. data/spec/middleware/second_level_parse_json_spec.rb +35 -0
  58. data/spec/model/associations/association_proxy_spec.rb +29 -0
  59. data/spec/model/associations_spec.rb +911 -0
  60. data/spec/model/attributes_spec.rb +354 -0
  61. data/spec/model/callbacks_spec.rb +176 -0
  62. data/spec/model/dirty_spec.rb +133 -0
  63. data/spec/model/http_spec.rb +201 -0
  64. data/spec/model/introspection_spec.rb +81 -0
  65. data/spec/model/nested_attributes_spec.rb +135 -0
  66. data/spec/model/orm_spec.rb +704 -0
  67. data/spec/model/parse_spec.rb +520 -0
  68. data/spec/model/paths_spec.rb +348 -0
  69. data/spec/model/relation_spec.rb +247 -0
  70. data/spec/model/validations_spec.rb +43 -0
  71. data/spec/model_spec.rb +45 -0
  72. data/spec/spec_helper.rb +25 -0
  73. data/spec/support/macros/her_macros.rb +17 -0
  74. data/spec/support/macros/model_macros.rb +36 -0
  75. data/spec/support/macros/request_macros.rb +27 -0
  76. metadata +203 -0
@@ -0,0 +1,520 @@
1
+ # encoding: utf-8
2
+
3
+ require File.join(File.dirname(__FILE__), "../spec_helper.rb")
4
+
5
+ describe Restorm::Model::Parse do
6
+ context "when include_root_in_json is set" do
7
+ before do
8
+ Restorm::API.setup url: "https://api.example.com" do |builder|
9
+ builder.use Restorm::Middleware::FirstLevelParseJSON
10
+ builder.use Faraday::Request::UrlEncoded
11
+ end
12
+
13
+ Restorm::API.default_api.connection.adapter :test do |stub|
14
+ stub.post("/users") { |env| [200, {}, { user: { id: 1, fullname: params(env)[:user][:fullname] } }.to_json] }
15
+ stub.post("/users/admins") { |env| [200, {}, { user: { id: 1, fullname: params(env)[:user][:fullname] } }.to_json] }
16
+ end
17
+ end
18
+
19
+ context "to true" do
20
+ before do
21
+ spawn_model "Foo::User" do
22
+ include_root_in_json true
23
+ parse_root_in_json true
24
+ custom_post :admins
25
+ end
26
+ end
27
+
28
+ it "inherits attributes from parent class" do
29
+ spawn_model "Foo::ChildUser", super_class: Foo::User do
30
+ end
31
+
32
+ expect(Foo::ChildUser).to be_include_root_in_json
33
+ end
34
+
35
+ it "allows `include_root_in_json` to be set to `false` on a child model" do
36
+ spawn_model "Foo::ChildUser", super_class: Foo::User do
37
+ include_root_in_json false
38
+ end
39
+
40
+ expect(Foo::ChildUser).to_not be_include_root_in_json
41
+ end
42
+
43
+ it "wraps params in the element name in `to_params`" do
44
+ @new_user = Foo::User.new(fullname: "Tobias Fünke")
45
+ expect(@new_user.to_params).to eq(user: { fullname: "Tobias Fünke" })
46
+ end
47
+
48
+ it "wraps params in the element name in `.create`" do
49
+ @new_user = Foo::User.admins(fullname: "Tobias Fünke")
50
+ expect(@new_user.fullname).to eq("Tobias Fünke")
51
+ end
52
+ end
53
+
54
+ context "to false" do
55
+ before do
56
+ spawn_model "Foo::User" do
57
+ include_root_in_json false
58
+ end
59
+ end
60
+
61
+ it "inherits attributes from parent class" do
62
+ spawn_model "Foo::ChildUser", super_class: Foo::User do
63
+ end
64
+
65
+ expect(Foo::ChildUser).to_not be_include_root_in_json
66
+ end
67
+
68
+ it "allows `include_root_in_json` to be set to `true` on a child model" do
69
+ spawn_model "Foo::ChildUser", super_class: Foo::User do
70
+ include_root_in_json true
71
+ end
72
+
73
+ expect(Foo::ChildUser).to be_include_root_in_json
74
+ end
75
+ end
76
+
77
+ context "to a symbol" do
78
+ before do
79
+ spawn_model "Foo::User" do
80
+ include_root_in_json :person
81
+ parse_root_in_json :person
82
+ end
83
+ end
84
+
85
+ it "wraps params in the specified value" do
86
+ @new_user = Foo::User.new(fullname: "Tobias Fünke")
87
+ expect(@new_user.to_params).to eq(person: { fullname: "Tobias Fünke" })
88
+ end
89
+ end
90
+
91
+ context "in the parent class" do
92
+ before do
93
+ spawn_model("Foo::Model") { include_root_in_json true }
94
+
95
+ class User < Foo::Model; end
96
+ @spawned_models << :User
97
+ end
98
+
99
+ it "wraps params with the class name" do
100
+ @new_user = User.new(fullname: "Tobias Fünke")
101
+ expect(@new_user.to_params).to eq(user: { fullname: "Tobias Fünke" })
102
+ end
103
+ end
104
+ end
105
+
106
+ context "when `request_new_object_on_build` is set" do
107
+ context "to true" do
108
+ before do
109
+ spawn_model "Foo::User" do
110
+ request_new_object_on_build true
111
+ end
112
+ end
113
+
114
+ it "inherits attributes from parent class" do
115
+ spawn_model "Foo::ChildUser", super_class: Foo::User do
116
+ end
117
+
118
+ expect(Foo::ChildUser).to be_request_new_object_on_build
119
+ end
120
+
121
+ it "allows `request_new_object_on_build` to be set to `false` on a child model" do
122
+ spawn_model "Foo::ChildUser", super_class: Foo::User do
123
+ request_new_object_on_build false
124
+ end
125
+
126
+ expect(Foo::ChildUser).to_not be_request_new_object_on_build
127
+ end
128
+ end
129
+
130
+ context "to false" do
131
+ before do
132
+ spawn_model "Foo::User" do
133
+ request_new_object_on_build false
134
+ end
135
+ end
136
+
137
+ it "inherits attributes from parent class" do
138
+ spawn_model "Foo::ChildUser", super_class: Foo::User do
139
+ end
140
+
141
+ expect(Foo::ChildUser).to_not be_request_new_object_on_build
142
+ end
143
+
144
+ it "allows `request_new_object_on_build` to be set to `true` on a child model" do
145
+ spawn_model "Foo::ChildUser", super_class: Foo::User do
146
+ request_new_object_on_build true
147
+ end
148
+
149
+ expect(Foo::ChildUser).to be_request_new_object_on_build
150
+ end
151
+ end
152
+ end
153
+
154
+ context "when parse_root_in_json is set" do
155
+ before do
156
+ Restorm::API.setup url: "https://api.example.com" do |builder|
157
+ builder.use Restorm::Middleware::FirstLevelParseJSON
158
+ builder.use Faraday::Request::UrlEncoded
159
+ end
160
+ end
161
+
162
+ context "to true" do
163
+ before do
164
+ Restorm::API.default_api.connection.adapter :test do |stub|
165
+ stub.post("/users") { [200, {}, { user: { id: 1, fullname: "Lindsay Fünke" } }.to_json] }
166
+ stub.get("/users") { [200, {}, [{ user: { id: 1, fullname: "Lindsay Fünke" } }].to_json] }
167
+ stub.get("/users/admins") { [200, {}, [{ user: { id: 1, fullname: "Lindsay Fünke" } }].to_json] }
168
+ stub.get("/users/1") { [200, {}, { user: { id: 1, fullname: "Lindsay Fünke" } }.to_json] }
169
+ stub.put("/users/1") { [200, {}, { user: { id: 1, fullname: "Tobias Fünke Jr." } }.to_json] }
170
+ end
171
+
172
+ spawn_model("Foo::User") do
173
+ parse_root_in_json true
174
+ custom_get :admins
175
+ end
176
+ end
177
+
178
+ it "inherits attributes from parent class" do
179
+ spawn_model "Foo::ChildUser", super_class: Foo::User do
180
+ end
181
+
182
+ expect(Foo::ChildUser).to be_parse_root_in_json
183
+ end
184
+
185
+ it "allows `parse_root_in_json` to be set to `false` on a child model" do
186
+ spawn_model "Foo::ChildUser", super_class: Foo::User do
187
+ parse_root_in_json false
188
+ end
189
+
190
+ expect(Foo::ChildUser).to_not be_parse_root_in_json
191
+ end
192
+
193
+ it "parse the data from the JSON root element after .create" do
194
+ @new_user = Foo::User.create(fullname: "Lindsay Fünke")
195
+ expect(@new_user.fullname).to eq("Lindsay Fünke")
196
+ end
197
+
198
+ it "parse the data from the JSON root element after an arbitrary HTTP request" do
199
+ @new_user = Foo::User.admins
200
+ expect(@new_user.first.fullname).to eq("Lindsay Fünke")
201
+ end
202
+
203
+ it "parse the data from the JSON root element after .all" do
204
+ @users = Foo::User.all
205
+ expect(@users.first.fullname).to eq("Lindsay Fünke")
206
+ end
207
+
208
+ it "parse the data from the JSON root element after .find" do
209
+ @user = Foo::User.find(1)
210
+ expect(@user.fullname).to eq("Lindsay Fünke")
211
+ end
212
+
213
+ it "parse the data from the JSON root element after .save" do
214
+ @user = Foo::User.find(1)
215
+ @user.fullname = "Tobias Fünke"
216
+ @user.save
217
+ expect(@user.fullname).to eq("Tobias Fünke Jr.")
218
+ end
219
+ end
220
+
221
+ context "to false" do
222
+ before do
223
+ spawn_model "Foo::User" do
224
+ parse_root_in_json false
225
+ end
226
+ end
227
+
228
+ it "inherits attributes from parent class" do
229
+ spawn_model "Foo::ChildUser", super_class: Foo::User do
230
+ end
231
+
232
+ expect(Foo::ChildUser).to_not be_parse_root_in_json
233
+ end
234
+
235
+ it "allows `parse_root_in_json` to be set to `true` on a child model" do
236
+ spawn_model "Foo::ChildUser", super_class: Foo::User do
237
+ parse_root_in_json true
238
+ end
239
+
240
+ expect(Foo::ChildUser).to be_parse_root_in_json
241
+ end
242
+ end
243
+
244
+ context "to a symbol" do
245
+ before do
246
+ Restorm::API.default_api.connection.adapter :test do |stub|
247
+ stub.post("/users") { [200, {}, { person: { id: 1, fullname: "Lindsay Fünke" } }.to_json] }
248
+ end
249
+
250
+ spawn_model("Foo::User") { parse_root_in_json :person }
251
+ end
252
+
253
+ it "parse the data with the symbol" do
254
+ @new_user = Foo::User.create(fullname: "Lindsay Fünke")
255
+ expect(@new_user.id).to eq(1)
256
+ expect(@new_user.fullname).to eq("Lindsay Fünke")
257
+ end
258
+ end
259
+
260
+ context "in the parent class" do
261
+ before do
262
+ Restorm::API.default_api.connection.adapter :test do |stub|
263
+ stub.post("/users") { [200, {}, { user: { id: 1, fullname: "Lindsay Fünke" } }.to_json] }
264
+ stub.get("/users") { [200, {}, { users: [{ id: 1, fullname: "Lindsay Fünke" }] }.to_json] }
265
+ end
266
+
267
+ spawn_model("Foo::Model") { parse_root_in_json true, format: :active_model_serializers }
268
+ class User < Foo::Model
269
+
270
+ collection_path "/users"
271
+ end
272
+
273
+ @spawned_models << :User
274
+ end
275
+
276
+ it "parse the data with the symbol" do
277
+ @new_user = User.create(fullname: "Lindsay Fünke")
278
+ expect(@new_user.fullname).to eq("Lindsay Fünke")
279
+ end
280
+
281
+ it "parses the collection of data" do
282
+ @users = User.all
283
+ expect(@users.first.fullname).to eq("Lindsay Fünke")
284
+ end
285
+ end
286
+
287
+ context "to true with format: :active_model_serializers" do
288
+ before do
289
+ Restorm::API.default_api.connection.adapter :test do |stub|
290
+ stub.post("/users") { [200, {}, { user: { id: 1, fullname: "Lindsay Fünke" } }.to_json] }
291
+ stub.get("/users") { [200, {}, { users: [{ id: 1, fullname: "Lindsay Fünke" }] }.to_json] }
292
+ stub.get("/users/admins") { [200, {}, { users: [{ id: 1, fullname: "Lindsay Fünke" }] }.to_json] }
293
+ stub.get("/users/1") { [200, {}, { user: { id: 1, fullname: "Lindsay Fünke" } }.to_json] }
294
+ stub.put("/users/1") { [200, {}, { user: { id: 1, fullname: "Tobias Fünke Jr." } }.to_json] }
295
+ end
296
+
297
+ spawn_model("Foo::User") do
298
+ parse_root_in_json true, format: :active_model_serializers
299
+ custom_get :admins
300
+ end
301
+ end
302
+
303
+ it "parse the data from the JSON root element after .create" do
304
+ @new_user = Foo::User.create(fullname: "Lindsay Fünke")
305
+ expect(@new_user.fullname).to eq("Lindsay Fünke")
306
+ end
307
+
308
+ it "parse the data from the JSON root element after an arbitrary HTTP request" do
309
+ @users = Foo::User.admins
310
+ expect(@users.first.fullname).to eq("Lindsay Fünke")
311
+ end
312
+
313
+ it "parse the data from the JSON root element after .all" do
314
+ @users = Foo::User.all
315
+ expect(@users.first.fullname).to eq("Lindsay Fünke")
316
+ end
317
+
318
+ it "parse the data from the JSON root element after .find" do
319
+ @user = Foo::User.find(1)
320
+ expect(@user.fullname).to eq("Lindsay Fünke")
321
+ end
322
+
323
+ it "parse the data from the JSON root element after .save" do
324
+ @user = Foo::User.find(1)
325
+ @user.fullname = "Tobias Fünke"
326
+ @user.save
327
+ expect(@user.fullname).to eq("Tobias Fünke Jr.")
328
+ end
329
+ end
330
+ end
331
+
332
+ context "when to_params is set" do
333
+ before do
334
+ Restorm::API.setup url: "https://api.example.com" do |builder|
335
+ builder.use Restorm::Middleware::FirstLevelParseJSON
336
+ builder.use Faraday::Request::UrlEncoded
337
+ builder.adapter :test do |stub|
338
+ stub.post("/users") { |env| ok! id: 1, fullname: params(env)["fullname"] }
339
+ end
340
+ end
341
+
342
+ spawn_model "Foo::User" do
343
+ def to_params
344
+ { fullname: "Lindsay Fünke" }
345
+ end
346
+ end
347
+ end
348
+
349
+ it "changes the request parameters for one-line resource creation" do
350
+ @user = Foo::User.create(fullname: "Tobias Fünke")
351
+ expect(@user.fullname).to eq("Lindsay Fünke")
352
+ end
353
+
354
+ it "changes the request parameters for Model.new + #save" do
355
+ @user = Foo::User.new(fullname: "Tobias Fünke")
356
+ @user.save
357
+ expect(@user.fullname).to eq("Lindsay Fünke")
358
+ end
359
+ end
360
+
361
+ context "when parse_root_in_json set json_api to true" do
362
+ before do
363
+ Restorm::API.setup url: "https://api.example.com" do |builder|
364
+ builder.use Restorm::Middleware::FirstLevelParseJSON
365
+ builder.use Faraday::Request::UrlEncoded
366
+ builder.adapter :test do |stub|
367
+ stub.get("/users") { [200, {}, { users: [{ id: 1, fullname: "Lindsay Fünke" }] }.to_json] }
368
+ stub.get("/users/admins") { [200, {}, { users: [{ id: 1, fullname: "Lindsay Fünke" }] }.to_json] }
369
+ stub.get("/users/1") { [200, {}, { users: [{ id: 1, fullname: "Lindsay Fünke" }] }.to_json] }
370
+ stub.post("/users") { [200, {}, { users: [{ fullname: "Lindsay Fünke" }] }.to_json] }
371
+ stub.put("/users/1") { [200, {}, { users: [{ id: 1, fullname: "Tobias Fünke Jr." }] }.to_json] }
372
+ end
373
+ end
374
+
375
+ spawn_model("Foo::User") do
376
+ parse_root_in_json true, format: :json_api
377
+ include_root_in_json true
378
+ custom_get :admins
379
+ end
380
+ end
381
+
382
+ it "parse the data from the JSON root element after .create" do
383
+ @new_user = Foo::User.create(fullname: "Lindsay Fünke")
384
+ expect(@new_user.fullname).to eq("Lindsay Fünke")
385
+ end
386
+
387
+ it "parse the data from the JSON root element after an arbitrary HTTP request" do
388
+ @new_user = Foo::User.admins
389
+ expect(@new_user.first.fullname).to eq("Lindsay Fünke")
390
+ end
391
+
392
+ it "parse the data from the JSON root element after .all" do
393
+ @users = Foo::User.all
394
+ expect(@users.first.fullname).to eq("Lindsay Fünke")
395
+ end
396
+
397
+ it "parse the data from the JSON root element after .find" do
398
+ @user = Foo::User.find(1)
399
+ expect(@user.fullname).to eq("Lindsay Fünke")
400
+ end
401
+
402
+ it "parse the data from the JSON root element after .save" do
403
+ @user = Foo::User.find(1)
404
+ @user.fullname = "Tobias Fünke"
405
+ @user.save
406
+ expect(@user.fullname).to eq("Tobias Fünke Jr.")
407
+ end
408
+
409
+ it "parse the data from the JSON root element after new/save" do
410
+ @user = Foo::User.new
411
+ @user.fullname = "Lindsay Fünke (before save)"
412
+ @user.save
413
+ expect(@user.fullname).to eq("Lindsay Fünke")
414
+ end
415
+ end
416
+
417
+ context "when include_root_in_json set json_api" do
418
+ before do
419
+ Restorm::API.setup url: "https://api.example.com" do |builder|
420
+ builder.use Restorm::Middleware::FirstLevelParseJSON
421
+ builder.use Faraday::Request::UrlEncoded
422
+ end
423
+
424
+ Restorm::API.default_api.connection.adapter :test do |stub|
425
+ stub.post("/users") { |env| [200, {}, { users: [{ id: 1, fullname: params(env)[:users][:fullname] }] }.to_json] }
426
+ end
427
+ end
428
+
429
+ context "to true" do
430
+ before do
431
+ spawn_model "Foo::User" do
432
+ include_root_in_json true
433
+ parse_root_in_json true, format: :json_api
434
+ custom_post :admins
435
+ end
436
+ end
437
+
438
+ it "wraps params in the element name in `to_params`" do
439
+ @new_user = Foo::User.new(fullname: "Tobias Fünke")
440
+ expect(@new_user.to_params).to eq(users: [{ fullname: "Tobias Fünke" }])
441
+ end
442
+
443
+ it "wraps params in the element name in `.where`" do
444
+ @new_user = Foo::User.where(fullname: "Tobias Fünke").build
445
+ expect(@new_user.fullname).to eq("Tobias Fünke")
446
+ end
447
+ end
448
+ end
449
+
450
+ context "when send_only_modified_attributes is set" do
451
+ before do
452
+ Restorm::API.setup url: "https://api.example.com", send_only_modified_attributes: true do |builder|
453
+ builder.use Restorm::Middleware::FirstLevelParseJSON
454
+ builder.use Faraday::Request::UrlEncoded
455
+ end
456
+
457
+ Restorm::API.default_api.connection.adapter :test do |stub|
458
+ stub.get("/users/1") { [200, {}, { id: 1, first_name: "Gooby", last_name: "Pls" }.to_json] }
459
+ end
460
+
461
+ spawn_model "Foo::User" do
462
+ include_root_in_json true
463
+ end
464
+ end
465
+
466
+ it "only sends the attributes that were modified" do
467
+ user = Foo::User.find 1
468
+ user.first_name = "Someone"
469
+ expect(user.to_params).to eql(user: { first_name: "Someone" })
470
+ end
471
+ end
472
+
473
+ context 'when passed a non-Restorm ActiveModel instance' do
474
+ before do
475
+ klass = Class.new do
476
+ include ActiveModel::Serialization
477
+
478
+ def attributes
479
+ { 'name' => nil }
480
+ end
481
+
482
+ def name
483
+ 'foo'
484
+ end
485
+ end
486
+
487
+ @model = klass.new
488
+
489
+ Restorm::API.setup
490
+ spawn_model 'Foo::User'
491
+ end
492
+
493
+ it 'serializes the instance in `to_params`' do
494
+ attributes = { model: @model }
495
+ user = Foo::User.new(attributes)
496
+ expect(user.to_params).to eq(model: { name: 'foo' })
497
+ end
498
+ end
499
+
500
+ context "when attribute uses the same name as root element" do
501
+ before do
502
+ Restorm::API.setup url: "https://api.example.com" do |builder|
503
+ builder.use Restorm::Middleware::FirstLevelParseJSON
504
+ builder.use Faraday::Request::UrlEncoded
505
+ end
506
+
507
+ Restorm::API.default_api.connection.adapter :test do |stub|
508
+ stub.post("/users") { |env| [200, {}, { user: "foobar", id: 1, fullname: params(env)[:fullname] }.to_json] }
509
+ end
510
+
511
+ spawn_model "Foo::User"
512
+ end
513
+
514
+ it "parses as attribute instead of root element" do
515
+ user = Foo::User.create(fullname: "barfoo")
516
+ expect(user.fullname).to eq "barfoo"
517
+ expect(user.user).to eq "foobar"
518
+ end
519
+ end
520
+ end