macasek-happymapper 0.2.5

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.
@@ -0,0 +1,115 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ module Foo
4
+ class Bar; end
5
+ end
6
+
7
+ describe HappyMapper::Item do
8
+
9
+ describe "new instance" do
10
+ before do
11
+ @item = HappyMapper::Item.new(:foo, String, :tag => 'foobar')
12
+ end
13
+
14
+ it "should accept a name" do
15
+ @item.name.should == 'foo'
16
+ end
17
+
18
+ it 'should accept a type' do
19
+ @item.type.should == String
20
+ end
21
+
22
+ it 'should accept :tag as an option' do
23
+ @item.tag.should == 'foobar'
24
+ end
25
+
26
+ it "should have a method_name" do
27
+ @item.method_name.should == 'foo'
28
+ end
29
+ end
30
+
31
+ describe "#constant" do
32
+ it "should just use type if constant" do
33
+ item = HappyMapper::Item.new(:foo, String)
34
+ item.constant.should == String
35
+ end
36
+
37
+ it "should convert string type to constant" do
38
+ item = HappyMapper::Item.new(:foo, 'String')
39
+ item.constant.should == String
40
+ end
41
+
42
+ it "should convert string with :: to constant" do
43
+ item = HappyMapper::Item.new(:foo, 'Foo::Bar')
44
+ item.constant.should == Foo::Bar
45
+ end
46
+ end
47
+
48
+ describe "#method_name" do
49
+ it "should convert dashes to underscores" do
50
+ item = HappyMapper::Item.new(:'foo-bar', String, :tag => 'foobar')
51
+ item.method_name.should == 'foo_bar'
52
+ end
53
+ end
54
+
55
+ describe "#xpath" do
56
+ it "should default to tag" do
57
+ item = HappyMapper::Item.new(:foo, String, :tag => 'foobar')
58
+ item.xpath.should == 'foobar'
59
+ end
60
+
61
+ it "should prepend with .// if options[:deep] true" do
62
+ item = HappyMapper::Item.new(:foo, String, :tag => 'foobar', :deep => true)
63
+ item.xpath.should == './/foobar'
64
+ end
65
+
66
+ it "should prepend namespace if namespace exists" do
67
+ item = HappyMapper::Item.new(:foo, String, :tag => 'foobar')
68
+ item.namespace = 'v2'
69
+ item.xpath.should == 'v2:foobar'
70
+ end
71
+ end
72
+
73
+ describe "typecasting" do
74
+ it "should work with Strings" do
75
+ item = HappyMapper::Item.new(:foo, String)
76
+ [21, '21'].each do |a|
77
+ item.typecast(a).should == '21'
78
+ end
79
+ end
80
+
81
+ it "should work with Integers" do
82
+ item = HappyMapper::Item.new(:foo, Integer)
83
+ [21, 21.0, '21'].each do |a|
84
+ item.typecast(a).should == 21
85
+ end
86
+ end
87
+
88
+ it "should work with Floats" do
89
+ item = HappyMapper::Item.new(:foo, Float)
90
+ [21, 21.0, '21'].each do |a|
91
+ item.typecast(a).should == 21.0
92
+ end
93
+ end
94
+
95
+ it "should work with Times" do
96
+ item = HappyMapper::Item.new(:foo, Time)
97
+ item.typecast('2000-01-01 01:01:01.123456').should == Time.local(2000, 1, 1, 1, 1, 1, 123456)
98
+ end
99
+
100
+ it "should work with Dates" do
101
+ item = HappyMapper::Item.new(:foo, Date)
102
+ item.typecast('2000-01-01').should == Date.new(2000, 1, 1)
103
+ end
104
+
105
+ it "should work with DateTimes" do
106
+ item = HappyMapper::Item.new(:foo, DateTime)
107
+ item.typecast('2000-01-01 00:00:00').should == DateTime.new(2000, 1, 1, 0, 0, 0)
108
+ end
109
+
110
+ it "should work with Boolean" do
111
+ item = HappyMapper::Item.new(:foo, Boolean)
112
+ item.typecast('false').should == false
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,581 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+ require 'pp'
3
+ require 'uri'
4
+
5
+ module Analytics
6
+ class Property
7
+ include HappyMapper
8
+
9
+ tag 'property'
10
+ namespace 'dxp'
11
+ attribute :name, String
12
+ attribute :value, String
13
+ end
14
+
15
+ class Entry
16
+ include HappyMapper
17
+
18
+ tag 'entry'
19
+ element :id, String
20
+ element :updated, DateTime
21
+ element :title, String
22
+ element :table_id, String, :namespace => 'dxp', :tag => 'tableId'
23
+ has_many :properties, Property
24
+ end
25
+
26
+ class Feed
27
+ include HappyMapper
28
+
29
+ tag 'feed'
30
+ element :id, String
31
+ element :updated, DateTime
32
+ element :title, String
33
+ has_many :entries, Entry
34
+ end
35
+ end
36
+
37
+ class Feature
38
+ include HappyMapper
39
+ element :name, String, :tag => '.|.//text()'
40
+ end
41
+
42
+ class FeatureBullet
43
+ include HappyMapper
44
+
45
+ tag 'features_bullets'
46
+ has_many :features, Feature
47
+ element :bug, String
48
+ end
49
+
50
+ class Product
51
+ include HappyMapper
52
+
53
+ element :title, String
54
+ has_one :feature_bullets, FeatureBullet
55
+ end
56
+
57
+ module FamilySearch
58
+ class Person
59
+ include HappyMapper
60
+
61
+ attribute :version, String
62
+ attribute :modified, Time
63
+ attribute :id, String
64
+ end
65
+
66
+ class Persons
67
+ include HappyMapper
68
+ has_many :person, Person
69
+ end
70
+
71
+ class FamilyTree
72
+ include HappyMapper
73
+
74
+ tag 'familytree'
75
+ attribute :version, String
76
+ attribute :status_message, String, :tag => 'statusMessage'
77
+ attribute :status_code, String, :tag => 'statusCode'
78
+ has_one :persons, Persons
79
+ end
80
+ end
81
+
82
+ module FedEx
83
+ class Address
84
+ include HappyMapper
85
+
86
+ tag 'Address'
87
+ namespace 'v2'
88
+ element :city, String, :tag => 'City'
89
+ element :state, String, :tag => 'StateOrProvinceCode'
90
+ element :zip, String, :tag => 'PostalCode'
91
+ element :countrycode, String, :tag => 'CountryCode'
92
+ element :residential, Boolean, :tag => 'Residential'
93
+ end
94
+
95
+ class Event
96
+ include HappyMapper
97
+
98
+ tag 'Events'
99
+ namespace 'v2'
100
+ element :timestamp, String, :tag => 'Timestamp'
101
+ element :eventtype, String, :tag => 'EventType'
102
+ element :eventdescription, String, :tag => 'EventDescription'
103
+ has_one :address, Address
104
+ end
105
+
106
+ class PackageWeight
107
+ include HappyMapper
108
+
109
+ tag 'PackageWeight'
110
+ namespace 'v2'
111
+ element :units, String, :tag => 'Units'
112
+ element :value, Integer, :tag => 'Value'
113
+ end
114
+
115
+ class TrackDetails
116
+ include HappyMapper
117
+
118
+ tag 'TrackDetails'
119
+ namespace 'v2'
120
+ element :tracking_number, String, :tag => 'TrackingNumber'
121
+ element :status_code, String, :tag => 'StatusCode'
122
+ element :status_desc, String, :tag => 'StatusDescription'
123
+ element :carrier_code, String, :tag => 'CarrierCode'
124
+ element :service_info, String, :tag => 'ServiceInfo'
125
+ has_one :weight, PackageWeight, :tag => 'PackageWeight'
126
+ element :est_delivery, String, :tag => 'EstimatedDeliveryTimestamp'
127
+ has_many :events, Event
128
+ end
129
+
130
+ class Notification
131
+ include HappyMapper
132
+
133
+ tag 'Notifications'
134
+ namespace 'v2'
135
+ element :severity, String, :tag => 'Severity'
136
+ element :source, String, :tag => 'Source'
137
+ element :code, Integer, :tag => 'Code'
138
+ element :message, String, :tag => 'Message'
139
+ element :localized_message, String, :tag => 'LocalizedMessage'
140
+ end
141
+
142
+ class TransactionDetail
143
+ include HappyMapper
144
+
145
+ tag 'TransactionDetail'
146
+ namespace 'v2'
147
+ element :cust_tran_id, String, :tag => 'CustomerTransactionId'
148
+ end
149
+
150
+ class TrackReply
151
+ include HappyMapper
152
+
153
+ tag 'TrackReply'
154
+ namespace 'v2'
155
+ element :highest_severity, String, :tag => 'HighestSeverity'
156
+ element :more_data, Boolean, :tag => 'MoreData'
157
+ has_many :notifications, Notification, :tag => 'Notifications'
158
+ has_many :trackdetails, TrackDetails, :tag => 'TrackDetails'
159
+ has_one :tran_detail, TransactionDetail, :tab => 'TransactionDetail'
160
+ end
161
+ end
162
+
163
+ class Place
164
+ include HappyMapper
165
+ element :name, String
166
+ end
167
+
168
+ class Radar
169
+ include HappyMapper
170
+ has_many :places, Place
171
+ end
172
+
173
+ class Post
174
+ include HappyMapper
175
+
176
+ attribute :href, String
177
+ attribute :hash, String
178
+ attribute :description, String
179
+ attribute :tag, String
180
+ attribute :time, Time
181
+ attribute :others, Integer
182
+ attribute :extended, String
183
+ end
184
+
185
+ class User
186
+ include HappyMapper
187
+
188
+ element :id, Integer
189
+ element :name, String
190
+ element :screen_name, String
191
+ element :location, String
192
+ element :description, String
193
+ element :profile_image_url, String
194
+ element :url, String
195
+ element :protected, Boolean
196
+ element :followers_count, Integer
197
+ end
198
+
199
+ class Status
200
+ include HappyMapper
201
+
202
+ element :id, Integer
203
+ element :text, String
204
+ element :created_at, Time
205
+ element :source, String
206
+ element :truncated, Boolean
207
+ element :in_reply_to_status_id, Integer
208
+ element :in_reply_to_user_id, Integer
209
+ element :favorited, Boolean
210
+ element :non_existent, String, :tag => 'dummy', :namespace => 'fake'
211
+ has_one :user, User
212
+ end
213
+
214
+ class CurrentWeather
215
+ include HappyMapper
216
+
217
+ tag 'ob'
218
+ namespace 'aws'
219
+ element :temperature, Integer, :tag => 'temp'
220
+ element :feels_like, Integer, :tag => 'feels-like'
221
+ element :current_condition, String, :tag => 'current-condition', :attributes => {:icon => String}
222
+ end
223
+
224
+ class Address
225
+ include HappyMapper
226
+
227
+ tag 'address'
228
+ element :street, String
229
+ element :postcode, String
230
+ element :housenumber, String
231
+ element :city, String
232
+ element :country, String
233
+ end
234
+
235
+ # for type coercion
236
+ class ProductGroup < String; end
237
+
238
+ module PITA
239
+ class Item
240
+ include HappyMapper
241
+
242
+ tag 'Item' # if you put class in module you need tag
243
+ element :asin, String, :tag => 'ASIN'
244
+ element :detail_page_url, URI, :tag => 'DetailPageURL', :parser => :parse
245
+ element :manufacturer, String, :tag => 'Manufacturer', :deep => true
246
+ element :point, String, :tag => 'point', :namespace => 'georss'
247
+ element :product_group, ProductGroup, :tag => 'ProductGroup', :deep => true, :parser => :new, :raw => true
248
+ end
249
+
250
+ class Items
251
+ include HappyMapper
252
+
253
+ tag 'Items' # if you put class in module you need tag
254
+ element :total_results, Integer, :tag => 'TotalResults'
255
+ element :total_pages, Integer, :tag => 'TotalPages'
256
+ has_many :items, Item
257
+ end
258
+ end
259
+
260
+ module GitHub
261
+ class Commit
262
+ include HappyMapper
263
+
264
+ tag "commit"
265
+ element :url, String
266
+ element :tree, String
267
+ element :message, String
268
+ element :id, String
269
+ element :'committed-date', Date
270
+ end
271
+ end
272
+
273
+ describe HappyMapper do
274
+
275
+ describe "being included into another class" do
276
+ before do
277
+ @klass = Class.new do
278
+ include HappyMapper
279
+
280
+ def self.to_s
281
+ 'Foo'
282
+ end
283
+ end
284
+ end
285
+
286
+ it "should set attributes to an array" do
287
+ @klass.attributes.should == []
288
+ end
289
+
290
+ it "should set @elements to a hash" do
291
+ @klass.elements.should == []
292
+ end
293
+
294
+ it "should allow adding an attribute" do
295
+ lambda {
296
+ @klass.attribute :name, String
297
+ }.should change(@klass, :attributes)
298
+ end
299
+
300
+ it "should allow adding an attribute containing a dash" do
301
+ lambda {
302
+ @klass.attribute :'bar-baz', String
303
+ }.should change(@klass, :attributes)
304
+ end
305
+
306
+ it "should be able to get all attributes in array" do
307
+ @klass.attribute :name, String
308
+ @klass.attributes.size.should == 1
309
+ end
310
+
311
+ it "should allow adding an element" do
312
+ lambda {
313
+ @klass.element :name, String
314
+ }.should change(@klass, :elements)
315
+ end
316
+
317
+ it "should allow adding an element containing a dash" do
318
+ lambda {
319
+ @klass.element :'bar-baz', String
320
+ }.should change(@klass, :elements)
321
+
322
+ end
323
+
324
+ it "should be able to get all elements in array" do
325
+ @klass.element(:name, String)
326
+ @klass.elements.size.should == 1
327
+ end
328
+
329
+ it "should allow has one association" do
330
+ @klass.has_one(:user, User)
331
+ element = @klass.elements.first
332
+ element.name.should == 'user'
333
+ element.type.should == User
334
+ element.options[:single] = true
335
+ end
336
+
337
+ it "should allow has many association" do
338
+ @klass.has_many(:users, User)
339
+ element = @klass.elements.first
340
+ element.name.should == 'users'
341
+ element.type.should == User
342
+ element.options[:single] = false
343
+ end
344
+
345
+ it "should default tag name to lowercase class" do
346
+ @klass.tag_name.should == 'foo'
347
+ end
348
+
349
+ it "should default tag name of class in modules to the last constant lowercase" do
350
+ module Bar; class Baz; include HappyMapper; end; end
351
+ Bar::Baz.tag_name.should == 'baz'
352
+ end
353
+
354
+ it "should allow setting tag name" do
355
+ @klass.tag('FooBar')
356
+ @klass.tag_name.should == 'FooBar'
357
+ end
358
+
359
+ it "should allow setting a namespace" do
360
+ @klass.namespace(namespace = "foo")
361
+ @klass.namespace.should == namespace
362
+ end
363
+
364
+ it "should provide #parse" do
365
+ @klass.should respond_to(:parse)
366
+ end
367
+ end
368
+
369
+ describe "#attributes" do
370
+ it "should only return attributes for the current class" do
371
+ Post.attributes.size.should == 7
372
+ Status.attributes.size.should == 0
373
+ end
374
+ end
375
+
376
+ describe "#elements" do
377
+ it "should only return elements for the current class" do
378
+ Post.elements.size.should == 0
379
+ Status.elements.size.should == 10
380
+ end
381
+ end
382
+
383
+ it "should parse xml attributes into ruby objects" do
384
+ posts = Post.parse(fixture_file('posts.xml'))
385
+ posts.size.should == 20
386
+ first = posts.first
387
+ first.href.should == 'http://roxml.rubyforge.org/'
388
+ first.hash.should == '19bba2ab667be03a19f67fb67dc56917'
389
+ first.description.should == 'ROXML - Ruby Object to XML Mapping Library'
390
+ first.tag.should == 'ruby xml gems mapping'
391
+ first.time.should == Time.utc(2008, 8, 9, 5, 24, 20)
392
+ first.others.should == 56
393
+ first.extended.should == '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.'
394
+ end
395
+
396
+ it "should parse xml elements to ruby objcts" do
397
+ statuses = Status.parse(fixture_file('statuses.xml'))
398
+ statuses.size.should == 20
399
+ first = statuses.first
400
+ first.id.should == 882281424
401
+ first.created_at.should == Time.utc(2008, 8, 9, 5, 38, 12)
402
+ first.source.should == 'web'
403
+ first.truncated.should be_false
404
+ first.in_reply_to_status_id.should == 1234
405
+ first.in_reply_to_user_id.should == 12345
406
+ first.favorited.should be_false
407
+ first.user.id.should == 4243
408
+ first.user.name.should == 'John Nunemaker'
409
+ first.user.screen_name.should == 'jnunemaker'
410
+ first.user.location.should == 'Mishawaka, IN, US'
411
+ first.user.description.should == 'Loves his wife, ruby, notre dame football and iu basketball'
412
+ first.user.profile_image_url.should == 'http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg'
413
+ first.user.url.should == 'http://addictedtonew.com'
414
+ first.user.protected.should be_false
415
+ first.user.followers_count.should == 486
416
+ end
417
+
418
+ it "should parse xml containing the desired element as root node" do
419
+ address = Address.parse(fixture_file('address.xml'), :single => true)
420
+ address.street.should == 'Milchstrasse'
421
+ address.postcode.should == '26131'
422
+ address.housenumber.should == '23'
423
+ address.city.should == 'Oldenburg'
424
+ address.country.should == 'Germany'
425
+ end
426
+
427
+ it "should parse xml with default namespace (amazon)" do
428
+ file_contents = fixture_file('pita.xml')
429
+ items = PITA::Items.parse(file_contents, :single => true)
430
+ items.total_results.should == 22
431
+ items.total_pages.should == 3
432
+ first = items.items[0]
433
+ second = items.items[1]
434
+ first.asin.should == '0321480791'
435
+ first.point.should == '38.5351715088 -121.7948684692'
436
+ first.detail_page_url.should be_a_kind_of(URI)
437
+ first.detail_page_url.to_s.should == 'http://www.amazon.com/gp/redirect.html%3FASIN=0321480791%26tag=ws%26lcode=xm2%26cID=2025%26ccmID=165953%26location=/o/ASIN/0321480791%253FSubscriptionId=dontbeaswoosh'
438
+ first.manufacturer.should == 'Addison-Wesley Professional'
439
+ first.product_group.should == '<ProductGroup>Book</ProductGroup>'
440
+ second.asin.should == '047022388X'
441
+ second.manufacturer.should == 'Wrox'
442
+ end
443
+
444
+ it "should parse xml that has attributes of elements" do
445
+ items = CurrentWeather.parse(fixture_file('current_weather.xml'))
446
+ first = items[0]
447
+ first.temperature.should == 51
448
+ first.feels_like.should == 51
449
+ first.current_condition.should == 'Sunny'
450
+ first.current_condition.icon.should == 'http://deskwx.weatherbug.com/images/Forecast/icons/cond007.gif'
451
+ end
452
+
453
+ it "should parse xml with nested elements" do
454
+ radars = Radar.parse(fixture_file('radar.xml'))
455
+ first = radars[0]
456
+ first.places.size.should == 1
457
+ first.places[0].name.should == 'Store'
458
+ second = radars[1]
459
+ second.places.size.should == 0
460
+ third = radars[2]
461
+ third.places.size.should == 2
462
+ third.places[0].name.should == 'Work'
463
+ third.places[1].name.should == 'Home'
464
+ end
465
+
466
+ it "should parse xml that has elements with dashes" do
467
+ commit = GitHub::Commit.parse(fixture_file('commit.xml'))
468
+ commit.message.should == "move commands.rb and helpers.rb into commands/ dir"
469
+ commit.url.should == "http://github.com/defunkt/github-gem/commit/c26d4ce9807ecf57d3f9eefe19ae64e75bcaaa8b"
470
+ commit.id.should == "c26d4ce9807ecf57d3f9eefe19ae64e75bcaaa8b"
471
+ commit.committed_date.should == Date.parse("2008-03-02T16:45:41-08:00")
472
+ commit.tree.should == "28a1a1ca3e663d35ba8bf07d3f1781af71359b76"
473
+ end
474
+
475
+ it "should parse xml with no namespace" do
476
+ product = Product.parse(fixture_file('product_no_namespace.xml'), :single => true)
477
+ product.title.should == "A Title"
478
+ product.feature_bullets.bug.should == 'This is a bug'
479
+ product.feature_bullets.features.size.should == 2
480
+ product.feature_bullets.features[0].name.should == 'This is feature text 1'
481
+ product.feature_bullets.features[1].name.should == 'This is feature text 2'
482
+ end
483
+
484
+ it "should parse xml with default namespace" do
485
+ product = Product.parse(fixture_file('product_default_namespace.xml'), :single => true)
486
+ product.title.should == "A Title"
487
+ product.feature_bullets.bug.should == 'This is a bug'
488
+ product.feature_bullets.features.size.should == 2
489
+ product.feature_bullets.features[0].name.should == 'This is feature text 1'
490
+ product.feature_bullets.features[1].name.should == 'This is feature text 2'
491
+ end
492
+
493
+ it "should parse xml with single namespace" do
494
+ product = Product.parse(fixture_file('product_single_namespace.xml'), :single => true)
495
+ product.title.should == "A Title"
496
+ product.feature_bullets.bug.should == 'This is a bug'
497
+ product.feature_bullets.features.size.should == 2
498
+ product.feature_bullets.features[0].name.should == 'This is feature text 1'
499
+ product.feature_bullets.features[1].name.should == 'This is feature text 2'
500
+ end
501
+
502
+ it "should parse xml with multiple namespaces" do
503
+ track = FedEx::TrackReply.parse(fixture_file('multiple_namespaces.xml'))
504
+ track.highest_severity.should == 'SUCCESS'
505
+ track.more_data.should be_false
506
+ notification = track.notifications.first
507
+ notification.code.should == 0
508
+ notification.localized_message.should == 'Request was successfully processed.'
509
+ notification.message.should == 'Request was successfully processed.'
510
+ notification.severity.should == 'SUCCESS'
511
+ notification.source.should == 'trck'
512
+ detail = track.trackdetails.first
513
+ detail.carrier_code.should == 'FDXG'
514
+ detail.est_delivery.should == '2009-01-02T00:00:00'
515
+ detail.service_info.should == 'Ground-Package Returns Program-Domestic'
516
+ detail.status_code.should == 'OD'
517
+ detail.status_desc.should == 'On FedEx vehicle for delivery'
518
+ detail.tracking_number.should == '9611018034267800045212'
519
+ detail.weight.units.should == 'LB'
520
+ detail.weight.value.should == 2
521
+ events = detail.events
522
+ events.size.should == 10
523
+ first_event = events[0]
524
+ first_event.eventdescription.should == 'On FedEx vehicle for delivery'
525
+ first_event.eventtype.should == 'OD'
526
+ first_event.timestamp.should == '2009-01-02T06:00:00'
527
+ first_event.address.city.should == 'WICHITA'
528
+ first_event.address.countrycode.should == 'US'
529
+ first_event.address.residential.should be_false
530
+ first_event.address.state.should == 'KS'
531
+ first_event.address.zip.should == '67226'
532
+ last_event = events[-1]
533
+ last_event.eventdescription.should == 'In FedEx possession'
534
+ last_event.eventtype.should == 'IP'
535
+ last_event.timestamp.should == '2008-12-27T09:40:00'
536
+ last_event.address.city.should == 'LONGWOOD'
537
+ last_event.address.countrycode.should == 'US'
538
+ last_event.address.residential.should be_false
539
+ last_event.address.state.should == 'FL'
540
+ last_event.address.zip.should == '327506398'
541
+ track.tran_detail.cust_tran_id.should == '20090102-111321'
542
+ end
543
+
544
+ it "should be able to parse google analytics api xml" do
545
+ data = Analytics::Feed.parse(fixture_file('analytics.xml'))
546
+ data.id.should == 'http://www.google.com/analytics/feeds/accounts/nunemaker@gmail.com'
547
+ data.entries.size.should == 4
548
+
549
+ entry = data.entries[0]
550
+ entry.title.should == 'addictedtonew.com'
551
+ entry.properties.size.should == 4
552
+
553
+ property = entry.properties[0]
554
+ property.name.should == 'ga:accountId'
555
+ property.value.should == '85301'
556
+ end
557
+
558
+ it "should allow instantiating with a string" do
559
+ module StringFoo
560
+ class Bar
561
+ include HappyMapper
562
+ has_many :things, 'StringFoo::Thing'
563
+ end
564
+
565
+ class Thing
566
+ include HappyMapper
567
+ end
568
+ end
569
+ end
570
+
571
+ xit "should parse family search xml" do
572
+ tree = FamilySearch::FamilyTree.parse(fixture_file('family_tree.xml'))
573
+ tree.version.should == '1.0.20071213.942'
574
+ tree.status_message.should == 'OK'
575
+ tree.status_code.should == '200'
576
+ # tree.people.size.should == 1
577
+ # tree.people.first.version.should == '1199378491000'
578
+ # tree.people.first.modified.should == Time.utc(2008, 1, 3, 16, 41, 31) # 2008-01-03T09:41:31-07:00
579
+ # tree.people.first.id.should == 'KWQS-BBQ'
580
+ end
581
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,13 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+
9
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'happymapper')
10
+
11
+ def fixture_file(filename)
12
+ File.read(File.dirname(__FILE__) + "/fixtures/#{filename}")
13
+ end