atom-tools 2.0.3 → 2.0.4
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.
- data/Rakefile +63 -70
- data/bin/atom-post +1 -0
- data/lib/atom/element.rb +42 -4
- data/lib/atom/entry.rb +15 -40
- data/lib/atom/feed.rb +4 -0
- data/lib/atom/http.rb +1 -1
- data/spec/entry_spec.rb +353 -0
- data/spec/ext_spec.rb +42 -0
- data/spec/feed_spec.rb +20 -0
- data/spec/fixtures/entry-w-ext.xml +15 -0
- data/spec/fixtures/entry.xml +42 -0
- data/spec/fixtures/feed-w-ext.xml +33 -0
- data/spec/fixtures/service-w-xhtml-ns.xml +21 -0
- data/spec/fixtures/service.xml +36 -0
- data/spec/service_spec.rb +108 -0
- data/spec/spec_helper.rb +9 -0
- metadata +24 -9
data/Rakefile
CHANGED
@@ -7,81 +7,74 @@ require "spec/rake/spectask"
|
|
7
7
|
require "rake/clean"
|
8
8
|
|
9
9
|
NAME = "atom-tools"
|
10
|
-
VERS = "2.0.
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
10
|
+
VERS = "2.0.4"
|
11
|
+
|
12
|
+
task :default => [:spec]
|
13
|
+
|
14
|
+
# For historical reasons, atom-tools has both rspec specs and test/unit tests.
|
15
|
+
# This is silly (and there's a lot of duplication), but I have better things to
|
16
|
+
# do than rewrite the tests.
|
17
|
+
#
|
18
|
+
# Ideally all the tests should be runnable with one command, but for now you
|
19
|
+
# have to run "rake test" and "rake spec"
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
21
|
+
# spec task
|
22
|
+
desc 'Run all specs (see also "test" task)'
|
23
|
+
Spec::Rake::SpecTask.new('spec')
|
24
|
+
|
25
|
+
# test task
|
26
|
+
Rake::TestTask.new do |t|
|
27
|
+
t.libs << "test"
|
28
|
+
t.test_files = FileList['test/test*.rb']
|
29
|
+
t.verbose = true
|
29
30
|
end
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
spec = Gem::Specification.new do |s|
|
37
|
-
s.name = pkg_name
|
38
|
-
s.version = pkg_version
|
39
|
-
s.platform = Gem::Platform::RUBY
|
40
|
-
s.author = author
|
41
|
-
s.email = 'whateley@gmail.com'
|
42
|
-
s.homepage = 'http://code.necronomicorp.com/atom-tools'
|
43
|
-
s.rubyforge_project = 'ibes'
|
44
|
-
s.summary = summary
|
45
|
-
s.test_file = test_file
|
46
|
-
s.has_rdoc = true
|
47
|
-
s.extra_rdoc_files = [ "README" ]
|
48
|
-
dependencies.each do |dep|
|
49
|
-
s.add_dependency(*dep)
|
50
|
-
end
|
51
|
-
s.files = %w(COPYING README Rakefile setup.rb) +
|
52
|
-
Dir.glob("{bin,doc,test,lib}/**/*") +
|
53
|
-
Dir.glob("ext/**/*.{h,c,rb}") +
|
54
|
-
Dir.glob("examples/**/*.rb") +
|
55
|
-
Dir.glob("tools/*.rb")
|
56
|
-
|
57
|
-
s.require_path = "lib"
|
58
|
-
s.extensions = FileList["ext/**/extconf.rb"].to_a
|
59
|
-
|
60
|
-
s.bindir = "bin"
|
61
|
-
end
|
62
|
-
|
63
|
-
Rake::GemPackageTask.new(spec) do |p|
|
64
|
-
p.gem_spec = spec
|
65
|
-
p.need_tar = true
|
66
|
-
end
|
67
|
-
|
68
|
-
task :install do
|
69
|
-
sh %{rake package}
|
70
|
-
sh %{gem install pkg/#{pkg_name}-#{pkg_version}}
|
71
|
-
end
|
32
|
+
Rake::RDocTask.new do |rdoc|
|
33
|
+
rdoc.title = 'atom-tools documentation'
|
34
|
+
rdoc.main = 'README'
|
35
|
+
rdoc.rdoc_files.include 'README', 'lib/**/*.rb'
|
36
|
+
rdoc.rdoc_dir = 'doc'
|
72
37
|
end
|
73
38
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
39
|
+
spec = Gem::Specification.new do |s|
|
40
|
+
s.name = NAME
|
41
|
+
s.version = VERS
|
42
|
+
s.platform = Gem::Platform::RUBY
|
43
|
+
s.author = "Brendan Taylor"
|
44
|
+
s.email = 'whateley@gmail.com'
|
45
|
+
s.homepage = 'http://github.com/bct/atom-tools/wikis'
|
46
|
+
|
47
|
+
s.rubyforge_project = 'ibes'
|
48
|
+
|
49
|
+
s.summary = 'Tools for working with Atom Entries, Feeds and Collections.'
|
50
|
+
s.description = 'atom-tools is an all-in-one Atom library. It parses and builds Atom (RFC 4287) entries and feeds, and manipulates Atom Publishing Protocol (RFC 5023) Collections.
|
51
|
+
|
52
|
+
It also comes with a set of commandline utilities for working with AtomPub Collections.
|
53
|
+
|
54
|
+
It is not the fastest Ruby Atom library, but it is comprehensive and makes handling extensions to the Atom format very easy.'
|
55
|
+
|
56
|
+
s.test_file = "test/runtests.rb" # TODO: should have the spec here instead?
|
57
|
+
s.has_rdoc = true
|
58
|
+
s.extra_rdoc_files = [ "README" ]
|
59
|
+
|
60
|
+
s.files = %w(COPYING README Rakefile setup.rb) +
|
61
|
+
Dir.glob("{bin,doc,test,spec,lib}/**/*") +
|
62
|
+
Dir.glob("ext/**/*.{h,c,rb}") +
|
63
|
+
Dir.glob("examples/**/*.rb") +
|
64
|
+
Dir.glob("tools/*.rb")
|
65
|
+
|
66
|
+
s.require_path = "lib"
|
67
|
+
s.extensions = FileList["ext/**/extconf.rb"].to_a
|
68
|
+
|
69
|
+
s.bindir = "bin"
|
80
70
|
end
|
81
71
|
|
82
|
-
|
83
|
-
|
72
|
+
Rake::GemPackageTask.new(spec) do |p|
|
73
|
+
p.gem_spec = spec
|
74
|
+
p.need_tar = true
|
75
|
+
end
|
84
76
|
|
85
|
-
|
86
|
-
|
87
|
-
|
77
|
+
task :install do
|
78
|
+
sh %{rake package}
|
79
|
+
sh %{gem install pkg/#{NAME}-#{VERS}}
|
80
|
+
end
|
data/bin/atom-post
CHANGED
data/lib/atom/element.rb
CHANGED
@@ -507,7 +507,7 @@ module Atom # :nodoc:
|
|
507
507
|
@attrs
|
508
508
|
end
|
509
509
|
|
510
|
-
self.class.
|
510
|
+
self.class.run_initters do |init|
|
511
511
|
self.instance_eval &init
|
512
512
|
end
|
513
513
|
|
@@ -521,9 +521,8 @@ module Atom # :nodoc:
|
|
521
521
|
@on_init << block
|
522
522
|
end
|
523
523
|
|
524
|
-
def self.
|
525
|
-
@on_init
|
526
|
-
@on_init.each &block
|
524
|
+
def self.run_initters &block
|
525
|
+
@on_init.each(&block) if @on_init
|
527
526
|
end
|
528
527
|
|
529
528
|
# appends an element named 'name' in namespace 'ns' to 'root'
|
@@ -644,4 +643,43 @@ module Atom # :nodoc:
|
|
644
643
|
class Contributor < Atom::Person
|
645
644
|
is_atom_element :contributor
|
646
645
|
end
|
646
|
+
|
647
|
+
module HasLinks
|
648
|
+
def HasLinks.included(klass)
|
649
|
+
klass.atom_elements :link, :links, Atom::Link
|
650
|
+
end
|
651
|
+
|
652
|
+
def find_link(criteria)
|
653
|
+
self.links.find do |l|
|
654
|
+
criteria.all? { |k,v| l.send(k) == v }
|
655
|
+
end
|
656
|
+
end
|
657
|
+
end
|
658
|
+
|
659
|
+
module HasCategories
|
660
|
+
def HasCategories.included(klass)
|
661
|
+
klass.atom_elements :category, :categories, Atom::Category
|
662
|
+
end
|
663
|
+
|
664
|
+
# categorize the entry with each of an array or a space-separated
|
665
|
+
# string
|
666
|
+
def tag_with(tags, delimiter = ' ')
|
667
|
+
return if not tags or tags.empty?
|
668
|
+
|
669
|
+
tag_list = unless tags.is_a?(String)
|
670
|
+
tags
|
671
|
+
else
|
672
|
+
tags = tags.split(delimiter)
|
673
|
+
tags.map! { |t| t.strip }
|
674
|
+
tags.reject! { |t| t.empty? }
|
675
|
+
tags.uniq
|
676
|
+
end
|
677
|
+
|
678
|
+
tag_list.each do |tag|
|
679
|
+
unless categories.any? { |c| c.term == tag }
|
680
|
+
categories.new :term => tag
|
681
|
+
end
|
682
|
+
end
|
683
|
+
end
|
684
|
+
end
|
647
685
|
end
|
data/lib/atom/entry.rb
CHANGED
@@ -3,7 +3,21 @@ require "rexml/document"
|
|
3
3
|
require "atom/element"
|
4
4
|
require "atom/text"
|
5
5
|
|
6
|
+
require 'atom/feed'
|
7
|
+
|
6
8
|
module Atom
|
9
|
+
# this is just a forward declaration since atom/entry includes atom/feed and vice-versa.
|
10
|
+
class Feed < Atom::Element # :nodoc:
|
11
|
+
end
|
12
|
+
|
13
|
+
class Source < Atom::Feed
|
14
|
+
is_atom_element :source
|
15
|
+
|
16
|
+
# TODO: this shouldn't be necessary, but on_init doesn't get inherited the
|
17
|
+
# way I would like it to.
|
18
|
+
@on_init = Atom::Feed.instance_variable_get '@on_init'
|
19
|
+
end
|
20
|
+
|
7
21
|
class Control < Atom::Element
|
8
22
|
attr_accessor :draft
|
9
23
|
|
@@ -21,45 +35,6 @@ module Atom
|
|
21
35
|
end
|
22
36
|
end
|
23
37
|
|
24
|
-
module HasCategories
|
25
|
-
def HasCategories.included(klass)
|
26
|
-
klass.atom_elements :category, :categories, Atom::Category
|
27
|
-
end
|
28
|
-
|
29
|
-
# categorize the entry with each of an array or a space-separated
|
30
|
-
# string
|
31
|
-
def tag_with(tags, delimiter = ' ')
|
32
|
-
return if not tags or tags.empty?
|
33
|
-
|
34
|
-
tag_list = unless tags.is_a?(String)
|
35
|
-
tags
|
36
|
-
else
|
37
|
-
tags = tags.split(delimiter)
|
38
|
-
tags.map! { |t| t.strip }
|
39
|
-
tags.reject! { |t| t.empty? }
|
40
|
-
tags.uniq
|
41
|
-
end
|
42
|
-
|
43
|
-
tag_list.each do |tag|
|
44
|
-
unless categories.any? { |c| c.term == tag }
|
45
|
-
categories.new :term => tag
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
module HasLinks
|
52
|
-
def HasLinks.included(klass)
|
53
|
-
klass.atom_elements :link, :links, Atom::Link
|
54
|
-
end
|
55
|
-
|
56
|
-
def find_link(criteria)
|
57
|
-
self.links.find do |l|
|
58
|
-
criteria.all? { |k,v| l.send(k) == v }
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
38
|
# An individual entry in a feed. As an Atom::Element, it can be
|
64
39
|
# manipulated using accessors for each of its child elements. You
|
65
40
|
# should be able to set them using an instance of any class that
|
@@ -94,7 +69,7 @@ module Atom
|
|
94
69
|
|
95
70
|
atom_element :rights, Atom::Rights
|
96
71
|
|
97
|
-
|
72
|
+
atom_element :source, Atom::Source
|
98
73
|
|
99
74
|
atom_time :published
|
100
75
|
atom_time :updated
|
data/lib/atom/feed.rb
CHANGED
data/lib/atom/http.rb
CHANGED
data/spec/entry_spec.rb
ADDED
@@ -0,0 +1,353 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
require 'atom/entry'
|
4
|
+
|
5
|
+
module TestsXML
|
6
|
+
def read_entry_xml xpath
|
7
|
+
REXML::XPath.first(@entry.to_xml, xpath, { 'atom' => Atom::NS, 'app' => Atom::PP_NS })
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Atom::Entry do
|
12
|
+
describe 'when parsing' do
|
13
|
+
before(:each) do
|
14
|
+
@entry = Atom::Entry.parse(fixtures(:entry))
|
15
|
+
@empty_entry = '<entry xmlns="http://www.w3.org/2005/Atom" />'
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should read & parse input from an IO object' do
|
19
|
+
input = mock('IO')
|
20
|
+
input.should_receive(:read).and_return(@empty_entry)
|
21
|
+
Atom::Entry.parse(input).should be_an_instance_of(Atom::Entry)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should read & parse input from a string' do
|
25
|
+
input = mock('string')
|
26
|
+
input.should_receive(:to_s).and_return(@empty_entry)
|
27
|
+
Atom::Entry.parse(input).should be_an_instance_of(Atom::Entry)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should raise ParseError when invalid entry' do
|
31
|
+
lambda { Atom::Entry.parse('<entry/>') }.should raise_error(Atom::ParseError)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should parse title element correctly' do
|
35
|
+
@entry.title.should be_is_a(Atom::Text)
|
36
|
+
@entry.title['type'].should == 'text'
|
37
|
+
@entry.title.to_s.should == 'Atom draft-07 snapshot'
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should parse id element correctly' do
|
41
|
+
@entry.id.should == 'tag:example.org,2003:3.2397'
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should parse updated element correctly' do
|
45
|
+
@entry.updated.should == Time.parse('2005-07-31T12:29:29Z')
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should parse published element correctly' do
|
49
|
+
@entry.published.should == Time.parse('2003-12-13T08:29:29-04:00')
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should parse app:edited element correctly' do
|
53
|
+
@entry.edited.should == Time.parse('2005-07-31T12:29:29Z')
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should parse app:control/draft element correctly' do
|
57
|
+
@entry.draft?.should be_true
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should parse rights element correctly' do
|
61
|
+
@entry.rights.should be_is_a(Atom::Text)
|
62
|
+
@entry.rights['type'].should == 'text'
|
63
|
+
@entry.rights.to_s.should == 'Copyright (c) 2003, Mark Pilgrim'
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should parse author element correctly' do
|
67
|
+
@entry.authors.length.should == 1
|
68
|
+
@entry.authors.first.name.should == 'Mark Pilgrim'
|
69
|
+
@entry.authors.first.email.should == 'f8dy@example.com'
|
70
|
+
@entry.authors.first.uri.should == 'http://example.org/'
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should parse contributor element correctly' do
|
74
|
+
@entry.contributors.length.should == 2
|
75
|
+
@entry.contributors.first.name.should == 'Sam Ruby'
|
76
|
+
@entry.contributors[1].name.should == 'Joe Gregorio'
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should parse content element correctly' do
|
80
|
+
@entry.content.should be_an_instance_of(Atom::Content)
|
81
|
+
@entry.content['type'].should == 'xhtml'
|
82
|
+
@entry.content.base.should == 'http://diveintomark.org/'
|
83
|
+
@entry.content.to_s.strip.should == '<p><i>[Update: The Atom draft is finished.]</i></p>'
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should parse summary element correctly' do
|
87
|
+
@entry.summary['type'].should == 'text'
|
88
|
+
@entry.summary.to_s.should == 'Some text.'
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should parse links element correctly' do
|
92
|
+
@entry.links.length.should == 2
|
93
|
+
alternates = @entry.links.select { |l| l['rel'] == 'alternate' }
|
94
|
+
alternates.length.should == 1
|
95
|
+
alternates.first['href'].should == 'http://example.org/2005/04/02/atom'
|
96
|
+
alternates.first['type'].should == 'text/html'
|
97
|
+
@entry.links.last['rel'].should == 'enclosure'
|
98
|
+
@entry.links.last['href'].should == 'http://example.org/audio/ph34r_my_podcast.mp3'
|
99
|
+
@entry.links.last['type'].should == 'audio/mpeg'
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'should parse category element correctly' do
|
103
|
+
@entry.categories.first['term'].should == 'ann'
|
104
|
+
@entry.categories.first['scheme'].should == 'http://example.org/cats'
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'should parse source element correctly' do
|
108
|
+
@entry.source.title.to_s.should == 'Atom Sample Feed'
|
109
|
+
@entry.source.id.should == 'tag:example.org,2003:/'
|
110
|
+
|
111
|
+
@entry.source.links.length.should == 1
|
112
|
+
@entry.source.links.first.rel == 'self'
|
113
|
+
|
114
|
+
@entry.source.authors.length.should == 0
|
115
|
+
|
116
|
+
@entry.source.contributors.length.should == 1
|
117
|
+
@entry.source.contributors.first.name == 'Mark Pilgrim'
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe 'title element' do
|
122
|
+
before(:each) do
|
123
|
+
@entry = Atom::Entry.new
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should be nil if not defined' do
|
127
|
+
@entry.title.should be_nil
|
128
|
+
|
129
|
+
@entry.title.to_s.should == ''
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should accept a simple string' do
|
133
|
+
@entry.title = '<clever thing here>'
|
134
|
+
|
135
|
+
@entry.title.type.should == 'text'
|
136
|
+
|
137
|
+
@entry.title.to_s.should == '<clever thing here>'
|
138
|
+
@entry.title.html.should =~ /^<clever thing/
|
139
|
+
@entry.title.to_xml.to_s.should =~ /<clever thing/
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'should accept an HTML string' do
|
143
|
+
@entry.title = 'even <em>cleverer</em>'
|
144
|
+
@entry.title.type = 'html'
|
145
|
+
|
146
|
+
@entry.title.type.should == 'html'
|
147
|
+
|
148
|
+
@entry.title.to_s.should =~ /even <em>clever/
|
149
|
+
@entry.title.html.should =~ /even <em>clever/
|
150
|
+
@entry.title.to_xml.to_s.should =~ /even <em/
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should accept an XHTML string' do
|
154
|
+
@entry.title = 'the <strong>cleverest</strong>'
|
155
|
+
@entry.title.type = 'xhtml'
|
156
|
+
|
157
|
+
@entry.title.to_xml.to_s.should =~ /w3.org\/1999\/xhtml.>the <strong>/
|
158
|
+
@entry.title.html.should =~ /the <strong>cleverest/
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'should reject an ill-formed XHTML string' do
|
162
|
+
@entry.title = 'the <strong>cleverest'
|
163
|
+
lambda { @entry.title.type = 'xhtml' }.should raise_error(Atom::ParseError)
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'should accept something like Atom::Text' do
|
167
|
+
title = Atom::Title.new '<3'
|
168
|
+
|
169
|
+
@entry.title = title
|
170
|
+
@entry.title.type.should == 'text'
|
171
|
+
|
172
|
+
@entry.title.to_xml.to_s.should =~ /<3/
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe 'updated element' do
|
177
|
+
before(:each) do
|
178
|
+
@entry = Atom::Entry.new
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'should be nil if not defined' do
|
182
|
+
@entry.updated.should be_nil
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'should be definable' do
|
186
|
+
@entry.updated = '1990-04-07'
|
187
|
+
@entry.updated.should == Time.parse('1990-04-07')
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'should be an xsd:DateTime' do
|
191
|
+
@entry.updated = '1990-04-07'
|
192
|
+
@entry.updated.to_s.should =~ /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'should be declarable as updated using #updated!' do
|
196
|
+
@entry.updated!
|
197
|
+
@entry.updated.should > Time.parse('1990-04-07')
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
describe 'app:edited element' do
|
202
|
+
include TestsXML
|
203
|
+
|
204
|
+
before(:each) do
|
205
|
+
@entry = Atom::Entry.new
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'should be nil if not defined' do
|
209
|
+
@entry.edited.should be_nil
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'should be definable' do
|
213
|
+
@entry.edited = '1990-04-07'
|
214
|
+
@entry.edited.should == Time.parse('1990-04-07')
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'should be an xsd:DateTime' do
|
218
|
+
@entry.edited = '1990-04-07'
|
219
|
+
@entry.edited.to_s.should =~ /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/
|
220
|
+
end
|
221
|
+
|
222
|
+
it 'should have APP namespace' do
|
223
|
+
@entry.edited = '1990-04-07'
|
224
|
+
read_entry_xml('app:edited').namespace.should == Atom::PP_NS
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'should be declarable as edited using #edited!' do
|
228
|
+
@entry.edited!
|
229
|
+
@entry.edited.should > Time.parse('1990-04-07')
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
describe 'category element' do
|
234
|
+
before(:each) do
|
235
|
+
@entry = Atom::Entry.new
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'should have no category on intializing' do
|
239
|
+
@entry.categories.should be_empty
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'should increase total count when adding a new category' do
|
243
|
+
@count = @entry.categories.length
|
244
|
+
@entry.categories.new['term'] = 'foo'
|
245
|
+
@entry.categories.length.should == @count + 1
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'should find category' do
|
249
|
+
category = @entry.categories.new
|
250
|
+
category['scheme'] = 'http://example.org/categories'
|
251
|
+
category['term'] = 'bar'
|
252
|
+
@entry.categories.select { |c| c['scheme'] == 'http://example.org/categories' }.should == [category]
|
253
|
+
end
|
254
|
+
|
255
|
+
describe 'when using tags' do
|
256
|
+
before(:each) do
|
257
|
+
@tags = %w(chunky bacon ruby)
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'should set categories from an array of tags' do
|
261
|
+
@entry.tag_with(@tags)
|
262
|
+
@entry.categories.length.should == 3
|
263
|
+
@tags.each { |tag| @entry.categories.any? { |c| c['term'] == tag }.should be_true }
|
264
|
+
end
|
265
|
+
|
266
|
+
it 'should set categories from a space-sperated string of tags' do
|
267
|
+
@entry.tag_with(@tags.join(' '))
|
268
|
+
@entry.categories.length.should == 3
|
269
|
+
@tags.each { |tag| @entry.categories.any? { |c| c['term'] == tag }.should be_true }
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'should be possible to specify the delimiter when passing tags as a string' do
|
273
|
+
@entry.tag_with(@tags.join(','), ',')
|
274
|
+
@entry.categories.length.should == 3
|
275
|
+
@tags.each { |tag| @entry.categories.any? { |c| c['term'] == tag }.should be_true }
|
276
|
+
end
|
277
|
+
|
278
|
+
it 'should create a category only once' do
|
279
|
+
@entry.tag_with(@tags)
|
280
|
+
@entry.tag_with(@tags.first)
|
281
|
+
@entry.categories.length.should == 3
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
describe 'edit url' do
|
287
|
+
before(:each) do
|
288
|
+
@entry = Atom::Entry.new
|
289
|
+
end
|
290
|
+
|
291
|
+
it 'should be nil on initializing' do
|
292
|
+
@entry.edit_url.should be_nil
|
293
|
+
end
|
294
|
+
|
295
|
+
it 'should be easily definable' do
|
296
|
+
@entry.edit_url = 'http://example.org/entries/foo'
|
297
|
+
@entry.edit_url.should == 'http://example.org/entries/foo'
|
298
|
+
end
|
299
|
+
|
300
|
+
it 'should not erase other links' do
|
301
|
+
link = @entry.links.new :rel => 'related', :href => 'http://example.org'
|
302
|
+
|
303
|
+
@entry.edit_url = 'http://example.com/entries/foo'
|
304
|
+
@entry.links.length.should == 2
|
305
|
+
@entry.links.should include(link)
|
306
|
+
end
|
307
|
+
|
308
|
+
it 'should accept a URI object' do
|
309
|
+
@entry.edit_url = URI.parse('http://example.com/entries/foo')
|
310
|
+
@entry.to_s.should =~ /example.com\/entries/
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
describe 'draft element' do
|
315
|
+
include TestsXML
|
316
|
+
|
317
|
+
before(:each) do
|
318
|
+
@entry = Atom::Entry.new
|
319
|
+
end
|
320
|
+
|
321
|
+
it 'should not be a draft by default' do
|
322
|
+
@entry.should_not be_draft
|
323
|
+
end
|
324
|
+
|
325
|
+
it 'should be definable using draft=' do
|
326
|
+
@entry.draft = true
|
327
|
+
@entry.should be_draft
|
328
|
+
@entry.draft = false
|
329
|
+
@entry.should_not be_draft
|
330
|
+
end
|
331
|
+
|
332
|
+
it 'should be declarable as a draft using #draft!' do
|
333
|
+
@entry.draft!
|
334
|
+
@entry.should be_draft
|
335
|
+
end
|
336
|
+
|
337
|
+
it 'should have APP namespace' do
|
338
|
+
@entry.draft!
|
339
|
+
read_entry_xml('app:control/app:draft').namespace.should == Atom::PP_NS
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
|
344
|
+
describe 'extensions' do
|
345
|
+
before(:each) do
|
346
|
+
@entry = Atom::Entry.parse(fixtures('entry-w-ext'))
|
347
|
+
end
|
348
|
+
|
349
|
+
it 'should preserve namespaces' do
|
350
|
+
@entry.to_s.should =~ /purl/
|
351
|
+
end
|
352
|
+
end
|
353
|
+
end
|
data/spec/ext_spec.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
require 'atom/entry'
|
4
|
+
|
5
|
+
module Atom
|
6
|
+
THR_NS = "http://purl.org/syndication/thread/1.0"
|
7
|
+
SLUG_NS = 'http://example.org/ns/slug'
|
8
|
+
|
9
|
+
class InReplyTo < Atom::Element
|
10
|
+
is_element THR_NS, :"in-reply-to"
|
11
|
+
|
12
|
+
atom_attrb :ref
|
13
|
+
atom_attrb :href
|
14
|
+
atom_attrb :type
|
15
|
+
atom_attrb :source
|
16
|
+
end
|
17
|
+
|
18
|
+
class Entry
|
19
|
+
attrb ['sl', SLUG_NS], 'slug'
|
20
|
+
element ['thr', THR_NS], :"in-reply-to", InReplyTo
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe Atom::Entry do
|
25
|
+
it 'should correctly write extension attributes' do
|
26
|
+
entry = Atom::Entry.new
|
27
|
+
entry.slug = 'hallo'
|
28
|
+
|
29
|
+
entry.to_s.should =~ /sl:slug/
|
30
|
+
entry.to_s.should =~ /xmlns:sl='#{Atom::SLUG_NS}'/
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'in-reply-to' do
|
34
|
+
it 'should be written with the correct namespace' do
|
35
|
+
entry = Atom::Entry.new
|
36
|
+
entry.in_reply_to = { :ref => 'http://example.org/some-entry' }
|
37
|
+
|
38
|
+
entry.to_s.should =~ /ref='http:\/\/example.org/
|
39
|
+
entry.to_s.should =~ Regexp.new(Atom::THR_NS)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/spec/feed_spec.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
require 'atom/feed'
|
4
|
+
|
5
|
+
describe Atom::Entry do
|
6
|
+
describe 'extensions' do
|
7
|
+
before(:each) do
|
8
|
+
@feed = Atom::Feed.parse(fixtures('feed-w-ext'))
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should preserve namespaces' do
|
12
|
+
@feed.to_s.should =~ /purl/
|
13
|
+
|
14
|
+
feed2 = Atom::Feed.new
|
15
|
+
feed2.merge! @feed
|
16
|
+
|
17
|
+
feed2.to_s.should =~ /purl/
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<entry xmlns="http://www.w3.org/2005/Atom"
|
2
|
+
xml:base='http://www.example.org/'
|
3
|
+
xmlns:thr='http://purl.org/syndication/thread/1.0'
|
4
|
+
xml:lang='en-us'>
|
5
|
+
<title>Extendy</title>
|
6
|
+
<link rel='replies' thr:count='2' type='application/xhtml+xml' href='Extendy#comments' />
|
7
|
+
<id>http://www.example.org/Extendy.atom</id>
|
8
|
+
<published>2008-03-15T02:00:00-07:00</published>
|
9
|
+
<updated>2008-03-15T18:10:25-07:00</updated>
|
10
|
+
<content type='xhtml'>
|
11
|
+
<div xmlns='http://www.w3.org/1999/xhtml'>
|
12
|
+
<p>Extensions ahoy!</p>
|
13
|
+
</div>
|
14
|
+
</content>
|
15
|
+
</entry>
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<entry xmlns="http://www.w3.org/2005/Atom"
|
2
|
+
xmlns:app="http://www.w3.org/2007/app">
|
3
|
+
<title>Atom draft-07 snapshot</title>
|
4
|
+
<link rel="alternate" type="text/html"
|
5
|
+
href="http://example.org/2005/04/02/atom"/>
|
6
|
+
<link rel="enclosure" type="audio/mpeg" length="1337"
|
7
|
+
href="http://example.org/audio/ph34r_my_podcast.mp3"/>
|
8
|
+
<source>
|
9
|
+
<title>Atom Sample Feed</title>
|
10
|
+
<id>tag:example.org,2003:/</id>
|
11
|
+
<link rel="self" href="http://example.org/feed"/>
|
12
|
+
<contributor>
|
13
|
+
<name>Mark Pilgrim</name>
|
14
|
+
</contributor>
|
15
|
+
</source>
|
16
|
+
<rights>Copyright (c) 2003, Mark Pilgrim</rights>
|
17
|
+
<id>tag:example.org,2003:3.2397</id>
|
18
|
+
<updated>2005-07-31T12:29:29Z</updated>
|
19
|
+
<published>2003-12-13T08:29:29-04:00</published>
|
20
|
+
<app:edited>2005-07-31T12:29:29Z</app:edited>
|
21
|
+
<app:control><app:draft>yes</app:draft></app:control>
|
22
|
+
<author>
|
23
|
+
<name>Mark Pilgrim</name>
|
24
|
+
<uri>http://example.org/</uri>
|
25
|
+
<email>f8dy@example.com</email>
|
26
|
+
</author>
|
27
|
+
<contributor>
|
28
|
+
<name>Sam Ruby</name>
|
29
|
+
</contributor>
|
30
|
+
<contributor>
|
31
|
+
<name>Joe Gregorio</name>
|
32
|
+
</contributor>
|
33
|
+
<summary>Some text.</summary>
|
34
|
+
<category scheme="http://example.org/cats" term="ann" />
|
35
|
+
<content type="xhtml" xml:lang="en"
|
36
|
+
xml:base="http://diveintomark.org/">
|
37
|
+
<div xmlns="http://www.w3.org/1999/xhtml">
|
38
|
+
<p><i>[Update: The Atom draft is finished.]</i></p>
|
39
|
+
</div>
|
40
|
+
</content>
|
41
|
+
</entry>
|
42
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<feed xmlns='http://www.w3.org/2005/Atom'
|
2
|
+
xmlns:thr='http://purl.org/syndication/thread/1.0'
|
3
|
+
xml:base='http://www.tbray.org/ongoing/ongoing.atom'
|
4
|
+
xml:lang='en-us'>
|
5
|
+
<title>ongoing</title>
|
6
|
+
<id>http://www.tbray.org/ongoing/</id>
|
7
|
+
<link href='./' />
|
8
|
+
<link rel='self' href='' />
|
9
|
+
<link rel='replies' thr:count='101' href='/home/tbray.org/www/html/ongoing/comments.atom' />
|
10
|
+
<logo>rsslogo.jpg</logo>
|
11
|
+
<icon>/favicon.ico</icon>
|
12
|
+
<updated>2008-03-17T02:04:49-07:00</updated>
|
13
|
+
<author><name>Tim Bray</name></author>
|
14
|
+
<subtitle>ongoing fragmented essay by Tim Bray</subtitle>
|
15
|
+
<rights>All content written by Tim Bray and photos by Tim Bray Copyright Tim Bray, some rights reserved, see /ongoing/misc/Copyright</rights>
|
16
|
+
<generator uri='/misc/Colophon'>Generated from XML source code using Perl, Expat, Emacs, Mysql, Ruby, Java, and ImageMagick. Industrial-strength technology, baby.</generator>
|
17
|
+
<entry xml:base='When/200x/2008/03/13/'>
|
18
|
+
<title>Maui Bound</title>
|
19
|
+
<link href='Maui' />
|
20
|
+
<link rel='replies' thr:count='1' type='application/xhtml+xml' href='Maui#comments' />
|
21
|
+
<id>http://www.tbray.org/ongoing/When/200x/2008/03/13/Maui</id>
|
22
|
+
<published>2008-03-13T02:00:00-07:00</published>
|
23
|
+
<updated>2008-03-13T17:23:47-07:00</updated>
|
24
|
+
<category scheme='http://www.tbray.org/ongoing/What/' term='The World/Places/Hawaii' />
|
25
|
+
<category scheme='http://www.tbray.org/ongoing/What/' term='The World' />
|
26
|
+
<category scheme='http://www.tbray.org/ongoing/What/' term='Places' />
|
27
|
+
<category scheme='http://www.tbray.org/ongoing/What/' term='Hawaii' />
|
28
|
+
<content type='xhtml'><div xmlns='http://www.w3.org/1999/xhtml'>
|
29
|
+
<p>I’m off with the family tomorrow for ten days in Maui, 15th through the
|
30
|
+
24th. We’ll be meeting an Aussie friend. Anyone else I know who’ll be there,
|
31
|
+
drop me a line and we’ll get together for a Mai Tai.</p>
|
32
|
+
</div></content></entry>
|
33
|
+
</feed>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<service xmlns="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
3
|
+
<workspace title="Yulup Demo">
|
4
|
+
<atom:title type="text">Yulup Demo</atom:title>
|
5
|
+
|
6
|
+
<collection title="Releases" href="../entries/?yanel.resource.viewid=atom">
|
7
|
+
<atom:title type="html">Early Yulup <i>Releases</i></atom:title>
|
8
|
+
</collection>
|
9
|
+
</workspace>
|
10
|
+
|
11
|
+
<workspace title="Yulup Website">
|
12
|
+
<atom:title type="text">Yulup Website</atom:title>
|
13
|
+
|
14
|
+
<collection title="Releases" href="http://www.yulup.org/download/release-atom-entries/?yanel.resource.viewid=atom">
|
15
|
+
<atom:title type="xhtml"><xhtml:div>Yulup <xhtml:b>Releases</xhtml:b>
|
16
|
+
</xhtml:div>
|
17
|
+
</atom:title>
|
18
|
+
|
19
|
+
</collection>
|
20
|
+
</workspace>
|
21
|
+
</service>
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<?xml version="1.0" encoding='utf-8'?>
|
2
|
+
<service xmlns="http://www.w3.org/2007/app"
|
3
|
+
xmlns:atom="http://www.w3.org/2005/Atom">
|
4
|
+
<workspace>
|
5
|
+
<atom:title>Main Site</atom:title>
|
6
|
+
<collection
|
7
|
+
href="http://example.org/blog/main" >
|
8
|
+
<atom:title>My Blog Entries</atom:title>
|
9
|
+
<categories
|
10
|
+
href="http://example.com/cats/forMain.cats" />
|
11
|
+
</collection>
|
12
|
+
<collection
|
13
|
+
href="http://example.org/blog/pic" >
|
14
|
+
<atom:title>Pictures</atom:title>
|
15
|
+
<accept>image/png</accept>
|
16
|
+
<accept>image/jpeg</accept>
|
17
|
+
<accept>image/gif</accept>
|
18
|
+
</collection>
|
19
|
+
</workspace>
|
20
|
+
<workspace>
|
21
|
+
<atom:title>Sidebar Blog</atom:title>
|
22
|
+
<collection
|
23
|
+
href="http://example.org/sidebar/list" >
|
24
|
+
<atom:title>Remaindered Links</atom:title>
|
25
|
+
<accept>application/atom+xml;type=entry</accept>
|
26
|
+
<categories fixed="yes">
|
27
|
+
<atom:category
|
28
|
+
scheme="http://example.org/extra-cats/"
|
29
|
+
term="joke" />
|
30
|
+
<atom:category
|
31
|
+
scheme="http://example.org/extra-cats/"
|
32
|
+
term="serious" />
|
33
|
+
</categories>
|
34
|
+
</collection>
|
35
|
+
</workspace>
|
36
|
+
</service>
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
require 'atom/service'
|
4
|
+
|
5
|
+
describe Atom::Service do
|
6
|
+
describe 'when parsing' do
|
7
|
+
before(:each) do
|
8
|
+
@service = Atom::Service.parse(fixtures(:service))
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should parse workspace elements correctly' do
|
12
|
+
@service.workspaces.length.should == 2
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should absolutize relative hrefs' do
|
16
|
+
svc = Atom::Service.parse(
|
17
|
+
fixtures('service-w-xhtml-ns'),
|
18
|
+
'http://example.org/introspection/')
|
19
|
+
|
20
|
+
coll = svc.workspaces.first.collections.first
|
21
|
+
coll.href.should == "http://example.org/entries/?yanel.resource.viewid=atom"
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should parse XHTML outside the default namespace correctly' do
|
25
|
+
xhtml_svc = Atom::Service.parse(fixtures('service-w-xhtml-ns'))
|
26
|
+
|
27
|
+
xhtml_svc.workspaces.length.should == 2
|
28
|
+
xhtml_coll = xhtml_svc.workspaces.last.collections.first
|
29
|
+
xhtml_coll.title.html.strip.should == 'Yulup <b>Releases</b>'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe Atom::Workspace do
|
35
|
+
describe 'when parsing' do
|
36
|
+
before(:each) do
|
37
|
+
svc = Atom::Service.parse(fixtures(:service))
|
38
|
+
@main = svc.workspaces.first
|
39
|
+
@sidebar = svc.workspaces.last
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should parse title element correctly' do
|
43
|
+
@main.title.to_s.should == 'Main Site'
|
44
|
+
@sidebar.title.to_s.should == 'Sidebar Blog'
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should parse collection elements correctly' do
|
48
|
+
@main.collections.length.should == 2
|
49
|
+
@sidebar.collections.length.should == 1
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe Atom::Collection do
|
55
|
+
describe 'when parsing' do
|
56
|
+
before(:each) do
|
57
|
+
svc = Atom::Service.parse(fixtures(:service))
|
58
|
+
@entries = svc.workspaces.first.collections.first
|
59
|
+
@pictures = svc.workspaces.first.collections.last
|
60
|
+
@links = svc.workspaces.last.collections.first
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should parse href correctly' do
|
64
|
+
@entries.href.should == 'http://example.org/blog/main'
|
65
|
+
@entries.feed.uri.to_s.should == 'http://example.org/blog/main'
|
66
|
+
|
67
|
+
@pictures.href.should == 'http://example.org/blog/pic'
|
68
|
+
@links.href.should == 'http://example.org/sidebar/list'
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should parse title element correctly' do
|
72
|
+
@entries.title.to_s.should == 'My Blog Entries'
|
73
|
+
@pictures.title.to_s.should == 'Pictures'
|
74
|
+
@links.title.to_s.should == 'Remaindered Links'
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should parse accept elements correctly' do
|
78
|
+
@entries.accepts.should == ['application/atom+xml;type=entry']
|
79
|
+
@pictures.accepts.should == ['image/png', 'image/jpeg', 'image/gif']
|
80
|
+
@links.accepts.should == ['application/atom+xml;type=entry']
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe Atom::Categories do
|
86
|
+
describe 'when parsing' do
|
87
|
+
before(:each) do
|
88
|
+
svc = Atom::Service.parse(fixtures(:service))
|
89
|
+
@ool = svc.workspaces.first.collections.first.categories.first
|
90
|
+
@il = svc.workspaces.last.collections.first.categories.first
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should parse out-of-line categories correctly' do
|
94
|
+
@ool.href.should == 'http://example.com/cats/forMain.cats'
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should parse inline categories correctly' do
|
98
|
+
@il.fixed.should be_true
|
99
|
+
|
100
|
+
@il.list.length.should == 2
|
101
|
+
|
102
|
+
@il.list.first.scheme.should == 'http://example.org/extra-cats/'
|
103
|
+
@il.list.first.term.should == 'joke'
|
104
|
+
|
105
|
+
@il.list.last.term.should == 'serious'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: atom-tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brendan Taylor
|
@@ -9,11 +9,16 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-08-15 00:00:00 +00:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
|
-
description:
|
16
|
+
description: |-
|
17
|
+
atom-tools is an all-in-one Atom library. It parses and builds Atom (RFC 4287) entries and feeds, and manipulates Atom Publishing Protocol (RFC 5023) Collections.
|
18
|
+
|
19
|
+
It also comes with a set of commandline utilities for working with AtomPub Collections.
|
20
|
+
|
21
|
+
It is not the fastest Ruby Atom library, but it is comprehensive and makes handling extensions to the Atom format very easy.
|
17
22
|
email: whateley@gmail.com
|
18
23
|
executables: []
|
19
24
|
|
@@ -34,7 +39,6 @@ files:
|
|
34
39
|
- test/runtests.rb
|
35
40
|
- test/test_feed.rb
|
36
41
|
- test/test_protocol.rb
|
37
|
-
- test/conformance
|
38
42
|
- test/conformance/updated.rb
|
39
43
|
- test/conformance/xmlnamespace.rb
|
40
44
|
- test/conformance/title.rb
|
@@ -43,7 +47,16 @@ files:
|
|
43
47
|
- test/test_xml.rb
|
44
48
|
- test/test_http.rb
|
45
49
|
- test/test_general.rb
|
46
|
-
-
|
50
|
+
- spec/entry_spec.rb
|
51
|
+
- spec/ext_spec.rb
|
52
|
+
- spec/spec_helper.rb
|
53
|
+
- spec/feed_spec.rb
|
54
|
+
- spec/fixtures/feed-w-ext.xml
|
55
|
+
- spec/fixtures/service-w-xhtml-ns.xml
|
56
|
+
- spec/fixtures/entry-w-ext.xml
|
57
|
+
- spec/fixtures/service.xml
|
58
|
+
- spec/fixtures/entry.xml
|
59
|
+
- spec/service_spec.rb
|
47
60
|
- lib/atom/cache.rb
|
48
61
|
- lib/atom/feed.rb
|
49
62
|
- lib/atom/text.rb
|
@@ -54,7 +67,9 @@ files:
|
|
54
67
|
- lib/atom/element.rb
|
55
68
|
- lib/atom/http.rb
|
56
69
|
has_rdoc: true
|
57
|
-
homepage: http://
|
70
|
+
homepage: http://github.com/bct/atom-tools/wikis
|
71
|
+
licenses: []
|
72
|
+
|
58
73
|
post_install_message:
|
59
74
|
rdoc_options: []
|
60
75
|
|
@@ -75,9 +90,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
90
|
requirements: []
|
76
91
|
|
77
92
|
rubyforge_project: ibes
|
78
|
-
rubygems_version: 1.3.
|
93
|
+
rubygems_version: 1.3.2
|
79
94
|
signing_key:
|
80
|
-
specification_version:
|
81
|
-
summary: Tools for working with Atom Entries, Feeds and Collections
|
95
|
+
specification_version: 3
|
96
|
+
summary: Tools for working with Atom Entries, Feeds and Collections.
|
82
97
|
test_files:
|
83
98
|
- test/runtests.rb
|