nokogiri-happymapper 0.6.0 → 0.9.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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +64 -5
- data/README.md +296 -192
- data/lib/happymapper/anonymous_mapper.rb +46 -43
- data/lib/happymapper/attribute.rb +7 -5
- data/lib/happymapper/element.rb +19 -22
- data/lib/happymapper/item.rb +19 -21
- data/lib/happymapper/supported_types.rb +20 -28
- data/lib/happymapper/text_node.rb +4 -3
- data/lib/happymapper/version.rb +3 -1
- data/lib/happymapper.rb +336 -362
- data/lib/nokogiri-happymapper.rb +4 -0
- metadata +124 -105
- data/spec/attribute_default_value_spec.rb +0 -50
- data/spec/attributes_spec.rb +0 -36
- data/spec/fixtures/address.xml +0 -9
- data/spec/fixtures/ambigous_items.xml +0 -22
- data/spec/fixtures/analytics.xml +0 -61
- data/spec/fixtures/analytics_profile.xml +0 -127
- data/spec/fixtures/atom.xml +0 -19
- data/spec/fixtures/commit.xml +0 -52
- data/spec/fixtures/current_weather.xml +0 -89
- data/spec/fixtures/current_weather_missing_elements.xml +0 -18
- data/spec/fixtures/default_namespace_combi.xml +0 -6
- data/spec/fixtures/dictionary.xml +0 -20
- data/spec/fixtures/family_tree.xml +0 -21
- data/spec/fixtures/inagy.xml +0 -85
- data/spec/fixtures/lastfm.xml +0 -355
- data/spec/fixtures/multiple_namespaces.xml +0 -170
- data/spec/fixtures/multiple_primitives.xml +0 -5
- data/spec/fixtures/optional_attributes.xml +0 -6
- data/spec/fixtures/pita.xml +0 -133
- data/spec/fixtures/posts.xml +0 -23
- data/spec/fixtures/product_default_namespace.xml +0 -18
- data/spec/fixtures/product_no_namespace.xml +0 -10
- data/spec/fixtures/product_single_namespace.xml +0 -10
- data/spec/fixtures/quarters.xml +0 -19
- data/spec/fixtures/radar.xml +0 -21
- data/spec/fixtures/set_config_options.xml +0 -3
- data/spec/fixtures/statuses.xml +0 -422
- data/spec/fixtures/subclass_namespace.xml +0 -50
- data/spec/fixtures/unformatted_address.xml +0 -1
- data/spec/fixtures/wrapper.xml +0 -11
- data/spec/happymapper/attribute_spec.rb +0 -12
- data/spec/happymapper/element_spec.rb +0 -9
- data/spec/happymapper/item_spec.rb +0 -136
- data/spec/happymapper/text_node_spec.rb +0 -9
- data/spec/happymapper_parse_spec.rb +0 -113
- data/spec/happymapper_spec.rb +0 -1129
- data/spec/has_many_empty_array_spec.rb +0 -43
- data/spec/ignay_spec.rb +0 -95
- data/spec/inheritance_spec.rb +0 -107
- data/spec/mixed_namespaces_spec.rb +0 -61
- data/spec/parse_with_object_to_update_spec.rb +0 -111
- data/spec/spec_helper.rb +0 -7
- data/spec/to_xml_spec.rb +0 -201
- data/spec/to_xml_with_namespaces_spec.rb +0 -232
- data/spec/wilcard_tag_name_spec.rb +0 -96
- data/spec/wrap_spec.rb +0 -82
- data/spec/xpath_spec.rb +0 -89
data/spec/happymapper_spec.rb
DELETED
@@ -1,1129 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'uri'
|
3
|
-
|
4
|
-
module Analytics
|
5
|
-
class Property
|
6
|
-
include HappyMapper
|
7
|
-
|
8
|
-
tag 'property'
|
9
|
-
namespace 'dxp'
|
10
|
-
attribute :name, String
|
11
|
-
attribute :value, String
|
12
|
-
end
|
13
|
-
|
14
|
-
class Goal
|
15
|
-
include HappyMapper
|
16
|
-
|
17
|
-
# Google Analytics does a dirtry trick where a user with no goals
|
18
|
-
# returns a profile without any goals data or the declared namespace
|
19
|
-
# which means Nokogiri does not pick up the namespace automatically.
|
20
|
-
# To fix this, we manually register the namespace to avoid bad XPath
|
21
|
-
# expression. Dirty, but works.
|
22
|
-
|
23
|
-
register_namespace 'ga', 'http://schemas.google.com/ga/2009'
|
24
|
-
namespace 'ga'
|
25
|
-
|
26
|
-
tag 'goal'
|
27
|
-
attribute :active, Boolean
|
28
|
-
attribute :name, String
|
29
|
-
attribute :number, Integer
|
30
|
-
attribute :value, Float
|
31
|
-
|
32
|
-
def clean_name
|
33
|
-
name.gsub(/ga:/, '')
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
class Profile
|
38
|
-
include HappyMapper
|
39
|
-
|
40
|
-
tag 'entry'
|
41
|
-
element :title, String
|
42
|
-
element :tableId, String, :namespace => 'dxp'
|
43
|
-
|
44
|
-
has_many :properties, Property
|
45
|
-
has_many :goals, Goal
|
46
|
-
end
|
47
|
-
|
48
|
-
|
49
|
-
class Entry
|
50
|
-
include HappyMapper
|
51
|
-
|
52
|
-
tag 'entry'
|
53
|
-
element :id, String
|
54
|
-
element :updated, DateTime
|
55
|
-
element :title, String
|
56
|
-
element :table_id, String, :namespace => 'dxp', :tag => 'tableId'
|
57
|
-
has_many :properties, Property
|
58
|
-
end
|
59
|
-
|
60
|
-
class Feed
|
61
|
-
include HappyMapper
|
62
|
-
|
63
|
-
tag 'feed'
|
64
|
-
element :id, String
|
65
|
-
element :updated, DateTime
|
66
|
-
element :title, String
|
67
|
-
has_many :entries, Entry
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
module Atom
|
72
|
-
class Feed
|
73
|
-
include HappyMapper
|
74
|
-
tag 'feed'
|
75
|
-
|
76
|
-
attribute :xmlns, String, :single => true
|
77
|
-
element :id, String, :single => true
|
78
|
-
element :title, String, :single => true
|
79
|
-
element :updated, DateTime, :single => true
|
80
|
-
element :link, String, :single => false, :attributes => {
|
81
|
-
:rel => String,
|
82
|
-
:type => String,
|
83
|
-
:href => String
|
84
|
-
}
|
85
|
-
# has_many :entries, Entry # nothing interesting in the entries
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
class Country
|
90
|
-
include HappyMapper
|
91
|
-
|
92
|
-
attribute :code, String
|
93
|
-
content :name, String
|
94
|
-
end
|
95
|
-
|
96
|
-
|
97
|
-
class State
|
98
|
-
include HappyMapper
|
99
|
-
end
|
100
|
-
|
101
|
-
class Address
|
102
|
-
include HappyMapper
|
103
|
-
|
104
|
-
attr_accessor :xml_value
|
105
|
-
attr_accessor :xml_content
|
106
|
-
|
107
|
-
tag 'address'
|
108
|
-
element :street, String
|
109
|
-
element :postcode, String
|
110
|
-
element :housenumber, String
|
111
|
-
element :city, String
|
112
|
-
has_one :country, Country
|
113
|
-
has_one :state, State
|
114
|
-
end
|
115
|
-
|
116
|
-
class Feature
|
117
|
-
include HappyMapper
|
118
|
-
element :name, String, :xpath => './/text()'
|
119
|
-
end
|
120
|
-
|
121
|
-
class FeatureBullet
|
122
|
-
include HappyMapper
|
123
|
-
|
124
|
-
tag 'features_bullets'
|
125
|
-
has_many :features, Feature
|
126
|
-
element :bug, String
|
127
|
-
end
|
128
|
-
|
129
|
-
class Product
|
130
|
-
include HappyMapper
|
131
|
-
|
132
|
-
element :title, String
|
133
|
-
has_one :feature_bullets, FeatureBullet
|
134
|
-
has_one :address, Address
|
135
|
-
end
|
136
|
-
|
137
|
-
class Rate
|
138
|
-
include HappyMapper
|
139
|
-
end
|
140
|
-
|
141
|
-
module FamilySearch
|
142
|
-
class AlternateIds
|
143
|
-
include HappyMapper
|
144
|
-
|
145
|
-
tag 'alternateIds'
|
146
|
-
has_many :ids, String, :tag => 'id'
|
147
|
-
end
|
148
|
-
|
149
|
-
class Information
|
150
|
-
include HappyMapper
|
151
|
-
|
152
|
-
has_one :alternateIds, AlternateIds
|
153
|
-
end
|
154
|
-
|
155
|
-
class Person
|
156
|
-
include HappyMapper
|
157
|
-
|
158
|
-
attribute :version, String
|
159
|
-
attribute :modified, Time
|
160
|
-
attribute :id, String
|
161
|
-
has_one :information, Information
|
162
|
-
end
|
163
|
-
|
164
|
-
class Persons
|
165
|
-
include HappyMapper
|
166
|
-
has_many :person, Person
|
167
|
-
end
|
168
|
-
|
169
|
-
class FamilyTree
|
170
|
-
include HappyMapper
|
171
|
-
|
172
|
-
tag 'familytree'
|
173
|
-
attribute :version, String
|
174
|
-
attribute :status_message, String, :tag => 'statusMessage'
|
175
|
-
attribute :status_code, String, :tag => 'statusCode'
|
176
|
-
has_one :persons, Persons
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
module FedEx
|
181
|
-
class Address
|
182
|
-
include HappyMapper
|
183
|
-
|
184
|
-
tag 'Address'
|
185
|
-
namespace 'v2'
|
186
|
-
element :city, String, :tag => 'City'
|
187
|
-
element :state, String, :tag => 'StateOrProvinceCode'
|
188
|
-
element :zip, String, :tag => 'PostalCode'
|
189
|
-
element :countrycode, String, :tag => 'CountryCode'
|
190
|
-
element :residential, Boolean, :tag => 'Residential'
|
191
|
-
end
|
192
|
-
|
193
|
-
class Event
|
194
|
-
include HappyMapper
|
195
|
-
|
196
|
-
tag 'Events'
|
197
|
-
namespace 'v2'
|
198
|
-
element :timestamp, String, :tag => 'Timestamp'
|
199
|
-
element :eventtype, String, :tag => 'EventType'
|
200
|
-
element :eventdescription, String, :tag => 'EventDescription'
|
201
|
-
has_one :address, Address
|
202
|
-
end
|
203
|
-
|
204
|
-
class PackageWeight
|
205
|
-
include HappyMapper
|
206
|
-
|
207
|
-
tag 'PackageWeight'
|
208
|
-
namespace 'v2'
|
209
|
-
element :units, String, :tag => 'Units'
|
210
|
-
element :value, Integer, :tag => 'Value'
|
211
|
-
end
|
212
|
-
|
213
|
-
class TrackDetails
|
214
|
-
include HappyMapper
|
215
|
-
|
216
|
-
tag 'TrackDetails'
|
217
|
-
namespace 'v2'
|
218
|
-
element :tracking_number, String, :tag => 'TrackingNumber'
|
219
|
-
element :status_code, String, :tag => 'StatusCode'
|
220
|
-
element :status_desc, String, :tag => 'StatusDescription'
|
221
|
-
element :carrier_code, String, :tag => 'CarrierCode'
|
222
|
-
element :service_info, String, :tag => 'ServiceInfo'
|
223
|
-
has_one :weight, PackageWeight, :tag => 'PackageWeight'
|
224
|
-
element :est_delivery, String, :tag => 'EstimatedDeliveryTimestamp'
|
225
|
-
has_many :events, Event
|
226
|
-
end
|
227
|
-
|
228
|
-
class Notification
|
229
|
-
include HappyMapper
|
230
|
-
|
231
|
-
tag 'Notifications'
|
232
|
-
namespace 'v2'
|
233
|
-
element :severity, String, :tag => 'Severity'
|
234
|
-
element :source, String, :tag => 'Source'
|
235
|
-
element :code, Integer, :tag => 'Code'
|
236
|
-
element :message, String, :tag => 'Message'
|
237
|
-
element :localized_message, String, :tag => 'LocalizedMessage'
|
238
|
-
end
|
239
|
-
|
240
|
-
class TransactionDetail
|
241
|
-
include HappyMapper
|
242
|
-
|
243
|
-
tag 'TransactionDetail'
|
244
|
-
namespace 'v2'
|
245
|
-
element :cust_tran_id, String, :tag => 'CustomerTransactionId'
|
246
|
-
end
|
247
|
-
|
248
|
-
class TrackReply
|
249
|
-
include HappyMapper
|
250
|
-
|
251
|
-
tag 'TrackReply'
|
252
|
-
namespace 'v2'
|
253
|
-
element :highest_severity, String, :tag => 'HighestSeverity'
|
254
|
-
element :more_data, Boolean, :tag => 'MoreData'
|
255
|
-
has_many :notifications, Notification, :tag => 'Notifications'
|
256
|
-
has_many :trackdetails, TrackDetails, :tag => 'TrackDetails'
|
257
|
-
has_one :tran_detail, TransactionDetail, :tab => 'TransactionDetail'
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
class Place
|
262
|
-
include HappyMapper
|
263
|
-
element :name, String
|
264
|
-
end
|
265
|
-
|
266
|
-
class Radar
|
267
|
-
include HappyMapper
|
268
|
-
has_many :places, Place, :tag => :place
|
269
|
-
end
|
270
|
-
|
271
|
-
class Post
|
272
|
-
include HappyMapper
|
273
|
-
|
274
|
-
attribute :href, String
|
275
|
-
attribute :hash, String
|
276
|
-
attribute :description, String
|
277
|
-
attribute :tag, String
|
278
|
-
attribute :time, Time
|
279
|
-
attribute :others, Integer
|
280
|
-
attribute :extended, String
|
281
|
-
end
|
282
|
-
|
283
|
-
class User
|
284
|
-
include HappyMapper
|
285
|
-
|
286
|
-
element :id, Integer
|
287
|
-
element :name, String
|
288
|
-
element :screen_name, String
|
289
|
-
element :location, String
|
290
|
-
element :description, String
|
291
|
-
element :profile_image_url, String
|
292
|
-
element :url, String
|
293
|
-
element :protected, Boolean
|
294
|
-
element :followers_count, Integer
|
295
|
-
end
|
296
|
-
|
297
|
-
class Status
|
298
|
-
include HappyMapper
|
299
|
-
|
300
|
-
register_namespace 'fake', "faka:namespace"
|
301
|
-
|
302
|
-
element :id, Integer
|
303
|
-
element :text, String
|
304
|
-
element :created_at, Time
|
305
|
-
element :source, String
|
306
|
-
element :truncated, Boolean
|
307
|
-
element :in_reply_to_status_id, Integer
|
308
|
-
element :in_reply_to_user_id, Integer
|
309
|
-
element :favorited, Boolean
|
310
|
-
element :non_existent, String, :tag => 'dummy', :namespace => 'fake'
|
311
|
-
has_one :user, User
|
312
|
-
end
|
313
|
-
|
314
|
-
class CurrentWeather
|
315
|
-
include HappyMapper
|
316
|
-
|
317
|
-
tag 'ob'
|
318
|
-
namespace 'aws'
|
319
|
-
element :temperature, Integer, :tag => 'temp'
|
320
|
-
element :feels_like, Integer, :tag => 'feels-like'
|
321
|
-
element :current_condition, String, :tag => 'current-condition', :attributes => {:icon => String}
|
322
|
-
end
|
323
|
-
|
324
|
-
# for type coercion
|
325
|
-
class ProductGroup < String; end
|
326
|
-
|
327
|
-
module PITA
|
328
|
-
class Item
|
329
|
-
include HappyMapper
|
330
|
-
|
331
|
-
tag 'Item' # if you put class in module you need tag
|
332
|
-
element :asin, String, :tag => 'ASIN'
|
333
|
-
element :detail_page_url, URI, :tag => 'DetailPageURL', :parser => :parse
|
334
|
-
element :manufacturer, String, :tag => 'Manufacturer', :deep => true
|
335
|
-
element :point, String, :tag => 'point', :namespace => 'georss'
|
336
|
-
element :product_group, ProductGroup, :tag => 'ProductGroup', :deep => true, :parser => :new, :raw => true
|
337
|
-
end
|
338
|
-
|
339
|
-
class Items
|
340
|
-
include HappyMapper
|
341
|
-
|
342
|
-
tag 'Items' # if you put class in module you need tag
|
343
|
-
element :total_results, Integer, :tag => 'TotalResults'
|
344
|
-
element :total_pages, Integer, :tag => 'TotalPages'
|
345
|
-
has_many :items, Item
|
346
|
-
end
|
347
|
-
end
|
348
|
-
|
349
|
-
module GitHub
|
350
|
-
class Commit
|
351
|
-
include HappyMapper
|
352
|
-
|
353
|
-
tag "commit"
|
354
|
-
element :url, String
|
355
|
-
element :tree, String
|
356
|
-
element :message, String
|
357
|
-
element :id, String
|
358
|
-
element :'committed-date', Date
|
359
|
-
end
|
360
|
-
end
|
361
|
-
|
362
|
-
module QuarterTest
|
363
|
-
class Quarter
|
364
|
-
include HappyMapper
|
365
|
-
|
366
|
-
element :start, String
|
367
|
-
end
|
368
|
-
|
369
|
-
class Details
|
370
|
-
include HappyMapper
|
371
|
-
|
372
|
-
element :round, Integer
|
373
|
-
element :quarter, Integer
|
374
|
-
end
|
375
|
-
|
376
|
-
class Game
|
377
|
-
include HappyMapper
|
378
|
-
|
379
|
-
# in an ideal world, the following elements would all be
|
380
|
-
# called 'quarter' with an attribute indicating which quarter
|
381
|
-
# it represented, but the refactoring that allows a single class
|
382
|
-
# to be used for all these differently named elements is the next
|
383
|
-
# best thing
|
384
|
-
has_one :details, QuarterTest::Details
|
385
|
-
has_one :q1, QuarterTest::Quarter, :tag => 'q1'
|
386
|
-
has_one :q2, QuarterTest::Quarter, :tag => 'q2'
|
387
|
-
has_one :q3, QuarterTest::Quarter, :tag => 'q3'
|
388
|
-
has_one :q4, QuarterTest::Quarter, :tag => 'q4'
|
389
|
-
end
|
390
|
-
end
|
391
|
-
|
392
|
-
# To check for multiple primitives
|
393
|
-
class Artist
|
394
|
-
include HappyMapper
|
395
|
-
|
396
|
-
tag 'artist'
|
397
|
-
element :images, String, :tag => "image", :single => false
|
398
|
-
element :name, String
|
399
|
-
end
|
400
|
-
|
401
|
-
class Location
|
402
|
-
include HappyMapper
|
403
|
-
|
404
|
-
tag 'point'
|
405
|
-
namespace "geo"
|
406
|
-
element :latitude, String, :tag => "lat"
|
407
|
-
end
|
408
|
-
|
409
|
-
# Testing the XmlContent type
|
410
|
-
module Dictionary
|
411
|
-
class Variant
|
412
|
-
include HappyMapper
|
413
|
-
tag 'var'
|
414
|
-
has_xml_content
|
415
|
-
|
416
|
-
def to_html
|
417
|
-
xml_content.gsub('<tag>','<em>').gsub('</tag>','</em>')
|
418
|
-
end
|
419
|
-
end
|
420
|
-
|
421
|
-
class Definition
|
422
|
-
include HappyMapper
|
423
|
-
|
424
|
-
tag 'def'
|
425
|
-
element :text, XmlContent, :tag => 'dtext'
|
426
|
-
end
|
427
|
-
|
428
|
-
class Record
|
429
|
-
include HappyMapper
|
430
|
-
|
431
|
-
tag 'record'
|
432
|
-
has_many :definitions, Definition
|
433
|
-
has_many :variants, Variant, :tag => 'var'
|
434
|
-
end
|
435
|
-
end
|
436
|
-
|
437
|
-
module AmbigousItems
|
438
|
-
class Item
|
439
|
-
include HappyMapper
|
440
|
-
|
441
|
-
tag 'item'
|
442
|
-
element :name, String
|
443
|
-
element :item, String
|
444
|
-
end
|
445
|
-
end
|
446
|
-
|
447
|
-
class PublishOptions
|
448
|
-
include HappyMapper
|
449
|
-
|
450
|
-
tag 'publishOptions'
|
451
|
-
|
452
|
-
element :author, String, :tag => 'author'
|
453
|
-
|
454
|
-
element :draft, Boolean, :tag => 'draft'
|
455
|
-
element :scheduled_day, String, :tag => 'scheduledDay'
|
456
|
-
element :scheduled_time, String, :tag => 'scheduledTime'
|
457
|
-
element :published_day, String, :tag => 'publishDisplayDay'
|
458
|
-
element :published_time, String, :tag => 'publishDisplayTime'
|
459
|
-
element :created_day, String, :tag => 'publishDisplayDay'
|
460
|
-
element :created_time, String, :tag => 'publishDisplayTime'
|
461
|
-
|
462
|
-
end
|
463
|
-
|
464
|
-
class Article
|
465
|
-
include HappyMapper
|
466
|
-
|
467
|
-
tag 'Article'
|
468
|
-
namespace 'article'
|
469
|
-
|
470
|
-
attr_writer :xml_value
|
471
|
-
|
472
|
-
element :title, String
|
473
|
-
element :text, String
|
474
|
-
has_many :photos, 'Photo', :tag => 'Photo', :namespace => 'photo', :xpath => '/article:Article'
|
475
|
-
has_many :galleries, 'Gallery', :tag => 'Gallery', :namespace => 'gallery'
|
476
|
-
|
477
|
-
element :publish_options, PublishOptions, :tag => 'publishOptions', :namespace => 'article'
|
478
|
-
|
479
|
-
end
|
480
|
-
|
481
|
-
class PartiallyBadArticle
|
482
|
-
include HappyMapper
|
483
|
-
|
484
|
-
attr_writer :xml_value
|
485
|
-
|
486
|
-
tag 'Article'
|
487
|
-
namespace 'article'
|
488
|
-
|
489
|
-
element :title, String
|
490
|
-
element :text, String
|
491
|
-
has_many :photos, 'Photo', :tag => 'Photo', :namespace => 'photo', :xpath => '/article:Article'
|
492
|
-
has_many :videos, 'Video', :tag => 'Video', :namespace => 'video'
|
493
|
-
|
494
|
-
element :publish_options, PublishOptions, :tag => 'publishOptions', :namespace => 'article'
|
495
|
-
|
496
|
-
end
|
497
|
-
|
498
|
-
class Photo
|
499
|
-
include HappyMapper
|
500
|
-
|
501
|
-
tag 'Photo'
|
502
|
-
namespace 'photo'
|
503
|
-
|
504
|
-
attr_writer :xml_value
|
505
|
-
|
506
|
-
element :title, String
|
507
|
-
element :publish_options, PublishOptions, :tag => 'publishOptions', :namespace => 'photo'
|
508
|
-
|
509
|
-
end
|
510
|
-
|
511
|
-
class Gallery
|
512
|
-
include HappyMapper
|
513
|
-
|
514
|
-
tag 'Gallery'
|
515
|
-
namespace 'gallery'
|
516
|
-
|
517
|
-
attr_writer :xml_value
|
518
|
-
|
519
|
-
element :title, String
|
520
|
-
|
521
|
-
end
|
522
|
-
|
523
|
-
class Video
|
524
|
-
include HappyMapper
|
525
|
-
|
526
|
-
tag 'Video'
|
527
|
-
namespace 'video'
|
528
|
-
|
529
|
-
attr_writer :xml_value
|
530
|
-
|
531
|
-
element :title, String
|
532
|
-
element :publish_options, PublishOptions, :tag => 'publishOptions', :namespace => 'video'
|
533
|
-
|
534
|
-
end
|
535
|
-
|
536
|
-
class OptionalAttribute
|
537
|
-
include HappyMapper
|
538
|
-
tag 'address'
|
539
|
-
|
540
|
-
attribute :street, String
|
541
|
-
end
|
542
|
-
|
543
|
-
class DefaultNamespaceCombi
|
544
|
-
include HappyMapper
|
545
|
-
|
546
|
-
|
547
|
-
register_namespace 'bk', "urn:loc.gov:books"
|
548
|
-
register_namespace 'isbn', "urn:ISBN:0-395-36341-6"
|
549
|
-
register_namespace 'p', "urn:loc.gov:people"
|
550
|
-
namespace 'bk'
|
551
|
-
|
552
|
-
tag 'book'
|
553
|
-
|
554
|
-
element :title, String, :namespace => 'bk', :tag => "title"
|
555
|
-
element :number, String, :namespace => 'isbn', :tag => "number"
|
556
|
-
element :author, String, :namespace => 'p', :tag => "author"
|
557
|
-
end
|
558
|
-
|
559
|
-
describe HappyMapper do
|
560
|
-
|
561
|
-
describe "being included into another class" do
|
562
|
-
before do
|
563
|
-
@klass = Class.new do
|
564
|
-
include HappyMapper
|
565
|
-
|
566
|
-
def self.to_s
|
567
|
-
'Boo'
|
568
|
-
end
|
569
|
-
end
|
570
|
-
end
|
571
|
-
|
572
|
-
class Boo; include HappyMapper end
|
573
|
-
|
574
|
-
it "should set attributes to an array" do
|
575
|
-
expect(@klass.attributes).to eq([])
|
576
|
-
end
|
577
|
-
|
578
|
-
it "should set @elements to a hash" do
|
579
|
-
expect(@klass.elements).to eq([])
|
580
|
-
end
|
581
|
-
|
582
|
-
it "should allow adding an attribute" do
|
583
|
-
expect {
|
584
|
-
@klass.attribute :name, String
|
585
|
-
}.to change(@klass, :attributes)
|
586
|
-
end
|
587
|
-
|
588
|
-
it "should allow adding an attribute containing a dash" do
|
589
|
-
expect {
|
590
|
-
@klass.attribute :'bar-baz', String
|
591
|
-
}.to change(@klass, :attributes)
|
592
|
-
end
|
593
|
-
|
594
|
-
it "should be able to get all attributes in array" do
|
595
|
-
@klass.attribute :name, String
|
596
|
-
expect(@klass.attributes.size).to eq(1)
|
597
|
-
end
|
598
|
-
|
599
|
-
it "should allow adding an element" do
|
600
|
-
expect {
|
601
|
-
@klass.element :name, String
|
602
|
-
}.to change(@klass, :elements)
|
603
|
-
end
|
604
|
-
|
605
|
-
it "should allow adding an element containing a dash" do
|
606
|
-
expect {
|
607
|
-
@klass.element :'bar-baz', String
|
608
|
-
}.to change(@klass, :elements)
|
609
|
-
|
610
|
-
end
|
611
|
-
|
612
|
-
it "should be able to get all elements in array" do
|
613
|
-
@klass.element(:name, String)
|
614
|
-
expect(@klass.elements.size).to eq(1)
|
615
|
-
end
|
616
|
-
|
617
|
-
it "should allow has one association" do
|
618
|
-
@klass.has_one(:user, User)
|
619
|
-
element = @klass.elements.first
|
620
|
-
expect(element.name).to eq('user')
|
621
|
-
expect(element.type).to eq(User)
|
622
|
-
expect(element.options[:single]).to eq(true)
|
623
|
-
end
|
624
|
-
|
625
|
-
it "should allow has many association" do
|
626
|
-
@klass.has_many(:users, User)
|
627
|
-
element = @klass.elements.first
|
628
|
-
expect(element.name).to eq('users')
|
629
|
-
expect(element.type).to eq(User)
|
630
|
-
expect(element.options[:single]).to eq(false)
|
631
|
-
end
|
632
|
-
|
633
|
-
it "should default tag name to lowercase class" do
|
634
|
-
expect(@klass.tag_name).to eq('boo')
|
635
|
-
end
|
636
|
-
|
637
|
-
it "should default tag name of class in modules to the last constant lowercase" do
|
638
|
-
module Bar; class Baz; include HappyMapper; end; end
|
639
|
-
expect(Bar::Baz.tag_name).to eq('baz')
|
640
|
-
end
|
641
|
-
|
642
|
-
it "should allow setting tag name" do
|
643
|
-
@klass.tag('FooBar')
|
644
|
-
expect(@klass.tag_name).to eq('FooBar')
|
645
|
-
end
|
646
|
-
|
647
|
-
it "should allow setting a namespace" do
|
648
|
-
@klass.namespace(namespace = "boo")
|
649
|
-
expect(@klass.namespace).to eq(namespace)
|
650
|
-
end
|
651
|
-
|
652
|
-
it "should provide #parse" do
|
653
|
-
expect(@klass).to respond_to(:parse)
|
654
|
-
end
|
655
|
-
end
|
656
|
-
|
657
|
-
describe "#attributes" do
|
658
|
-
it "should only return attributes for the current class" do
|
659
|
-
expect(Post.attributes.size).to eq(7)
|
660
|
-
expect(Status.attributes.size).to eq(0)
|
661
|
-
end
|
662
|
-
end
|
663
|
-
|
664
|
-
describe "#elements" do
|
665
|
-
it "should only return elements for the current class" do
|
666
|
-
expect(Post.elements.size).to eq(0)
|
667
|
-
expect(Status.elements.size).to eq(10)
|
668
|
-
end
|
669
|
-
end
|
670
|
-
|
671
|
-
describe "#content" do
|
672
|
-
it "should take String as default argument for type" do
|
673
|
-
State.content :name
|
674
|
-
address = Address.parse(fixture_file('address.xml'))
|
675
|
-
expect(address.state.name).to eq("Lower Saxony")
|
676
|
-
address.state.name.class == String
|
677
|
-
end
|
678
|
-
|
679
|
-
it "should work when specific type is provided" do
|
680
|
-
Rate.content :value, Float
|
681
|
-
Product.has_one :rate, Rate
|
682
|
-
product = Product.parse(fixture_file('product_default_namespace.xml'), :single => true)
|
683
|
-
expect(product.rate.value).to eq(120.25)
|
684
|
-
product.rate.class == Float
|
685
|
-
end
|
686
|
-
end
|
687
|
-
|
688
|
-
it "should parse xml attributes into ruby objects" do
|
689
|
-
posts = Post.parse(fixture_file('posts.xml'))
|
690
|
-
expect(posts.size).to eq(20)
|
691
|
-
first = posts.first
|
692
|
-
expect(first.href).to eq('http://roxml.rubyforge.org/')
|
693
|
-
expect(first.hash).to eq('19bba2ab667be03a19f67fb67dc56917')
|
694
|
-
expect(first.description).to eq('ROXML - Ruby Object to XML Mapping Library')
|
695
|
-
expect(first.tag).to eq('ruby xml gems mapping')
|
696
|
-
expect(first.time).to eq(Time.utc(2008, 8, 9, 5, 24, 20))
|
697
|
-
expect(first.others).to eq(56)
|
698
|
-
expect(first.extended).to eq('ROXML is a Ruby library designed to make it easier for Ruby developers to work with XML. Using simple annotations, it enables Ruby classes to be custom-mapped to XML. ROXML takes care of the marshalling and unmarshalling of mapped attributes so that developers can focus on building first-class Ruby classes.')
|
699
|
-
end
|
700
|
-
|
701
|
-
it "should parse xml elements to ruby objcts" do
|
702
|
-
statuses = Status.parse(fixture_file('statuses.xml'))
|
703
|
-
expect(statuses.size).to eq(20)
|
704
|
-
first = statuses.first
|
705
|
-
expect(first.id).to eq(882281424)
|
706
|
-
expect(first.created_at).to eq(Time.utc(2008, 8, 9, 5, 38, 12))
|
707
|
-
expect(first.source).to eq('web')
|
708
|
-
expect(first.truncated).to be_falsey
|
709
|
-
expect(first.in_reply_to_status_id).to eq(1234)
|
710
|
-
expect(first.in_reply_to_user_id).to eq(12345)
|
711
|
-
expect(first.favorited).to be_falsey
|
712
|
-
expect(first.user.id).to eq(4243)
|
713
|
-
expect(first.user.name).to eq('John Nunemaker')
|
714
|
-
expect(first.user.screen_name).to eq('jnunemaker')
|
715
|
-
expect(first.user.location).to eq('Mishawaka, IN, US')
|
716
|
-
expect(first.user.description).to eq('Loves his wife, ruby, notre dame football and iu basketball')
|
717
|
-
expect(first.user.profile_image_url).to eq('http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg')
|
718
|
-
expect(first.user.url).to eq('http://addictedtonew.com')
|
719
|
-
expect(first.user.protected).to be_falsey
|
720
|
-
expect(first.user.followers_count).to eq(486)
|
721
|
-
end
|
722
|
-
|
723
|
-
it "should parse xml containing the desired element as root node" do
|
724
|
-
address = Address.parse(fixture_file('address.xml'), :single => true)
|
725
|
-
expect(address.street).to eq('Milchstrasse')
|
726
|
-
expect(address.postcode).to eq('26131')
|
727
|
-
expect(address.housenumber).to eq('23')
|
728
|
-
expect(address.city).to eq('Oldenburg')
|
729
|
-
expect(address.country.class).to eq(Country)
|
730
|
-
end
|
731
|
-
|
732
|
-
it "should parse text node correctly" do
|
733
|
-
address = Address.parse(fixture_file('address.xml'), :single => true)
|
734
|
-
expect(address.country.name).to eq('Germany')
|
735
|
-
expect(address.country.code).to eq('de')
|
736
|
-
end
|
737
|
-
|
738
|
-
it "should treat Nokogiri::XML::Document as root" do
|
739
|
-
doc = Nokogiri::XML(fixture_file('address.xml'))
|
740
|
-
address = Address.parse(doc)
|
741
|
-
expect(address.class).to eq(Address)
|
742
|
-
end
|
743
|
-
|
744
|
-
it "should parse xml with default namespace (amazon)" do
|
745
|
-
file_contents = fixture_file('pita.xml')
|
746
|
-
items = PITA::Items.parse(file_contents, :single => true)
|
747
|
-
expect(items.total_results).to eq(22)
|
748
|
-
expect(items.total_pages).to eq(3)
|
749
|
-
first = items.items[0]
|
750
|
-
second = items.items[1]
|
751
|
-
expect(first.asin).to eq('0321480791')
|
752
|
-
expect(first.point).to eq('38.5351715088 -121.7948684692')
|
753
|
-
expect(first.detail_page_url).to be_a_kind_of(URI)
|
754
|
-
expect(first.detail_page_url.to_s).to eq('http://www.amazon.com/gp/redirect.html%3FASIN=0321480791%26tag=ws%26lcode=xm2%26cID=2025%26ccmID=165953%26location=/o/ASIN/0321480791%253FSubscriptionId=dontbeaswoosh')
|
755
|
-
expect(first.manufacturer).to eq('Addison-Wesley Professional')
|
756
|
-
expect(first.product_group).to eq('<ProductGroup>Book</ProductGroup>')
|
757
|
-
expect(second.asin).to eq('047022388X')
|
758
|
-
expect(second.manufacturer).to eq('Wrox')
|
759
|
-
end
|
760
|
-
|
761
|
-
it "should parse xml that has attributes of elements" do
|
762
|
-
items = CurrentWeather.parse(fixture_file('current_weather.xml'))
|
763
|
-
first = items[0]
|
764
|
-
expect(first.temperature).to eq(51)
|
765
|
-
expect(first.feels_like).to eq(51)
|
766
|
-
expect(first.current_condition).to eq('Sunny')
|
767
|
-
expect(first.current_condition.icon).to eq('http://deskwx.weatherbug.com/images/Forecast/icons/cond007.gif')
|
768
|
-
end
|
769
|
-
|
770
|
-
it "parses xml with attributes of elements that aren't :single => true" do
|
771
|
-
feed = Atom::Feed.parse(fixture_file('atom.xml'))
|
772
|
-
expect(feed.link.first.href).to eq('http://www.example.com')
|
773
|
-
expect(feed.link.last.href).to eq('http://www.example.com/tv_shows.atom')
|
774
|
-
end
|
775
|
-
|
776
|
-
it "parses xml with optional elements with embedded attributes" do
|
777
|
-
expect { CurrentWeather.parse(fixture_file('current_weather_missing_elements.xml')) }.to_not raise_error()
|
778
|
-
end
|
779
|
-
|
780
|
-
it "returns nil rather than empty array for absent values when :single => true" do
|
781
|
-
address = Address.parse('<?xml version="1.0" encoding="UTF-8"?><foo/>', :single => true)
|
782
|
-
expect(address).to be_nil
|
783
|
-
end
|
784
|
-
|
785
|
-
it "should return same result for absent values when :single => true, regardless of :in_groups_of" do
|
786
|
-
addr1 = Address.parse('<?xml version="1.0" encoding="UTF-8"?><foo/>', :single => true)
|
787
|
-
addr2 = Address.parse('<?xml version="1.0" encoding="UTF-8"?><foo/>', :single => true, :in_groups_of => 10)
|
788
|
-
expect(addr1).to eq(addr2)
|
789
|
-
end
|
790
|
-
|
791
|
-
it "should parse xml with nested elements" do
|
792
|
-
radars = Radar.parse(fixture_file('radar.xml'))
|
793
|
-
first = radars[0]
|
794
|
-
expect(first.places.size).to eq(1)
|
795
|
-
expect(first.places[0].name).to eq('Store')
|
796
|
-
second = radars[1]
|
797
|
-
expect(second.places.size).to eq(0)
|
798
|
-
third = radars[2]
|
799
|
-
expect(third.places.size).to eq(2)
|
800
|
-
expect(third.places[0].name).to eq('Work')
|
801
|
-
expect(third.places[1].name).to eq('Home')
|
802
|
-
end
|
803
|
-
|
804
|
-
it "should parse xml with element name different to class name" do
|
805
|
-
game = QuarterTest::Game.parse(fixture_file('quarters.xml'))
|
806
|
-
expect(game.q1.start).to eq('4:40:15 PM')
|
807
|
-
expect(game.q2.start).to eq('5:18:53 PM')
|
808
|
-
end
|
809
|
-
|
810
|
-
it "should parse xml that has elements with dashes" do
|
811
|
-
commit = GitHub::Commit.parse(fixture_file('commit.xml'))
|
812
|
-
expect(commit.message).to eq("move commands.rb and helpers.rb into commands/ dir")
|
813
|
-
expect(commit.url).to eq("http://github.com/defunkt/github-gem/commit/c26d4ce9807ecf57d3f9eefe19ae64e75bcaaa8b")
|
814
|
-
expect(commit.id).to eq("c26d4ce9807ecf57d3f9eefe19ae64e75bcaaa8b")
|
815
|
-
expect(commit.committed_date).to eq(Date.parse("2008-03-02T16:45:41-08:00"))
|
816
|
-
expect(commit.tree).to eq("28a1a1ca3e663d35ba8bf07d3f1781af71359b76")
|
817
|
-
end
|
818
|
-
|
819
|
-
it "should parse xml with no namespace" do
|
820
|
-
product = Product.parse(fixture_file('product_no_namespace.xml'), :single => true)
|
821
|
-
expect(product.title).to eq("A Title")
|
822
|
-
expect(product.feature_bullets.bug).to eq('This is a bug')
|
823
|
-
expect(product.feature_bullets.features.size).to eq(2)
|
824
|
-
expect(product.feature_bullets.features[0].name).to eq('This is feature text 1')
|
825
|
-
expect(product.feature_bullets.features[1].name).to eq('This is feature text 2')
|
826
|
-
end
|
827
|
-
|
828
|
-
it "should parse xml with default namespace" do
|
829
|
-
product = Product.parse(fixture_file('product_default_namespace.xml'), :single => true)
|
830
|
-
expect(product.title).to eq("A Title")
|
831
|
-
expect(product.feature_bullets.bug).to eq('This is a bug')
|
832
|
-
expect(product.feature_bullets.features.size).to eq(2)
|
833
|
-
expect(product.feature_bullets.features[0].name).to eq('This is feature text 1')
|
834
|
-
expect(product.feature_bullets.features[1].name).to eq('This is feature text 2')
|
835
|
-
end
|
836
|
-
|
837
|
-
it "should parse xml with single namespace" do
|
838
|
-
product = Product.parse(fixture_file('product_single_namespace.xml'), :single => true)
|
839
|
-
expect(product.title).to eq("A Title")
|
840
|
-
expect(product.feature_bullets.bug).to eq('This is a bug')
|
841
|
-
expect(product.feature_bullets.features.size).to eq(2)
|
842
|
-
expect(product.feature_bullets.features[0].name).to eq('This is feature text 1')
|
843
|
-
expect(product.feature_bullets.features[1].name).to eq('This is feature text 2')
|
844
|
-
end
|
845
|
-
|
846
|
-
it "should parse xml with multiple namespaces" do
|
847
|
-
track = FedEx::TrackReply.parse(fixture_file('multiple_namespaces.xml'))
|
848
|
-
expect(track.highest_severity).to eq('SUCCESS')
|
849
|
-
expect(track.more_data).to be_falsey
|
850
|
-
notification = track.notifications.first
|
851
|
-
expect(notification.code).to eq(0)
|
852
|
-
expect(notification.localized_message).to eq('Request was successfully processed.')
|
853
|
-
expect(notification.message).to eq('Request was successfully processed.')
|
854
|
-
expect(notification.severity).to eq('SUCCESS')
|
855
|
-
expect(notification.source).to eq('trck')
|
856
|
-
detail = track.trackdetails.first
|
857
|
-
expect(detail.carrier_code).to eq('FDXG')
|
858
|
-
expect(detail.est_delivery).to eq('2009-01-02T00:00:00')
|
859
|
-
expect(detail.service_info).to eq('Ground-Package Returns Program-Domestic')
|
860
|
-
expect(detail.status_code).to eq('OD')
|
861
|
-
expect(detail.status_desc).to eq('On FedEx vehicle for delivery')
|
862
|
-
expect(detail.tracking_number).to eq('9611018034267800045212')
|
863
|
-
expect(detail.weight.units).to eq('LB')
|
864
|
-
expect(detail.weight.value).to eq(2)
|
865
|
-
events = detail.events
|
866
|
-
expect(events.size).to eq(10)
|
867
|
-
first_event = events[0]
|
868
|
-
expect(first_event.eventdescription).to eq('On FedEx vehicle for delivery')
|
869
|
-
expect(first_event.eventtype).to eq('OD')
|
870
|
-
expect(first_event.timestamp).to eq('2009-01-02T06:00:00')
|
871
|
-
expect(first_event.address.city).to eq('WICHITA')
|
872
|
-
expect(first_event.address.countrycode).to eq('US')
|
873
|
-
expect(first_event.address.residential).to be_falsey
|
874
|
-
expect(first_event.address.state).to eq('KS')
|
875
|
-
expect(first_event.address.zip).to eq('67226')
|
876
|
-
last_event = events[-1]
|
877
|
-
expect(last_event.eventdescription).to eq('In FedEx possession')
|
878
|
-
expect(last_event.eventtype).to eq('IP')
|
879
|
-
expect(last_event.timestamp).to eq('2008-12-27T09:40:00')
|
880
|
-
expect(last_event.address.city).to eq('LONGWOOD')
|
881
|
-
expect(last_event.address.countrycode).to eq('US')
|
882
|
-
expect(last_event.address.residential).to be_falsey
|
883
|
-
expect(last_event.address.state).to eq('FL')
|
884
|
-
expect(last_event.address.zip).to eq('327506398')
|
885
|
-
expect(track.tran_detail.cust_tran_id).to eq('20090102-111321')
|
886
|
-
end
|
887
|
-
|
888
|
-
it "should be able to parse google analytics api xml" do
|
889
|
-
data = Analytics::Feed.parse(fixture_file('analytics.xml'))
|
890
|
-
expect(data.id).to eq('http://www.google.com/analytics/feeds/accounts/nunemaker@gmail.com')
|
891
|
-
expect(data.entries.size).to eq(4)
|
892
|
-
|
893
|
-
entry = data.entries[0]
|
894
|
-
expect(entry.title).to eq('addictedtonew.com')
|
895
|
-
expect(entry.properties.size).to eq(4)
|
896
|
-
|
897
|
-
property = entry.properties[0]
|
898
|
-
expect(property.name).to eq('ga:accountId')
|
899
|
-
expect(property.value).to eq('85301')
|
900
|
-
end
|
901
|
-
|
902
|
-
it "should be able to parse google analytics profile xml with manually declared namespace" do
|
903
|
-
data = Analytics::Profile.parse(fixture_file('analytics_profile.xml'))
|
904
|
-
expect(data.entries.size).to eq(6)
|
905
|
-
|
906
|
-
entry = data.entries[0]
|
907
|
-
expect(entry.title).to eq('www.homedepot.com')
|
908
|
-
expect(entry.properties.size).to eq(6)
|
909
|
-
expect(entry.goals.size).to eq(0)
|
910
|
-
end
|
911
|
-
|
912
|
-
it "should allow instantiating with a string" do
|
913
|
-
module StringFoo
|
914
|
-
class Bar
|
915
|
-
include HappyMapper
|
916
|
-
has_many :things, 'StringFoo::Thing'
|
917
|
-
end
|
918
|
-
|
919
|
-
class Thing
|
920
|
-
include HappyMapper
|
921
|
-
end
|
922
|
-
end
|
923
|
-
end
|
924
|
-
|
925
|
-
it "should parse family search xml" do
|
926
|
-
tree = FamilySearch::FamilyTree.parse(fixture_file('family_tree.xml'))
|
927
|
-
expect(tree.version).to eq('1.0.20071213.942')
|
928
|
-
expect(tree.status_message).to eq('OK')
|
929
|
-
expect(tree.status_code).to eq('200')
|
930
|
-
expect(tree.persons.person.size).to eq(1)
|
931
|
-
expect(tree.persons.person.first.version).to eq('1199378491000')
|
932
|
-
expect(tree.persons.person.first.modified).to eq(Time.utc(2008, 1, 3, 16, 41, 31)) # 2008-01-03T09:41:31-07:00
|
933
|
-
expect(tree.persons.person.first.id).to eq('KWQS-BBQ')
|
934
|
-
expect(tree.persons.person.first.information.alternateIds.ids).not_to be_kind_of(String)
|
935
|
-
expect(tree.persons.person.first.information.alternateIds.ids.size).to eq(8)
|
936
|
-
end
|
937
|
-
|
938
|
-
it "should parse multiple images" do
|
939
|
-
artist = Artist.parse(fixture_file('multiple_primitives.xml'))
|
940
|
-
expect(artist.name).to eq("value")
|
941
|
-
expect(artist.images.size).to eq(2)
|
942
|
-
end
|
943
|
-
|
944
|
-
it "should parse lastfm namespaces" do
|
945
|
-
l = Location.parse(fixture_file('lastfm.xml'))
|
946
|
-
expect(l.first.latitude).to eq("51.53469")
|
947
|
-
end
|
948
|
-
|
949
|
-
describe "Parse optional attributes" do
|
950
|
-
|
951
|
-
it "should parse an empty String as empty" do
|
952
|
-
a = OptionalAttribute.parse(fixture_file('optional_attributes.xml'))
|
953
|
-
expect(a[0].street).to eq("")
|
954
|
-
end
|
955
|
-
|
956
|
-
it "should parse a String with value" do
|
957
|
-
a = OptionalAttribute.parse(fixture_file('optional_attributes.xml'))
|
958
|
-
expect(a[1].street).to eq("Milchstrasse")
|
959
|
-
end
|
960
|
-
|
961
|
-
it "should parse a String with value" do
|
962
|
-
a = OptionalAttribute.parse(fixture_file('optional_attributes.xml'))
|
963
|
-
expect(a[2].street).to be_nil
|
964
|
-
end
|
965
|
-
|
966
|
-
end
|
967
|
-
|
968
|
-
describe "Default namespace combi" do
|
969
|
-
before(:each) do
|
970
|
-
file_contents = fixture_file('default_namespace_combi.xml')
|
971
|
-
@book = DefaultNamespaceCombi.parse(file_contents, :single => true)
|
972
|
-
end
|
973
|
-
|
974
|
-
it "should parse author" do
|
975
|
-
expect(@book.author).to eq("Frank Gilbreth")
|
976
|
-
end
|
977
|
-
|
978
|
-
it "should parse title" do
|
979
|
-
expect(@book.title).to eq("Cheaper by the Dozen")
|
980
|
-
end
|
981
|
-
|
982
|
-
it "should parse number" do
|
983
|
-
expect(@book.number).to eq("1568491379")
|
984
|
-
end
|
985
|
-
|
986
|
-
end
|
987
|
-
|
988
|
-
describe 'Xml Content' do
|
989
|
-
before(:each) do
|
990
|
-
file_contents = fixture_file('dictionary.xml')
|
991
|
-
@records = Dictionary::Record.parse(file_contents)
|
992
|
-
end
|
993
|
-
|
994
|
-
it "should parse XmlContent" do
|
995
|
-
expect(@records.first.definitions.first.text).to eq(
|
996
|
-
'a large common parrot, <bn>Cacatua galerita</bn>, predominantly white, with yellow on the undersides of wings and tail and a forward curving yellow crest, found in Australia, New Guinea and nearby islands.'
|
997
|
-
)
|
998
|
-
end
|
999
|
-
|
1000
|
-
it "should save object's xml content" do
|
1001
|
-
expect(@records.first.variants.first.xml_content).to eq(
|
1002
|
-
'white <tag>cockatoo</tag>'
|
1003
|
-
)
|
1004
|
-
expect(@records.first.variants.last.to_html).to eq(
|
1005
|
-
'<em>white</em> cockatoo'
|
1006
|
-
)
|
1007
|
-
end
|
1008
|
-
end
|
1009
|
-
|
1010
|
-
it "should parse ambigous items" do
|
1011
|
-
items = AmbigousItems::Item.parse(fixture_file('ambigous_items.xml'), :xpath => '/ambigous/my-items')
|
1012
|
-
expect(items.map(&:name)).to eq(%w(first second third).map{|s| "My #{s} item" })
|
1013
|
-
end
|
1014
|
-
|
1015
|
-
|
1016
|
-
context Article do
|
1017
|
-
it "should parse the publish options for Article and Photo" do
|
1018
|
-
expect(@article.title).not_to be_nil
|
1019
|
-
expect(@article.text).not_to be_nil
|
1020
|
-
expect(@article.photos).not_to be_nil
|
1021
|
-
expect(@article.photos.first.title).not_to be_nil
|
1022
|
-
end
|
1023
|
-
|
1024
|
-
it "should parse the publish options for Article" do
|
1025
|
-
expect(@article.publish_options).not_to be_nil
|
1026
|
-
end
|
1027
|
-
|
1028
|
-
it "should parse the publish options for Photo" do
|
1029
|
-
expect(@article.photos.first.publish_options).not_to be_nil
|
1030
|
-
end
|
1031
|
-
|
1032
|
-
it "should only find only items at the parent level" do
|
1033
|
-
expect(@article.photos.length).to eq(1)
|
1034
|
-
end
|
1035
|
-
|
1036
|
-
before(:all) do
|
1037
|
-
@article = Article.parse(fixture_file('subclass_namespace.xml'))
|
1038
|
-
end
|
1039
|
-
|
1040
|
-
end
|
1041
|
-
|
1042
|
-
context "Namespace is missing because an optional element that uses it is not present" do
|
1043
|
-
it "should parse successfully" do
|
1044
|
-
@article = PartiallyBadArticle.parse(fixture_file('subclass_namespace.xml'))
|
1045
|
-
expect(@article).not_to be_nil
|
1046
|
-
expect(@article.title).not_to be_nil
|
1047
|
-
expect(@article.text).not_to be_nil
|
1048
|
-
expect(@article.photos).not_to be_nil
|
1049
|
-
expect(@article.photos.first.title).not_to be_nil
|
1050
|
-
end
|
1051
|
-
end
|
1052
|
-
|
1053
|
-
|
1054
|
-
describe "with limit option" do
|
1055
|
-
it "should return results with limited size: 6" do
|
1056
|
-
sizes = []
|
1057
|
-
Post.parse(fixture_file('posts.xml'), :in_groups_of => 6) do |a|
|
1058
|
-
sizes << a.size
|
1059
|
-
end
|
1060
|
-
expect(sizes).to eq([6, 6, 6, 2])
|
1061
|
-
end
|
1062
|
-
|
1063
|
-
it "should return results with limited size: 10" do
|
1064
|
-
sizes = []
|
1065
|
-
Post.parse(fixture_file('posts.xml'), :in_groups_of => 10) do |a|
|
1066
|
-
sizes << a.size
|
1067
|
-
end
|
1068
|
-
expect(sizes).to eq([10, 10])
|
1069
|
-
end
|
1070
|
-
end
|
1071
|
-
|
1072
|
-
context "when letting user set Nokogiri::XML::ParseOptions" do
|
1073
|
-
let(:default) {
|
1074
|
-
Class.new do
|
1075
|
-
include HappyMapper
|
1076
|
-
element :item, String
|
1077
|
-
end
|
1078
|
-
}
|
1079
|
-
let(:custom) {
|
1080
|
-
Class.new do
|
1081
|
-
include HappyMapper
|
1082
|
-
element :item, String
|
1083
|
-
with_nokogiri_config do |config|
|
1084
|
-
config.default_xml
|
1085
|
-
end
|
1086
|
-
end
|
1087
|
-
}
|
1088
|
-
|
1089
|
-
it 'initializes @nokogiri_config_callback to nil' do
|
1090
|
-
expect(default.nokogiri_config_callback).to be_nil
|
1091
|
-
end
|
1092
|
-
|
1093
|
-
it 'defaults to Nokogiri::XML::ParseOptions::STRICT' do
|
1094
|
-
expect { default.parse(fixture_file('set_config_options.xml')) }.to raise_error(Nokogiri::XML::SyntaxError)
|
1095
|
-
end
|
1096
|
-
|
1097
|
-
it 'accepts .on_config callback' do
|
1098
|
-
expect(custom.nokogiri_config_callback).not_to be_nil
|
1099
|
-
end
|
1100
|
-
|
1101
|
-
it 'parses according to @nokogiri_config_callback' do
|
1102
|
-
expect { custom.parse(fixture_file('set_config_options.xml')) }.to_not raise_error
|
1103
|
-
end
|
1104
|
-
|
1105
|
-
it 'can clear @nokogiri_config_callback' do
|
1106
|
-
custom.with_nokogiri_config {}
|
1107
|
-
expect { custom.parse(fixture_file('set_config_options.xml')) }.to raise_error(Nokogiri::XML::SyntaxError)
|
1108
|
-
end
|
1109
|
-
end
|
1110
|
-
|
1111
|
-
context 'xml_value' do
|
1112
|
-
it 'does not reformat the xml' do
|
1113
|
-
xml = fixture_file('unformatted_address.xml')
|
1114
|
-
address = Address.parse(xml, single: true)
|
1115
|
-
|
1116
|
-
expect(address.xml_value).to eq %{<address><street>Milchstrasse</street><housenumber>23</housenumber></address>}
|
1117
|
-
end
|
1118
|
-
end
|
1119
|
-
|
1120
|
-
context 'xml_content' do
|
1121
|
-
it 'does not reformat the xml' do
|
1122
|
-
xml = fixture_file('unformatted_address.xml')
|
1123
|
-
address = Address.parse(xml)
|
1124
|
-
|
1125
|
-
expect(address.xml_content).to eq %{<street>Milchstrasse</street><housenumber>23</housenumber>}
|
1126
|
-
end
|
1127
|
-
end
|
1128
|
-
|
1129
|
-
end
|