ratom-ssl 0.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 (49) hide show
  1. data/.gitignore +4 -0
  2. data/History.txt +118 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +295 -0
  5. data/Rakefile +55 -0
  6. data/VERSION.yml +5 -0
  7. data/lib/atom/configuration.rb +24 -0
  8. data/lib/atom/pub.rb +253 -0
  9. data/lib/atom/version.rb +7 -0
  10. data/lib/atom/xml/parser.rb +376 -0
  11. data/lib/atom.rb +771 -0
  12. data/ratom-ssl.gemspec +98 -0
  13. data/spec/app/member_entry.atom +31 -0
  14. data/spec/app/service.xml +36 -0
  15. data/spec/atom/pub_spec.rb +504 -0
  16. data/spec/atom_spec.rb +1336 -0
  17. data/spec/conformance/baseuri.atom +19 -0
  18. data/spec/conformance/divtest.atom +32 -0
  19. data/spec/conformance/linktests.xml +103 -0
  20. data/spec/conformance/nondefaultnamespace-baseline.atom +25 -0
  21. data/spec/conformance/nondefaultnamespace-xhtml.atom +25 -0
  22. data/spec/conformance/nondefaultnamespace.atom +25 -0
  23. data/spec/conformance/ordertest.xml +112 -0
  24. data/spec/conformance/title/html-cdata.atom +22 -0
  25. data/spec/conformance/title/html-entity.atom +22 -0
  26. data/spec/conformance/title/html-ncr.atom +22 -0
  27. data/spec/conformance/title/text-cdata.atom +22 -0
  28. data/spec/conformance/title/text-entity.atom +21 -0
  29. data/spec/conformance/title/text-ncr.atom +21 -0
  30. data/spec/conformance/title/xhtml-entity.atom +21 -0
  31. data/spec/conformance/title/xhtml-ncr.atom +21 -0
  32. data/spec/conformance/unknown-namespace.atom +25 -0
  33. data/spec/conformance/xmlbase.atom +133 -0
  34. data/spec/fixtures/complex_single_entry.atom +45 -0
  35. data/spec/fixtures/created_entry.atom +31 -0
  36. data/spec/fixtures/entry.atom +30 -0
  37. data/spec/fixtures/entry_with_custom_extensions.atom +7 -0
  38. data/spec/fixtures/entry_with_simple_extensions.atom +30 -0
  39. data/spec/fixtures/entry_with_single_custom_extension.atom +6 -0
  40. data/spec/fixtures/multiple_entry.atom +0 -0
  41. data/spec/fixtures/simple_single_entry.atom +21 -0
  42. data/spec/fixtures/with_stylesheet.atom +8 -0
  43. data/spec/paging/first_paged_feed.atom +21 -0
  44. data/spec/paging/last_paged_feed.atom +21 -0
  45. data/spec/paging/middle_paged_feed.atom +22 -0
  46. data/spec/property.rb +31 -0
  47. data/spec/spec.opts +1 -0
  48. data/spec/spec_helper.rb +43 -0
  49. metadata +140 -0
data/spec/atom_spec.rb ADDED
@@ -0,0 +1,1336 @@
1
+ # Copyright (c) 2008 The Kaphan Foundation
2
+ #
3
+ # For licensing information see LICENSE.
4
+ #
5
+ # Please visit http://www.peerworks.org/contact for further information.
6
+ #
7
+
8
+ require File.dirname(__FILE__) + '/spec_helper.rb'
9
+ require 'net/http'
10
+ require 'time'
11
+ require 'spec/property'
12
+
13
+ shared_examples_for 'simple_single_entry.atom attributes' do
14
+ it "should parse title" do
15
+ @feed.title.should == 'Example Feed'
16
+ end
17
+
18
+ it "should parse updated" do
19
+ @feed.updated.should == Time.parse('2003-12-13T18:30:02Z')
20
+ end
21
+
22
+ it "should parse id" do
23
+ @feed.id.should == 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6'
24
+ end
25
+
26
+ it "should have an entries array" do
27
+ @feed.entries.should be_an_instance_of(Array)
28
+ end
29
+
30
+ it "should have one element in the entries array" do
31
+ @feed.entries.size.should == 1
32
+ end
33
+
34
+ it "should have an alternate" do
35
+ @feed.alternate.should_not be_nil
36
+ end
37
+
38
+ it "should have an Atom::Link as the alternate" do
39
+ @feed.alternate.should be_an_instance_of(Atom::Link)
40
+ end
41
+
42
+ it "should have the correct href in the alternate" do
43
+ @feed.alternate.href.should == 'http://example.org/'
44
+ end
45
+
46
+ it "should have 1 author" do
47
+ @feed.should have(1).authors
48
+ end
49
+
50
+ it "should have 'John Doe' as the author's name" do
51
+ @feed.authors.first.name.should == "John Doe"
52
+ end
53
+
54
+ it "should parse title" do
55
+ @entry.title.should == 'Atom-Powered Robots Run Amok'
56
+ end
57
+
58
+ it "should have an alternate" do
59
+ @entry.alternate.should_not be_nil
60
+ end
61
+
62
+ it "should have an Atom::Link as the alternate" do
63
+ @entry.alternate.should be_an_instance_of(Atom::Link)
64
+ end
65
+
66
+ it "should have the correct href on the alternate" do
67
+ @entry.alternate.href.should == 'http://example.org/2003/12/13/atom03'
68
+ end
69
+
70
+ it "should parse id" do
71
+ @entry.id.should == 'urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a'
72
+ end
73
+
74
+ it "should parse updated" do
75
+ @entry.updated.should == Time.parse('2003-12-13T18:30:02Z')
76
+ end
77
+
78
+ it "should parse summary" do
79
+ @entry.summary.should == 'Some text.'
80
+ end
81
+
82
+ it "should parse content" do
83
+ @entry.content.should == 'This <em>is</em> html.'
84
+ end
85
+
86
+ it "should parse content type" do
87
+ @entry.content.type.should == 'html'
88
+ end
89
+ end
90
+
91
+ describe Atom do
92
+ describe "Atom::Feed.load_feed" do
93
+ it "should accept an IO" do
94
+ lambda { Atom::Feed.load_feed(File.open('spec/fixtures/simple_single_entry.atom')) }.should_not raise_error
95
+ end
96
+
97
+ it "should raise ArgumentError with something other than IO or URI" do
98
+ lambda { Atom::Feed.load_feed(nil) }.should raise_error(ArgumentError)
99
+ end
100
+
101
+ it "should accept a String" do
102
+ Atom::Feed.load_feed(File.read('spec/fixtures/simple_single_entry.atom')).should be_an_instance_of(Atom::Feed)
103
+ end
104
+
105
+ it "should accept a URI" do
106
+ uri = URI.parse('http://example.com/feed.atom')
107
+ response = Net::HTTPSuccess.new(nil, nil, nil)
108
+ response.stub!(:body).and_return(File.read('spec/fixtures/simple_single_entry.atom'))
109
+ mock_http_get(uri, response)
110
+
111
+ Atom::Feed.load_feed(uri).should be_an_instance_of(Atom::Feed)
112
+ end
113
+
114
+ it "should accept a URI with query parameters" do
115
+ uri = URI.parse('http://example.com/feed.atom?page=2')
116
+ response = Net::HTTPSuccess.new(nil, nil, nil)
117
+ response.stub!(:body).and_return(File.read('spec/fixtures/simple_single_entry.atom'))
118
+ mock_http_get(uri, response)
119
+
120
+ Atom::Feed.load_feed(uri).should be_an_instance_of(Atom::Feed)
121
+ end
122
+
123
+ it "should raise ArgumentError with non-http uri" do
124
+ uri = URI.parse('file:/tmp')
125
+ lambda { Atom::Feed.load_feed(uri) }.should raise_error(ArgumentError)
126
+ end
127
+
128
+ it "should return an Atom::Feed" do
129
+ feed = Atom::Feed.load_feed(File.open('spec/fixtures/simple_single_entry.atom'))
130
+ feed.should be_an_instance_of(Atom::Feed)
131
+ end
132
+
133
+ it "should not raise an error with a String and basic-auth credentials" do
134
+ lambda { Atom::Feed.load_feed(File.read('spec/fixtures/simple_single_entry.atom'), :user => 'user', :pass => 'pass') }.should_not raise_error
135
+ end
136
+
137
+ it "should not raise an error with a URI with basic-auth credentials" do
138
+ uri = URI.parse('http://example.com/feed.atom')
139
+
140
+ response = Net::HTTPSuccess.new(nil, nil, nil)
141
+ response.stub!(:body).and_return(File.read('spec/fixtures/simple_single_entry.atom'))
142
+ mock_http_get(uri, response, 'user', 'pass')
143
+
144
+ lambda { Atom::Feed.load_feed(uri, :user => 'user', :pass => 'pass') }.should_not raise_error
145
+ end
146
+ end
147
+
148
+ describe 'Atom::Entry.load_entry' do
149
+ it "should accept an IO" do
150
+ Atom::Entry.load_entry(File.open('spec/fixtures/entry.atom')).should be_an_instance_of(Atom::Entry)
151
+ end
152
+
153
+ it "should accept a URI" do
154
+ uri = URI.parse('http://example.org/entry.atom')
155
+ response = Net::HTTPSuccess.new(nil, nil, nil)
156
+ response.stub!(:body).and_return(File.read('spec/fixtures/entry.atom'))
157
+ mock_http_get(uri, response)
158
+
159
+ Atom::Entry.load_entry(uri).should be_an_instance_of(Atom::Entry)
160
+ end
161
+
162
+ it "should accept a String" do
163
+ Atom::Entry.load_entry(File.read('spec/fixtures/entry.atom')).should be_an_instance_of(Atom::Entry)
164
+ end
165
+
166
+ it "should raise ArgumentError with something other than IO, String or URI" do
167
+ lambda { Atom::Entry.load_entry(nil) }.should raise_error(ArgumentError)
168
+ end
169
+
170
+ it "should raise ArgumentError with non-http uri" do
171
+ lambda { Atom::Entry.load_entry(URI.parse('file:/tmp')) }.should raise_error(ArgumentError)
172
+ end
173
+ end
174
+
175
+ describe 'SimpleSingleFeed' do
176
+ before(:all) do
177
+ @feed = Atom::Feed.load_feed(File.open('spec/fixtures/simple_single_entry.atom'))
178
+ @entry = @feed.entries.first
179
+ end
180
+
181
+ it_should_behave_like "simple_single_entry.atom attributes"
182
+ end
183
+
184
+ describe 'FeedWithStyleSheet' do
185
+ it "should load without failure" do
186
+ lambda { feed = Atom::Feed.load_feed(File.open('spec/fixtures/with_stylesheet.atom')) }.should_not raise_error
187
+ end
188
+ end
189
+
190
+ describe 'ComplexFeed' do
191
+ before(:all) do
192
+ @feed = Atom::Feed.load_feed(File.open('spec/fixtures/complex_single_entry.atom'))
193
+ end
194
+
195
+ describe Atom::Feed do
196
+ it "should have a title" do
197
+ @feed.title.should == 'dive into mark'
198
+ end
199
+
200
+ it "should have type on the title" do
201
+ @feed.title.type.should == 'text'
202
+ end
203
+
204
+ it "should have a subtitle" do
205
+ @feed.subtitle.should == 'A <em>lot</em> of effort went into making this effortless'
206
+ end
207
+
208
+ it "should have a type for the subtitle" do
209
+ @feed.subtitle.type.should == 'html'
210
+ end
211
+
212
+ it "should have an updated date" do
213
+ @feed.updated.should == Time.parse('2005-07-31T12:29:29Z')
214
+ end
215
+
216
+ it "should have an id" do
217
+ @feed.id.should == 'tag:example.org,2003:3'
218
+ end
219
+
220
+ it "should have 2 links" do
221
+ @feed.should have(2).links
222
+ end
223
+
224
+ it "should have an alternate link" do
225
+ @feed.alternate.should_not be_nil
226
+ end
227
+
228
+ it "should have the right url for the alternate" do
229
+ @feed.alternate.to_s.should == 'http://example.org/'
230
+ end
231
+
232
+ it "should have a self link" do
233
+ @feed.self.should_not be_nil
234
+ end
235
+
236
+ it "should have the right url for self" do
237
+ @feed.self.to_s.should == 'http://example.org/feed.atom'
238
+ end
239
+
240
+ it "should have rights" do
241
+ @feed.rights.should == 'Copyright (c) 2003, Mark Pilgrim'
242
+ end
243
+
244
+ it "should have a generator" do
245
+ @feed.generator.should_not be_nil
246
+ end
247
+
248
+ it "should have a generator uri" do
249
+ @feed.generator.uri.should == 'http://www.example.com/'
250
+ end
251
+
252
+ it "should have a generator version" do
253
+ @feed.generator.version.should == '1.0'
254
+ end
255
+
256
+ it "should have a generator name" do
257
+ @feed.generator.name.should == 'Example Toolkit'
258
+ end
259
+
260
+ it "should have an entry" do
261
+ @feed.should have(1).entries
262
+ end
263
+
264
+ it "should have a category" do
265
+ @feed.should have(1).categories
266
+ end
267
+ end
268
+
269
+ describe Atom::Entry do
270
+ before(:each) do
271
+ @entry = @feed.entries.first
272
+ end
273
+
274
+ it "should have a title" do
275
+ @entry.title.should == 'Atom draft-07 snapshot'
276
+ end
277
+
278
+ it "should have an id" do
279
+ @entry.id.should == 'tag:example.org,2003:3.2397'
280
+ end
281
+
282
+ it "should have an updated date" do
283
+ @entry.updated.should == Time.parse('2005-07-31T12:29:29Z')
284
+ end
285
+
286
+ it "should have a published date" do
287
+ @entry.published.should == Time.parse('2003-12-13T08:29:29-04:00')
288
+ end
289
+
290
+ it "should have an author" do
291
+ @entry.should have(1).authors
292
+ end
293
+
294
+ it "should have two links" do
295
+ @entry.should have(2).links
296
+ end
297
+
298
+ it "should have one alternate link" do
299
+ @entry.should have(1).alternates
300
+ end
301
+
302
+ it "should have one enclosure link" do
303
+ @entry.should have(1).enclosures
304
+ end
305
+
306
+ it "should have 2 contributors" do
307
+ @entry.should have(2).contributors
308
+ end
309
+
310
+ it "should have names for the contributors" do
311
+ @entry.contributors[0].name.should == 'Sam Ruby'
312
+ @entry.contributors[1].name.should == 'Joe Gregorio'
313
+ end
314
+
315
+ it "should have content" do
316
+ @entry.content.should_not be_nil
317
+ end
318
+
319
+ it "should have 2 categories" do
320
+ @entry.should have(2).categories
321
+ end
322
+ end
323
+
324
+ describe Atom::Category do
325
+ describe 'atom category' do
326
+ before(:each) do
327
+ @category = @feed.entries.first.categories.first
328
+ end
329
+
330
+ it "should have a term" do
331
+ @category.term.should == "atom"
332
+ end
333
+
334
+ it "should have a scheme" do
335
+ @category.scheme.should == "http://example.org"
336
+ end
337
+
338
+ it "should have a label" do
339
+ @category.label.should == "Atom"
340
+ end
341
+ end
342
+
343
+ describe 'draft category' do
344
+ before(:each) do
345
+ @category = @feed.entries.first.categories.last
346
+ end
347
+
348
+ it "should have a term" do
349
+ @category.term.should == "drafts"
350
+ end
351
+
352
+ it "should have a scheme" do
353
+ @category.scheme.should == "http://example2.org"
354
+ end
355
+
356
+ it "should have a label" do
357
+ @category.label.should == "Drafts"
358
+ end
359
+ end
360
+ end
361
+
362
+ describe Atom::Link do
363
+ describe 'alternate link' do
364
+ before(:each) do
365
+ @entry = @feed.entries.first
366
+ @link = @entry.alternate
367
+ end
368
+
369
+ it "should have text/html type" do
370
+ @link.type.should == 'text/html'
371
+ end
372
+
373
+ it "should have alternate rel" do
374
+ @link.rel.should == 'alternate'
375
+ end
376
+
377
+ it "should have href 'http://example.org/2005/04/02/atom'" do
378
+ @link.href.should == 'http://example.org/2005/04/02/atom'
379
+ end
380
+
381
+ it "should have 'http://example.org/2005/04/02/atom' string representation" do
382
+ @link.to_s.should == 'http://example.org/2005/04/02/atom'
383
+ end
384
+
385
+ it "should have title 'Alternate link'" do
386
+ @link.title.should == "Alternate link"
387
+ end
388
+ end
389
+
390
+ describe 'enclosure link' do
391
+ before(:each) do
392
+ @entry = @feed.entries.first
393
+ @link = @entry.enclosures.first
394
+ end
395
+
396
+ it "should have audio/mpeg type" do
397
+ @link.type.should == 'audio/mpeg'
398
+ end
399
+
400
+ it "should have enclosure rel" do
401
+ @link.rel.should == 'enclosure'
402
+ end
403
+
404
+ it "should have length 1337" do
405
+ @link.length.should == 1337
406
+ end
407
+
408
+ it "should have href 'http://example.org/audio/ph34r_my_podcast.mp3'" do
409
+ @link.href.should == 'http://example.org/audio/ph34r_my_podcast.mp3'
410
+ end
411
+
412
+ it "should have 'http://example.org/audio/ph34r_my_podcast.mp3' string representation" do
413
+ @link.to_s.should == 'http://example.org/audio/ph34r_my_podcast.mp3'
414
+ end
415
+ end
416
+ end
417
+
418
+ describe Atom::Person do
419
+ before(:each) do
420
+ @entry = @feed.entries.first
421
+ @person = @entry.authors.first
422
+ end
423
+
424
+ it "should have a name" do
425
+ @person.name.should == 'Mark Pilgrim'
426
+ end
427
+
428
+ it "should have a uri" do
429
+ @person.uri.should == 'http://example.org/'
430
+ end
431
+
432
+ it "should have an email address" do
433
+ @person.email.should == 'f8dy@example.com'
434
+ end
435
+ end
436
+
437
+ describe Atom::Content do
438
+ before(:each) do
439
+ @entry = @feed.entries.first
440
+ @content = @entry.content
441
+ end
442
+
443
+ it "should have 'xhtml' type" do
444
+ @content.type.should == 'xhtml'
445
+ end
446
+
447
+ it "should have 'en' language" do
448
+ @content.xml_lang.should == 'en'
449
+ end
450
+
451
+ it "should have the content as the string representation" do
452
+ @content.should == '<p xmlns="http://www.w3.org/1999/xhtml"><i>[Update: The Atom draft is finished.]</i></p>'
453
+ end
454
+ end
455
+ end
456
+
457
+ describe 'ConformanceTests' do
458
+ describe 'nondefaultnamespace.atom' do
459
+ before(:all) do
460
+ @feed = Atom::Feed.load_feed(File.open('spec/conformance/nondefaultnamespace.atom'))
461
+ end
462
+
463
+ it "should have a title" do
464
+ @feed.title.should == 'Non-default namespace test'
465
+ end
466
+
467
+ it "should have 1 entry" do
468
+ @feed.should have(1).entries
469
+ end
470
+
471
+ describe Atom::Entry do
472
+ before(:all) do
473
+ @entry = @feed.entries.first
474
+ end
475
+
476
+ it "should have a title" do
477
+ @entry.title.should == 'If you can read the content of this entry, your aggregator works fine.'
478
+ end
479
+
480
+ it "should have content" do
481
+ @entry.content.should_not be_nil
482
+ end
483
+
484
+ it "should have 'xhtml' for the type of the content" do
485
+ @entry.content.type.should == 'xhtml'
486
+ end
487
+
488
+ it "should strip the outer div of the content" do
489
+ @entry.content.should_not match(/div/)
490
+ end
491
+
492
+ it "should keep inner xhtml of content" do
493
+ @entry.content.should == '<p xmlns="http://www.w3.org/1999/xhtml">For information, see:</p> ' +
494
+ '<ul xmlns="http://www.w3.org/1999/xhtml"> ' +
495
+ '<li><a href="http://plasmasturm.org/log/376/">Who knows an <abbr title="Extensible Markup Language">XML</abbr> document from a hole in the ground?</a></li> ' +
496
+ '<li><a href="http://plasmasturm.org/log/377/">More on Atom aggregator <abbr title="Extensible Markup Language">XML</abbr> namespace conformance tests</a></li> ' +
497
+ '<li><a href="http://www.intertwingly.net/wiki/pie/XmlNamespaceConformanceTests"><abbr title="Extensible Markup Language">XML</abbr> Namespace Conformance Tests</a></li> ' +
498
+ '</ul>'
499
+ end
500
+ end
501
+ end
502
+
503
+ describe 'unknown-namespace.atom' do
504
+ before(:all) do
505
+ @feed = Atom::Feed.load_feed(File.open('spec/conformance/unknown-namespace.atom'))
506
+ @entry = @feed.entries.first
507
+ @content = @entry.content
508
+ end
509
+
510
+ it "should have content" do
511
+ @content.should_not be_nil
512
+ end
513
+
514
+ it "should strip surrounding div" do
515
+ @content.should_not match(/div/)
516
+ end
517
+
518
+ it "should keep inner lists" do
519
+ @content.should match(/<h:ul/)
520
+ @content.should match(/<ul/)
521
+ end
522
+
523
+ it "should have xhtml type" do
524
+ @content.type.should == 'xhtml'
525
+ end
526
+ end
527
+
528
+ describe 'linktests.atom' do
529
+ before(:all) do
530
+ @feed = Atom::Feed.load_feed(File.open('spec/conformance/linktests.xml'))
531
+ @entries = @feed.entries
532
+ end
533
+
534
+ describe 'linktest1' do
535
+ before(:all) do
536
+ @entry = @entries[0]
537
+ end
538
+
539
+ it "should pick single alternate link without rel" do
540
+ @entry.alternate.href.should == 'http://www.snellspace.com/public/linktests/alternate'
541
+ end
542
+ end
543
+
544
+ describe 'linktest2' do
545
+ before(:all) do
546
+ @entry = @entries[1]
547
+ end
548
+
549
+ it "should be picky about case of alternate rel" do
550
+ @entry.alternate.href.should == 'http://www.snellspace.com/public/linktests/alternate'
551
+ end
552
+
553
+ it "should be picky when picking the alternate by type" do
554
+ @entry.alternate('text/plain').href.should == 'http://www.snellspace.com/public/linktests/alternate2'
555
+ end
556
+ end
557
+
558
+ describe 'linktest3' do
559
+ before(:all) do
560
+ @entry = @entries[2]
561
+ end
562
+
563
+ it "should parse all links" do
564
+ @entry.should have(5).links
565
+ end
566
+
567
+ it "should pick the alternate from a full list of core types" do
568
+ @entry.alternate.href.should == 'http://www.snellspace.com/public/linktests/alternate'
569
+ end
570
+ end
571
+
572
+ describe 'linktest4' do
573
+ before(:all) do
574
+ @entry = @entries[3]
575
+ end
576
+
577
+ it "should parse all links" do
578
+ @entry.should have(6).links
579
+ end
580
+
581
+ it "should pick the first alternate from a full list of core types with an extra alternate" do
582
+ @entry.alternate.href.should == 'http://www.snellspace.com/public/linktests/alternate'
583
+ end
584
+
585
+ it "should pick the alternate by type from a full list of core types with an extra alternate" do
586
+ @entry.alternate('text/plain').href.should == 'http://www.snellspace.com/public/linktests/alternate2'
587
+ end
588
+ end
589
+
590
+ describe 'linktest5' do
591
+ before(:all) do
592
+ @entry = @entries[4]
593
+ end
594
+
595
+ it "should parse all links" do
596
+ @entry.should have(2).links
597
+ end
598
+
599
+ it "should pick the alternate without choking on a non-core type" do
600
+ @entry.alternate.href.should == 'http://www.snellspace.com/public/linktests/alternate'
601
+ end
602
+
603
+ it "should include the non-core type in the list of links" do
604
+ @entry.links.map{|l| l.href }.should include('http://www.snellspace.com/public/linktests/license')
605
+ end
606
+ end
607
+
608
+ describe 'linktest6' do
609
+ before(:all) do
610
+ @entry = @entries[5]
611
+ end
612
+
613
+ it "should parse all links" do
614
+ @entry.should have(2).links
615
+ end
616
+
617
+ it "should pick the alternate without choking on a non-core type identified by a uri" do
618
+ @entry.alternate.href.should == 'http://www.snellspace.com/public/linktests/alternate'
619
+ end
620
+
621
+ it "should include the non-core type in the list of links identified by a uri" do
622
+ @entry.links.map{|l| l.href }.should include('http://www.snellspace.com/public/linktests/example')
623
+ end
624
+ end
625
+
626
+ describe 'linktest7' do
627
+ before(:all) do
628
+ @entry = @entries[6]
629
+ end
630
+
631
+ it "should parse all links" do
632
+ @entry.should have(2).links
633
+ end
634
+
635
+ it "should pick the alternate without choking on a non-core type" do
636
+ @entry.alternate.href.should == 'http://www.snellspace.com/public/linktests/alternate'
637
+ end
638
+
639
+ it "should include the non-core type in the list of links" do
640
+ @entry.links.map{|l| l.href }.should include('http://www.snellspace.com/public/linktests/license')
641
+ end
642
+ end
643
+
644
+ describe 'linktest8' do
645
+ before(:all) do
646
+ @entry = @entries[7]
647
+ end
648
+
649
+ it "should parse all links" do
650
+ @entry.should have(2).links
651
+ end
652
+
653
+ it "should pick the alternate without choking on a non-core type identified by a uri" do
654
+ @entry.alternate.href.should == 'http://www.snellspace.com/public/linktests/alternate'
655
+ end
656
+
657
+ it "should include the non-core type in the list of links identified by a uri" do
658
+ @entry.links.map{|l| l.href }.should include('http://www.snellspace.com/public/linktests/example')
659
+ end
660
+ end
661
+
662
+ describe 'linktest9' do
663
+ before(:all) do
664
+ @entry = @entries[8]
665
+ end
666
+
667
+ it "should parse all links" do
668
+ @entry.should have(3).links
669
+ end
670
+
671
+ it "should pick the alternate without hreflang" do
672
+ @entry.alternate.href.should == 'http://www.snellspace.com/public/linktests/alternate'
673
+ end
674
+ end
675
+ end
676
+
677
+ describe 'ordertest.atom' do
678
+ before(:all) do
679
+ @feed = Atom::Feed.load_feed(File.open('spec/conformance/ordertest.xml'))
680
+ end
681
+
682
+ it 'should have 9 entries' do
683
+ @feed.should have(9).entries
684
+ end
685
+
686
+ describe 'ordertest1' do
687
+ before(:each) do
688
+ @entry = @feed.entries[0]
689
+ end
690
+
691
+ it "should have the correct title" do
692
+ @entry.title.should == 'Simple order, nothing fancy'
693
+ end
694
+ end
695
+
696
+ describe 'ordertest2' do
697
+ before(:each) do
698
+ @entry = @feed.entries[1]
699
+ end
700
+
701
+ it "should have the correct title" do
702
+ @entry.title.should == 'Same as the first, only mixed up a bit'
703
+ end
704
+ end
705
+
706
+ describe "ordertest3" do
707
+ before(:each) do
708
+ @entry = @feed.entries[2]
709
+ end
710
+
711
+ it "should have the correct title" do
712
+ @entry.title.should == 'Multiple alt link elements, which one does your reader show?'
713
+ end
714
+
715
+ it "should pick the first alternate" do
716
+ @entry.alternate.href.should == 'http://www.snellspace.com/public/alternate'
717
+ end
718
+ end
719
+
720
+ describe 'ordertest4' do
721
+ before(:each) do
722
+ @entry = @feed.entries[3]
723
+ end
724
+
725
+ it "should have the correct title" do
726
+ @entry.title.should == 'Multiple link elements, does your feed reader show the "alternate" correctly?'
727
+ end
728
+
729
+ it "should pick the right link" do
730
+ @entry.alternate.href.should == 'http://www.snellspace.com/public/alternate'
731
+ end
732
+ end
733
+
734
+ describe 'ordertest5' do
735
+ before(:each) do
736
+ @entry = @feed.entries[4]
737
+ end
738
+
739
+ it "should have a source" do
740
+ @entry.source.should_not be_nil
741
+ end
742
+
743
+ it "should have the correct title" do
744
+ @entry.title.should == 'Entry with a source first'
745
+ end
746
+
747
+ it "should have the correct updated" do
748
+ @entry.updated.should == Time.parse('2006-01-26T09:20:05Z')
749
+ end
750
+
751
+ it "should have the correct alt link" do
752
+ @entry.alternate.href.should == 'http://www.snellspace.com/public/alternate'
753
+ end
754
+
755
+ describe Atom::Source do
756
+ before(:each) do
757
+ @source = @entry.source
758
+ end
759
+
760
+ it "should have an id" do
761
+ @source.id.should == 'tag:example.org,2006:atom/conformance/element_order'
762
+ end
763
+
764
+ it "should have a title" do
765
+ @source.title.should == 'Order Matters'
766
+ end
767
+
768
+ it "should have a subtitle" do
769
+ @source.subtitle.should == 'Testing how feed readers handle the order of entry elements'
770
+ end
771
+
772
+ it "should have a updated" do
773
+ @source.updated.should == Time.parse('2006-01-26T09:16:00Z')
774
+ end
775
+
776
+ it "should have an author" do
777
+ @source.should have(1).authors
778
+ end
779
+
780
+ it "should have the right name for the author" do
781
+ @source.authors.first.name.should == 'James Snell'
782
+ end
783
+
784
+ it "should have 2 links" do
785
+ @source.should have(2).links
786
+ end
787
+
788
+ it "should have an alternate" do
789
+ @source.alternate.href.should == 'http://www.snellspace.com/wp/?p=255'
790
+ end
791
+
792
+ it "should have a self" do
793
+ @source.self.href.should == 'http://www.snellspace.com/public/ordertest.xml'
794
+ end
795
+ end
796
+ end
797
+
798
+ describe 'ordertest6' do
799
+ before(:each) do
800
+ @entry = @feed.entries[5]
801
+ end
802
+
803
+ it "should have a source" do
804
+ @entry.source.should_not be_nil
805
+ end
806
+
807
+ it "should have the correct title" do
808
+ @entry.title.should == 'Entry with a source last'
809
+ end
810
+
811
+ it "should have the correct updated" do
812
+ @entry.updated.should == Time.parse('2006-01-26T09:20:06Z')
813
+ end
814
+
815
+ it "should have the correct alt link" do
816
+ @entry.alternate.href.should == 'http://www.snellspace.com/public/alternate'
817
+ end
818
+ end
819
+
820
+ describe 'ordetest7' do
821
+ before(:each) do
822
+ @entry = @feed.entries[6]
823
+ end
824
+
825
+ it "should have a source" do
826
+ @entry.source.should_not be_nil
827
+ end
828
+
829
+ it "should have the correct title" do
830
+ @entry.title.should == 'Entry with a source in the middle'
831
+ end
832
+
833
+ it "should have the correct updated" do
834
+ @entry.updated.should == Time.parse('2006-01-26T09:20:07Z')
835
+ end
836
+
837
+ it "should have the correct alt link" do
838
+ @entry.alternate.href.should == 'http://www.snellspace.com/public/alternate'
839
+ end
840
+ end
841
+
842
+ describe 'ordertest8' do
843
+ before(:each) do
844
+ @entry = @feed.entries[7]
845
+ end
846
+
847
+ it "should have the right title" do
848
+ @entry.title.should == 'Atom elements in an extension element'
849
+ end
850
+
851
+ it "should have right id" do
852
+ @entry.id.should == 'tag:example.org,2006:atom/conformance/element_order/8'
853
+ end
854
+ end
855
+
856
+ describe 'ordertest9' do
857
+ before(:each) do
858
+ @entry = @feed.entries[8]
859
+ end
860
+
861
+ it "should have the right title" do
862
+ @entry.title.should == 'Atom elements in an extension element'
863
+ end
864
+
865
+ it 'should have the right id' do
866
+ @entry.id.should == 'tag:example.org,2006:atom/conformance/element_order/9'
867
+ end
868
+ end
869
+ end
870
+ end
871
+
872
+ describe 'pagination' do
873
+ describe 'first_paged_feed.atom' do
874
+ before(:all) do
875
+ @feed = Atom::Feed.load_feed(File.open('spec/paging/first_paged_feed.atom'))
876
+ end
877
+
878
+ it "should be first?" do
879
+ @feed.should be_first
880
+ end
881
+
882
+ it "should not be last?" do
883
+ @feed.should_not be_last
884
+ end
885
+
886
+ it "should have next" do
887
+ @feed.next_page.href.should == 'http://example.org/index.atom?page=2'
888
+ end
889
+
890
+ it "should not have prev" do
891
+ @feed.prev_page.should be_nil
892
+ end
893
+
894
+ it "should have last" do
895
+ @feed.last_page.href.should == 'http://example.org/index.atom?page=10'
896
+ end
897
+
898
+ it "should have first" do
899
+ @feed.first_page.href.should == 'http://example.org/index.atom'
900
+ end
901
+ end
902
+
903
+ describe 'middle_paged_feed.atom' do
904
+ before(:all) do
905
+ @feed = Atom::Feed.load_feed(File.open('spec/paging/middle_paged_feed.atom'))
906
+ end
907
+
908
+ it "should not be last?" do
909
+ @feed.should_not be_last
910
+ end
911
+
912
+ it "should not be first?" do
913
+ @feed.should_not be_first
914
+ end
915
+
916
+ it "should have next_page" do
917
+ @feed.next_page.href.should == 'http://example.org/index.atom?page=4'
918
+ end
919
+
920
+ it "should have prev_page" do
921
+ @feed.prev_page.href.should == 'http://example.org/index.atom?page=2'
922
+ end
923
+
924
+ it "should have last_page" do
925
+ @feed.last_page.href.should == 'http://example.org/index.atom?page=10'
926
+ end
927
+
928
+ it "should have first_page" do
929
+ @feed.first_page.href.should == 'http://example.org/index.atom'
930
+ end
931
+ end
932
+
933
+ describe 'last_paged_feed.atom' do
934
+ before(:all) do
935
+ @feed = Atom::Feed.load_feed(File.open('spec/paging/last_paged_feed.atom'))
936
+ end
937
+
938
+ it "should not be first?" do
939
+ @feed.should_not be_first
940
+ end
941
+
942
+ it "should be last?" do
943
+ @feed.should be_last
944
+ end
945
+
946
+ it "should have prev_page" do
947
+ @feed.prev_page.href.should == 'http://example.org/index.atom?page=9'
948
+ end
949
+
950
+ it "should not have next_page" do
951
+ @feed.next_page.should be_nil
952
+ end
953
+
954
+ it "should have first_page" do
955
+ @feed.first_page.href.should == 'http://example.org/index.atom'
956
+ end
957
+
958
+ it "should have last_page" do
959
+ @feed.last_page.href.should == 'http://example.org/index.atom?page=10'
960
+ end
961
+ end
962
+
963
+ describe 'pagination using each_entry' do
964
+ before(:each) do
965
+ @feed = Atom::Feed.load_feed(File.open('spec/paging/first_paged_feed.atom'))
966
+ end
967
+
968
+ it "should paginate through each entry" do
969
+ feed1 = Atom::Feed.load_feed(File.read('spec/paging/middle_paged_feed.atom'))
970
+ feed2 = Atom::Feed.load_feed(File.read('spec/paging/last_paged_feed.atom'))
971
+
972
+ Atom::Feed.should_receive(:load_feed).
973
+ with(URI.parse('http://example.org/index.atom?page=2'), an_instance_of(Hash)).
974
+ and_return(feed1)
975
+ Atom::Feed.should_receive(:load_feed).
976
+ with(URI.parse('http://example.org/index.atom?page=4'), an_instance_of(Hash)).
977
+ and_return(feed2)
978
+
979
+ entry_count = 0
980
+ @feed.each_entry(:paginate => true) do |entry|
981
+ entry_count += 1
982
+ end
983
+
984
+ entry_count.should == 3
985
+ end
986
+
987
+ it "should not paginate through each entry when paginate not true" do
988
+ entry_count = 0
989
+ @feed.each_entry do |entry|
990
+ entry_count += 1
991
+ end
992
+
993
+ entry_count.should == 1
994
+ end
995
+
996
+ it "should only paginate up to since" do
997
+ response1 = Net::HTTPSuccess.new(nil, nil, nil)
998
+ response1.stub!(:body).and_return(File.read('spec/paging/middle_paged_feed.atom'))
999
+ mock_http_get(URI.parse('http://example.org/index.atom?page=2'), response1)
1000
+
1001
+ entry_count = 0
1002
+ @feed.each_entry(:paginate => true, :since => Time.parse('2003-11-19T18:30:02Z')) do |entry|
1003
+ entry_count += 1
1004
+ end
1005
+
1006
+ entry_count.should == 1
1007
+ end
1008
+ end
1009
+
1010
+ describe "entry_with_simple_extensions.atom" do
1011
+ before(:each) do
1012
+ @feed = Atom::Feed.load_feed(File.open('spec/fixtures/entry_with_simple_extensions.atom'))
1013
+ @entry = @feed.entries.first
1014
+ end
1015
+
1016
+ it "should load simple extension for feed" do
1017
+ @feed["http://example.org/example", 'simple1'].should == ['Simple1 Value']
1018
+ end
1019
+
1020
+ it "should load empty simple extension for feed" do
1021
+ @feed["http://example.org/example", 'simple-empty'].should == ['']
1022
+ end
1023
+
1024
+ it "should load simple extension 1 for entry" do
1025
+ @entry["http://example.org/example", 'simple1'].should == ['Simple1 Entry Value']
1026
+ end
1027
+
1028
+ it "should load simple extension 2 for entry" do
1029
+ @entry["http://example.org/example", 'simple2'].should == ['Simple2', 'Simple2a']
1030
+ end
1031
+
1032
+ it "should find a simple extension in another namespace" do
1033
+ @entry["http://example2.org/example2", 'simple1'].should == ['Simple Entry Value (NS2)']
1034
+ end
1035
+
1036
+ it "should load simple extension attribute on a category" do
1037
+ @entry.categories.first["http://example.org/example", "attribute"].first.should == "extension"
1038
+ end
1039
+
1040
+ it "should write a simple extension attribute as an attribute" do
1041
+ @entry.categories.first.to_xml(true)['ns1:attribute'].should == 'extension'
1042
+ end
1043
+
1044
+ it "should read an extension with the same local name as an Atom element" do
1045
+ @feed['http://example.org/example', 'title'].should == ['Extension Title']
1046
+ end
1047
+
1048
+ it_should_behave_like 'simple_single_entry.atom attributes'
1049
+
1050
+ it "should load simple extension 3 xml for entry" do
1051
+ @entry["http://example.org/example3", 'simple3'].should == ['<ContinuityOfCareRecord xmlns="urn:astm-org:CCR">Simple Entry Value (NS2)</ContinuityOfCareRecord>']
1052
+ end
1053
+
1054
+ describe "when only namespace is provided" do
1055
+ before :each do
1056
+ @example_elements = @entry["http://example.org/example"]
1057
+ @example2_elements = @entry['http://example2.org/example2']
1058
+ @example3_elements = @entry['http://example.org/example3']
1059
+ end
1060
+
1061
+ it "should return namespace elements as a hash" do
1062
+ @example_elements.should == {
1063
+ 'simple1' => ['Simple1 Entry Value'],
1064
+ 'simple2' => ['Simple2', 'Simple2a']
1065
+ }
1066
+
1067
+ @example2_elements.should == {
1068
+ 'simple1' => ['Simple Entry Value (NS2)']
1069
+ }
1070
+
1071
+ @example3_elements.should == {
1072
+ 'simple3' => ['<ContinuityOfCareRecord xmlns="urn:astm-org:CCR">Simple Entry Value (NS2)</ContinuityOfCareRecord>']
1073
+ }
1074
+ end
1075
+ end
1076
+ end
1077
+
1078
+ describe 'writing simple extensions' do
1079
+ it "should recode and re-read a simple extension element" do
1080
+ entry = Atom::Entry.new do |entry|
1081
+ entry.id = 'urn:test'
1082
+ entry.title = 'Simple Ext. Test'
1083
+ entry.updated = Time.now
1084
+ entry['http://example.org', 'title'] << 'Example title'
1085
+ end
1086
+
1087
+ entry2 = Atom::Entry.load_entry(entry.to_xml)
1088
+ entry2['http://example.org', 'title'].should == ['Example title']
1089
+ end
1090
+ end
1091
+ end
1092
+
1093
+ describe 'custom_extensions' do
1094
+ before(:all) do
1095
+ Atom::Entry.add_extension_namespace :ns_alias, "http://custom.namespace"
1096
+ Atom::Entry.elements "ns_alias:property", :class => Atom::Extensions::Property
1097
+ @entry = Atom::Entry.load_entry(File.open('spec/fixtures/entry_with_custom_extensions.atom'))
1098
+ end
1099
+
1100
+ it "should_load_custom_extensions_for_entry" do
1101
+ @entry.ns_alias_property.should_not == []
1102
+ end
1103
+
1104
+ it "should_load_2_custom_extensions_for_entry" do
1105
+ @entry.ns_alias_property.size.should == 2
1106
+ end
1107
+
1108
+ it "should load correct_data_for_custom_extensions_for_entry" do
1109
+ @entry.ns_alias_property.map { |x| [x.name, x.value] }.should == [['foo', 'bar'], ['baz', 'bat']]
1110
+ end
1111
+ end
1112
+
1113
+ describe 'single custom_extensions' do
1114
+ before(:all) do
1115
+ Atom::Entry.add_extension_namespace :custom, "http://single.custom.namespace"
1116
+ Atom::Entry.element "custom:singleproperty", :class => Atom::Extensions::Property
1117
+ @entry = Atom::Entry.load_entry(File.open('spec/fixtures/entry_with_single_custom_extension.atom'))
1118
+ end
1119
+
1120
+ it "should load single custom extensions for entry" do
1121
+ @entry.custom_singleproperty.should_not be_nil
1122
+ end
1123
+
1124
+ it "should load correct data for custom extensions for entry" do
1125
+ @entry.custom_singleproperty.name.should == 'foo'
1126
+ @entry.custom_singleproperty.value.should == 'bar'
1127
+ end
1128
+ end
1129
+
1130
+ describe 'write_support' do
1131
+ # FIXME this example depends on "custom_extensions" for configuring Atom::Entry
1132
+ before(:all) do
1133
+ @entry = Atom::Entry.new
1134
+ @entry.ns_alias_property << Atom::Extensions::Property.new('ratom', 'rocks')
1135
+ @entry.ns_alias_property << Atom::Extensions::Property.new('custom extensions', 'also rock')
1136
+ @node = @entry.to_xml(true)
1137
+ end
1138
+
1139
+ it "should_write_custom_extensions_on_to_xml" do
1140
+ @node.children.size.should == 2
1141
+ ratom, custom_extensions = @node.children
1142
+ ratom.attributes["name"].should == "ratom"
1143
+ ratom.attributes["value"].should == "rocks"
1144
+ custom_extensions.attributes["name"].should == "custom extensions"
1145
+ custom_extensions.attributes["value"].should == "also rock"
1146
+ end
1147
+ end
1148
+
1149
+ describe Atom::Link do
1150
+ before(:each) do
1151
+ @href = 'http://example.org/next'
1152
+ @link = Atom::Link.new(:rel => 'next', :href => @href)
1153
+ end
1154
+
1155
+ it "should fetch feed for fetch_next" do
1156
+ Atom::Feed.should_receive(:load_feed).with(URI.parse(@href), an_instance_of(Hash))
1157
+ @link.fetch
1158
+ end
1159
+
1160
+ it "should fetch content when response is not xml" do
1161
+ Atom::Feed.should_receive(:load_feed).and_raise(Atom::LoadError)
1162
+ response = Net::HTTPSuccess.new(nil, nil, nil)
1163
+ response.stub!(:body).and_return('some text.')
1164
+ Net::HTTP.should_receive(:get_response).with(URI.parse(@href)).and_return(response)
1165
+ @link.fetch.should == 'some text.'
1166
+ end
1167
+ end
1168
+
1169
+ describe Atom::Entry do
1170
+ before(:all) do
1171
+ @entry = Atom::Entry.load_entry(File.read('spec/fixtures/entry.atom'))
1172
+ end
1173
+
1174
+ it "should be == to itself" do
1175
+ @entry.should == Atom::Entry.load_entry(File.read('spec/fixtures/entry.atom'))
1176
+ end
1177
+
1178
+ it "should be != if something changes" do
1179
+ @other = Atom::Entry.load_entry(File.read('spec/fixtures/entry.atom'))
1180
+ @other.title = 'foo'
1181
+ @entry.should_not == @other
1182
+ end
1183
+
1184
+ it "should be != if content changes" do
1185
+ @other = Atom::Entry.load_entry(File.read('spec/fixtures/entry.atom'))
1186
+ @other.content.type = 'html'
1187
+ @entry.should_not == @other
1188
+ end
1189
+
1190
+ it "should output itself" do
1191
+ other = Atom::Entry.load_entry(@entry.to_xml)
1192
+ @entry.should == other
1193
+ end
1194
+
1195
+ it "should properly escape titles" do
1196
+ @entry.title = "Breaking&nbsp;Space"
1197
+ other = Atom::Entry.load_entry(@entry.to_xml)
1198
+ @entry.should == other
1199
+ end
1200
+
1201
+ it "should raise error when to_xml'ing non-utf8 content" do
1202
+ lambda {
1203
+ puts(Atom::Entry.new do |entry|
1204
+ entry.title = "My entry"
1205
+ entry.id = "urn:entry:1"
1206
+ entry.content = Atom::Content::Html.new("this is not \227 utf8")
1207
+ end.to_xml)
1208
+ }.should raise_error(Atom::SerializationError)
1209
+ end
1210
+ end
1211
+
1212
+ describe 'Atom::Feed initializer' do
1213
+ it "should create an empty Feed" do
1214
+ lambda { Atom::Feed.new }.should_not raise_error
1215
+ end
1216
+
1217
+ it "should yield to a block" do
1218
+ lambda do
1219
+ Atom::Feed.new do |f|
1220
+ f.should be_an_instance_of(Atom::Feed)
1221
+ throw :yielded
1222
+ end
1223
+ end.should throw_symbol(:yielded)
1224
+ end
1225
+ end
1226
+
1227
+ describe 'Atom::Entry initializer' do
1228
+ it "should create an empty feed" do
1229
+ lambda { Atom::Entry.new }.should_not raise_error
1230
+ end
1231
+
1232
+ it "should yield to a block" do
1233
+ lambda do
1234
+ Atom::Entry.new do |f|
1235
+ f.should be_an_instance_of(Atom::Entry)
1236
+ throw :yielded
1237
+ end
1238
+ end.should throw_symbol(:yielded)
1239
+ end
1240
+ end
1241
+
1242
+ describe Atom::Content::Html do
1243
+ it "should escape ampersands in entities" do
1244
+ Atom::Content::Html.new("&nbsp;").to_xml.to_s.should == "<content type=\"html\">&amp;nbsp;</content>"
1245
+ end
1246
+ end
1247
+
1248
+ describe Atom::Content::Text do
1249
+ it "should be createable from a string" do
1250
+ txt = Atom::Content::Text.new("This is some text")
1251
+ txt.should == "This is some text"
1252
+ txt.type.should == "text"
1253
+ end
1254
+ end
1255
+
1256
+ describe Atom::Content::Xhtml do
1257
+ it "should be createable from a string" do
1258
+ txt = Atom::Content::Xhtml.new("<p>This is some text</p>")
1259
+ txt.should == "<p>This is some text</p>"
1260
+ txt.type.should == "xhtml"
1261
+ end
1262
+
1263
+ it "should be renderable to xml" do
1264
+ txt = Atom::Content::Xhtml.new("<p>This is some text</p>")
1265
+ txt.to_xml.should_not raise_error("TypeError")
1266
+ end
1267
+ end
1268
+
1269
+ describe 'Atom::Category initializer' do
1270
+ it "should create a empty category" do
1271
+ lambda { Atom::Category.new }.should_not raise_error
1272
+ end
1273
+
1274
+ it "should create from a hash" do
1275
+ category = Atom::Category.new(:term => 'term', :scheme => 'scheme', :label => 'label')
1276
+ category.term.should == 'term'
1277
+ category.scheme.should == 'scheme'
1278
+ category.label.should == 'label'
1279
+ end
1280
+
1281
+ it "should create from a block" do
1282
+ category = Atom::Category.new do |cat|
1283
+ cat.term = 'term'
1284
+ end
1285
+
1286
+ category.term.should == 'term'
1287
+ end
1288
+ end
1289
+
1290
+ describe Atom::Source do
1291
+ it "should create an empty source" do
1292
+ lambda { Atom::Source.new }.should_not raise_error
1293
+ end
1294
+
1295
+ it "should create from a hash" do
1296
+ source = Atom::Source.new(:title => 'title', :id => 'sourceid')
1297
+ source.title.should == 'title'
1298
+ source.id.should == 'sourceid'
1299
+ end
1300
+
1301
+ it "should create from a block" do
1302
+ source = Atom::Source.new do |source|
1303
+ source.title = 'title'
1304
+ source.id = 'sourceid'
1305
+ end
1306
+ source.title.should == 'title'
1307
+ source.id.should == 'sourceid'
1308
+ end
1309
+ end
1310
+
1311
+ describe Atom::Generator do
1312
+ it "should create an empty generator" do
1313
+ lambda { Atom::Generator.new }.should_not raise_error
1314
+ end
1315
+
1316
+ it "should create from a hash" do
1317
+ generator = Atom::Generator.new(:name => 'generator', :uri => 'http://generator')
1318
+ generator.name.should == 'generator'
1319
+ generator.uri.should == 'http://generator'
1320
+ end
1321
+
1322
+ it "should create from a block" do
1323
+ generator = Atom::Generator.new do |generator|
1324
+ generator.name = 'generator'
1325
+ generator.uri = 'http://generator'
1326
+ end
1327
+ generator.name.should == 'generator'
1328
+ generator.uri.should == 'http://generator'
1329
+ end
1330
+
1331
+ it "should output the name as the text of the generator element" do
1332
+ generator = Atom::Generator.new({:name => "My Generator"})
1333
+ generator.to_xml(true).to_s.should == "<generator>My Generator</generator>"
1334
+ end
1335
+ end
1336
+ end