atom-tools 0.9.2 → 0.9.3
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/README +2 -2
- data/Rakefile +1 -1
- data/bin/atom-client.rb +71 -45
- data/lib/atom/element.rb +7 -2
- data/lib/atom/entry.rb +51 -16
- data/lib/atom/feed.rb +6 -6
- data/lib/atom/http.rb +23 -19
- data/lib/atom/service.rb +0 -2
- data/lib/atom/text.rb +34 -12
- data/lib/atom/xml.rb +26 -17
- data/lib/atom/yaml.rb +23 -8
- data/test/test_constructs.rb +16 -2
- data/test/test_general.rb +22 -9
- data/test/test_http.rb +12 -8
- data/test/test_xml.rb +66 -20
- metadata +4 -40
- data/doc/classes/Atom/Author.html +0 -130
- data/doc/classes/Atom/Category.html +0 -128
- data/doc/classes/Atom/Collection.html +0 -322
- data/doc/classes/Atom/Content.html +0 -129
- data/doc/classes/Atom/Contributor.html +0 -119
- data/doc/classes/Atom/DigestAuth.html +0 -285
- data/doc/classes/Atom/Element.html +0 -325
- data/doc/classes/Atom/Entry.html +0 -369
- data/doc/classes/Atom/Feed.html +0 -595
- data/doc/classes/Atom/HTTP.html +0 -436
- data/doc/classes/Atom/HTTPResponse.html +0 -149
- data/doc/classes/Atom/Link.html +0 -137
- data/doc/classes/Atom/Service.html +0 -260
- data/doc/classes/Atom/Text.html +0 -245
- data/doc/classes/Atom/Workspace.html +0 -121
- data/doc/classes/XHTML.html +0 -118
- data/doc/created.rid +0 -1
- data/doc/files/README.html +0 -213
- data/doc/files/lib/atom/collection_rb.html +0 -110
- data/doc/files/lib/atom/element_rb.html +0 -109
- data/doc/files/lib/atom/entry_rb.html +0 -111
- data/doc/files/lib/atom/feed_rb.html +0 -112
- data/doc/files/lib/atom/http_rb.html +0 -112
- data/doc/files/lib/atom/service_rb.html +0 -111
- data/doc/files/lib/atom/text_rb.html +0 -109
- data/doc/files/lib/atom/xml_rb.html +0 -110
- data/doc/files/lib/atom/yaml_rb.html +0 -109
- data/doc/fr_class_index.html +0 -42
- data/doc/fr_file_index.html +0 -36
- data/doc/fr_method_index.html +0 -69
- data/doc/index.html +0 -24
- data/doc/rdoc-style.css +0 -208
data/lib/atom/service.rb
CHANGED
data/lib/atom/text.rb
CHANGED
@@ -4,11 +4,19 @@ module XHTML
|
|
4
4
|
NS = "http://www.w3.org/1999/xhtml"
|
5
5
|
end
|
6
6
|
|
7
|
-
module Atom
|
7
|
+
module Atom
|
8
8
|
# An Atom::Element representing a text construct.
|
9
|
-
# It has a single attribute, "type", which
|
10
|
-
#
|
11
|
-
|
9
|
+
# It has a single attribute, "type", which specifies how to interpret
|
10
|
+
# the element's content. Different types are:
|
11
|
+
#
|
12
|
+
# text:: a plain string, without any markup (default)
|
13
|
+
# html:: a chunk of HTML
|
14
|
+
# xhtml:: a chunk of *well-formed* XHTML
|
15
|
+
#
|
16
|
+
# You should set this attribute appropriately after you set a Text
|
17
|
+
# element (entry.content, entry.title or entry.summary).
|
18
|
+
#
|
19
|
+
# This content of this element can be retrieved in different formats, see #html and #xml
|
12
20
|
class Text < Atom::Element
|
13
21
|
attrb :type
|
14
22
|
|
@@ -16,19 +24,24 @@ module Atom
|
|
16
24
|
@content = value
|
17
25
|
@content ||= "" # in case of nil
|
18
26
|
self["type"] = "text"
|
19
|
-
|
27
|
+
|
20
28
|
super name
|
21
29
|
end
|
22
30
|
|
31
|
+
# convenient, but not overly useful. see #html instead.
|
23
32
|
def to_s
|
24
|
-
if self["type"] == "xhtml"
|
33
|
+
if self["type"] == "xhtml"
|
25
34
|
@content.children.to_s
|
26
35
|
else
|
27
36
|
@content.to_s
|
28
37
|
end
|
29
38
|
end
|
30
39
|
|
31
|
-
# returns a string suitable for dumping into an HTML document
|
40
|
+
# returns a string suitable for dumping into an HTML document.
|
41
|
+
# (or nil if that's impossible)
|
42
|
+
#
|
43
|
+
# if you're storing the content of a Text construct, you probably
|
44
|
+
# want this representation.
|
32
45
|
def html
|
33
46
|
if self["type"] == "xhtml" or self["type"] == "html"
|
34
47
|
to_s
|
@@ -40,7 +53,7 @@ module Atom
|
|
40
53
|
# attempts to parse the content of this element as XML and return it
|
41
54
|
# as an array of REXML::Elements.
|
42
55
|
#
|
43
|
-
# If
|
56
|
+
# If self["type"] is "html" and Hpricot is installed, it will
|
44
57
|
# be converted to XHTML first.
|
45
58
|
def xml
|
46
59
|
if self["type"] == "xhtml"
|
@@ -83,7 +96,7 @@ module Atom
|
|
83
96
|
|
84
97
|
super(key, value)
|
85
98
|
end
|
86
|
-
|
99
|
+
|
87
100
|
def to_element # :nodoc:
|
88
101
|
e = super
|
89
102
|
|
@@ -106,18 +119,19 @@ module Atom
|
|
106
119
|
|
107
120
|
e
|
108
121
|
end
|
109
|
-
|
122
|
+
|
110
123
|
private
|
124
|
+
# converts @content based on the value of self["type"]
|
111
125
|
def convert_contents e
|
112
126
|
if self["type"] == "xhtml"
|
113
127
|
@content
|
114
128
|
elsif self["type"] == "text" or self["type"].nil?
|
115
129
|
REXML::Text.normalize(@content.to_s)
|
116
130
|
elsif self["type"] == "html"
|
117
|
-
@content.to_s
|
131
|
+
@content.to_s.gsub(/&/, "&")
|
118
132
|
end
|
119
133
|
end
|
120
|
-
|
134
|
+
|
121
135
|
def valid_type? type
|
122
136
|
["text", "xhtml", "html"].member? type
|
123
137
|
end
|
@@ -154,6 +168,14 @@ module Atom
|
|
154
168
|
class Content < Atom::Text
|
155
169
|
attrb :src
|
156
170
|
|
171
|
+
def html
|
172
|
+
if self["src"]
|
173
|
+
""
|
174
|
+
else
|
175
|
+
super
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
157
179
|
private
|
158
180
|
def valid_type? type
|
159
181
|
super or type.match(/\//)
|
data/lib/atom/xml.rb
CHANGED
@@ -28,11 +28,22 @@ module REXML # :nodoc: all
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
def
|
31
|
+
def copy_extensions(coll)
|
32
32
|
# XXX also look for attributes
|
33
|
-
children.find_all
|
33
|
+
children.find_all do |child|
|
34
|
+
child.respond_to? :namespace and child.namespace != Atom::NS
|
35
|
+
end.each do |elem|
|
36
|
+
e = elem.dup
|
37
|
+
|
38
|
+
# because namespaces might be defined on parents
|
39
|
+
unless e.prefix.empty?
|
40
|
+
e.add_namespace e.prefix, e.namespace
|
41
|
+
end
|
42
|
+
|
43
|
+
coll << e
|
44
|
+
end
|
34
45
|
end
|
35
|
-
|
46
|
+
|
36
47
|
# get the text content of a descendant element in the Atom namespace
|
37
48
|
def get_atom_text name
|
38
49
|
elem = get_atom_element name
|
@@ -54,14 +65,14 @@ module REXML # :nodoc: all
|
|
54
65
|
|
55
66
|
self.attributes[attr]
|
56
67
|
end
|
57
|
-
|
68
|
+
|
58
69
|
def fill_text_construct(entry, name)
|
59
70
|
text = get_atom_element(name)
|
60
71
|
if text
|
61
72
|
type = text.ns_attr("type")
|
62
73
|
src = text.ns_attr("src")
|
63
74
|
|
64
|
-
if src and name == :content
|
75
|
+
if src and name == :content
|
65
76
|
# the only content is out of line
|
66
77
|
entry.send( "#{name}=".to_sym, "")
|
67
78
|
entry.send(name.to_sym)["src"] = src
|
@@ -74,10 +85,10 @@ module REXML # :nodoc: all
|
|
74
85
|
# content is the serialized content of the <div> wrapper
|
75
86
|
entry.send( "#{name}=".to_sym, div )
|
76
87
|
else
|
77
|
-
raw = text.text
|
88
|
+
raw = text.text || ""
|
78
89
|
entry.send( "#{name}=", raw )
|
79
90
|
end
|
80
|
-
|
91
|
+
|
81
92
|
if text.attributes["xml:base"]
|
82
93
|
entry.send(name.to_sym).base = text.attributes["xml:base"]
|
83
94
|
end
|
@@ -91,7 +102,7 @@ module REXML # :nodoc: all
|
|
91
102
|
def fill_elem_element(top, kind)
|
92
103
|
each_atom_element(kind) do |elem|
|
93
104
|
person = top.send("#{kind}s".to_sym).new
|
94
|
-
|
105
|
+
|
95
106
|
["name", "uri", "email"].each do |name|
|
96
107
|
person.send("#{name}=".to_sym, elem.get_atom_text(name))
|
97
108
|
end
|
@@ -105,7 +116,11 @@ module REXML # :nodoc: all
|
|
105
116
|
thing.class.attrs.each do |name,req|
|
106
117
|
value = elem.ns_attr name.to_s
|
107
118
|
if value and name == :href
|
108
|
-
|
119
|
+
begin
|
120
|
+
thing[name.to_s] = (top.base.to_uri + value).to_s
|
121
|
+
rescue URI::BadURIError
|
122
|
+
raise "Document contains relative URIs and no xml:base. You must pass a base URI to #parse()"
|
123
|
+
end
|
109
124
|
elsif value
|
110
125
|
thing[name.to_s] = value
|
111
126
|
end
|
@@ -145,10 +160,7 @@ module REXML # :nodoc: all
|
|
145
160
|
fill_attr_element(entry, v, k)
|
146
161
|
end
|
147
162
|
|
148
|
-
|
149
|
-
get_extensions.each do |elem|
|
150
|
-
entry.extensions << elem.dup # otherwise they get removed from the doc
|
151
|
-
end
|
163
|
+
copy_extensions(entry.extensions)
|
152
164
|
|
153
165
|
entry
|
154
166
|
end
|
@@ -189,10 +201,7 @@ module REXML # :nodoc: all
|
|
189
201
|
feed << elem.to_atom_entry(feed.base)
|
190
202
|
end
|
191
203
|
|
192
|
-
|
193
|
-
# have to duplicate them, or they'll get removed from the doc
|
194
|
-
feed.extensions << elem.dup
|
195
|
-
end
|
204
|
+
copy_extensions(feed.extensions)
|
196
205
|
|
197
206
|
feed
|
198
207
|
end
|
data/lib/atom/yaml.rb
CHANGED
@@ -62,36 +62,51 @@ module Atom
|
|
62
62
|
def to_yaml_type # :nodoc:
|
63
63
|
'!necronomicorp.com,2006/entry'
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
|
+
def to_yaml( opts = {} ) # :nodoc:
|
67
|
+
YAML::quick_emit( object_id, opts ) do |out|
|
68
|
+
out.map( taguri, to_yaml_style ) do |map|
|
69
|
+
self.to_yaml_properties.each do |m|
|
70
|
+
map.add( m[1..-1], instance_variable_get( m ) )
|
71
|
+
end
|
72
|
+
map.add("draft", true) if self.draft
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
66
77
|
# parses an Atom::Entry from YAML
|
67
78
|
def self.from_yaml yaml
|
68
79
|
hash = if yaml.kind_of?(Hash); yaml else YAML.load(yaml); end
|
69
80
|
|
70
81
|
entry = Atom::Entry.new
|
71
82
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
83
|
+
["id", "published", "updated", "title", "summary", "draft"].each do |name|
|
84
|
+
entry.send("#{name}=".to_sym, hash[name])
|
85
|
+
end
|
86
|
+
|
87
|
+
elem_constructs = {"authors" => entry.authors,
|
88
|
+
"contributors" => entry.contributors,
|
89
|
+
"links" => entry.links,
|
90
|
+
"categories" => entry.categories}
|
76
91
|
|
77
92
|
elem_constructs.each do |type,ary|
|
78
93
|
hash[type] ||= []
|
79
|
-
|
94
|
+
|
80
95
|
hash[type].each do |yelem|
|
81
96
|
elem = ary.new
|
82
97
|
|
83
98
|
elem.class.attrs.each do |attrb,req|
|
84
99
|
elem[attrb.to_s] = yelem[attrb.to_s]
|
85
100
|
end
|
86
|
-
|
101
|
+
|
87
102
|
elem.class.elements.each do |name,kind,req|
|
88
103
|
elem.send("#{name}=".to_sym, yelem[name.to_s])
|
89
104
|
end
|
90
105
|
end
|
91
106
|
end
|
92
107
|
|
93
|
-
# this adds more categories, and could cause conflicts
|
94
108
|
entry.tag_with hash["tags"]
|
109
|
+
|
95
110
|
entry.content = hash["content"]
|
96
111
|
entry.content["type"] = hash["type"] if hash["type"]
|
97
112
|
|
data/test/test_constructs.rb
CHANGED
@@ -44,12 +44,12 @@ END
|
|
44
44
|
assert_equal "This really is a horrendous mess.", last.text
|
45
45
|
=end
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def test_text_construct_text
|
49
49
|
entry = Atom::Entry.new
|
50
50
|
|
51
51
|
assert_nil entry.title
|
52
|
-
assert_equal "", entry.title.to_s
|
52
|
+
assert_equal "", entry.title.to_s
|
53
53
|
|
54
54
|
entry.title = "<3"
|
55
55
|
|
@@ -124,6 +124,20 @@ END
|
|
124
124
|
assert_equal("", entry.content.to_s)
|
125
125
|
end
|
126
126
|
|
127
|
+
def test_multiple
|
128
|
+
entry = Atom::Entry.new
|
129
|
+
|
130
|
+
link = Atom::Link.new
|
131
|
+
link["href"] = "http://example.org/"
|
132
|
+
|
133
|
+
assert_raises(ArgumentError) { entry.authors << "test" }
|
134
|
+
assert_raises(ArgumentError) { entry.authors << link }
|
135
|
+
|
136
|
+
entry.links << link
|
137
|
+
|
138
|
+
assert_equal 1, entry.links.length
|
139
|
+
end
|
140
|
+
|
127
141
|
require "date"
|
128
142
|
def test_date_construct
|
129
143
|
today = Date.today
|
data/test/test_general.rb
CHANGED
@@ -46,30 +46,43 @@ class AtomTest < Test::Unit::TestCase
|
|
46
46
|
assert_has_category(xml, "tags")
|
47
47
|
end
|
48
48
|
|
49
|
-
def
|
50
|
-
|
49
|
+
def test_devour_yaml
|
50
|
+
time = Time.parse "2007-01-18T12:37:46Z"
|
51
|
+
|
52
|
+
yaml = <<END
|
53
|
+
title: testing YAML
|
54
|
+
draft: yes
|
55
|
+
|
51
56
|
authors:
|
52
57
|
- name: Mr. Safe
|
53
58
|
uri: http://example.com/
|
59
|
+
|
54
60
|
links:
|
55
61
|
- href: http://atomenabled.org/
|
56
|
-
|
57
|
-
|
62
|
+
|
63
|
+
content: not much here
|
64
|
+
|
65
|
+
updated: #{time.iso8601}
|
66
|
+
END
|
58
67
|
|
59
68
|
entry = Atom::Entry.from_yaml(yaml)
|
60
69
|
|
61
70
|
assert_equal("testing YAML", entry.title.to_s)
|
62
71
|
|
72
|
+
assert entry.draft
|
73
|
+
|
63
74
|
assert_equal(1, entry.authors.length)
|
64
75
|
assert_equal("Mr. Safe", entry.authors.first.name)
|
65
76
|
assert_equal("http://example.com/", entry.authors.first.uri)
|
66
|
-
|
77
|
+
|
67
78
|
assert_equal(1, entry.links.length)
|
68
79
|
assert_equal("http://atomenabled.org/", entry.links.first["href"])
|
69
80
|
|
70
81
|
assert_equal("not much here", entry.content.to_s)
|
82
|
+
|
83
|
+
assert_equal(time, entry.updated)
|
71
84
|
end
|
72
|
-
|
85
|
+
|
73
86
|
def assert_has_category xml, term
|
74
87
|
assert_not_nil(REXML::XPath.match(xml, "/entry/category[@term = #{term}]"))
|
75
88
|
end
|
@@ -85,10 +98,10 @@ content: not much here\
|
|
85
98
|
def get_elements entry
|
86
99
|
xml = entry.to_xml
|
87
100
|
|
88
|
-
assert_equal(entry.to_s, Atom::Entry.parse(xml).to_s)
|
89
|
-
|
101
|
+
assert_equal(entry.to_s, Atom::Entry.parse(xml).to_s)
|
102
|
+
|
90
103
|
base_check xml
|
91
|
-
|
104
|
+
|
92
105
|
xml
|
93
106
|
end
|
94
107
|
|
data/test/test_http.rb
CHANGED
@@ -150,24 +150,31 @@ class AtomHTTPTest < Test::Unit::TestCase
|
|
150
150
|
# no credentials
|
151
151
|
assert_raises(Atom::Unauthorized) { get_root }
|
152
152
|
|
153
|
+
# incorrect credentials
|
153
154
|
@http.user = USER
|
154
155
|
@http.pass = "incorrect_password"
|
155
156
|
|
156
157
|
one_shot
|
157
158
|
|
158
|
-
# incorrect credentials
|
159
159
|
assert_raises(Atom::Unauthorized) { get_root }
|
160
160
|
|
161
|
+
# no credentials, fancy block
|
162
|
+
@http.when_auth do nil end
|
163
|
+
|
164
|
+
one_shot
|
165
|
+
|
166
|
+
assert_raises(Atom::Unauthorized) { get_root }
|
167
|
+
|
168
|
+
# correct credentials, fancy block
|
161
169
|
@http.when_auth do |abs_url,realm|
|
162
170
|
assert_equal "http://localhost:#{@port}/", abs_url
|
163
171
|
assert_equal REALM, realm
|
164
172
|
|
165
173
|
[USER, PASS]
|
166
174
|
end
|
167
|
-
|
175
|
+
|
168
176
|
one_shot
|
169
|
-
|
170
|
-
# correct credentials
|
177
|
+
|
171
178
|
assert_authenticates
|
172
179
|
end
|
173
180
|
|
@@ -218,11 +225,8 @@ class AtomHTTPTest < Test::Unit::TestCase
|
|
218
225
|
assert_equal USER, p[:Username]
|
219
226
|
assert_match /^UsernameToken /, xwsse
|
220
227
|
|
221
|
-
# un-base64 in preparation for SHA1-ing
|
222
|
-
nonce = p[:Nonce].unpack("m").first
|
223
|
-
|
224
228
|
# Base64( SHA1( Nonce + CreationTimestamp + Password ) )
|
225
|
-
pd_string =
|
229
|
+
pd_string = p[:Nonce] + p[:Created] + PASS
|
226
230
|
password_digest = [Digest::SHA1.digest(pd_string)].pack("m").chomp
|
227
231
|
|
228
232
|
assert_equal password_digest, p[:PasswordDigest]
|
data/test/test_xml.rb
CHANGED
@@ -6,12 +6,12 @@ require "atom/service"
|
|
6
6
|
class AtomTest < Test::Unit::TestCase
|
7
7
|
def test_text_type_text
|
8
8
|
entry = get_entry
|
9
|
-
|
9
|
+
|
10
10
|
entry.title = "Atom-drunk pirates run amok!"
|
11
11
|
assert_equal("text", entry.title["type"])
|
12
12
|
|
13
13
|
xml = get_elements entry
|
14
|
-
|
14
|
+
|
15
15
|
assert_equal("Atom-drunk pirates run amok!", xml.elements["/entry/title"].text)
|
16
16
|
end
|
17
17
|
|
@@ -34,17 +34,26 @@ class AtomTest < Test::Unit::TestCase
|
|
34
34
|
entry.title["type"] = "xhtml"
|
35
35
|
|
36
36
|
xml = get_elements entry
|
37
|
-
|
37
|
+
|
38
38
|
base_check xml
|
39
39
|
|
40
40
|
assert_equal(XHTML::NS, xml.elements["/entry/title/div"].namespace)
|
41
41
|
assert_equal("run amok", xml.elements["/entry/title/div/em"].text)
|
42
42
|
end
|
43
43
|
|
44
|
+
def test_html_text_with_entities
|
45
|
+
entry = get_entry
|
46
|
+
|
47
|
+
entry.title = "Atoms discovered to be smaller than 1μm"
|
48
|
+
entry.title["type"] = "html"
|
49
|
+
|
50
|
+
assert_match(/&mu;/, entry.to_s)
|
51
|
+
end
|
52
|
+
|
44
53
|
def test_author
|
45
54
|
entry = get_entry
|
46
55
|
a = entry.authors.new
|
47
|
-
|
56
|
+
|
48
57
|
a.name= "Brendan Taylor"
|
49
58
|
a.uri = "http://necronomicorp.com/blog/"
|
50
59
|
|
@@ -111,6 +120,32 @@ class AtomTest < Test::Unit::TestCase
|
|
111
120
|
assert_equal("http://purl.org/", xml.elements["/entry/test"].namespace)
|
112
121
|
end
|
113
122
|
|
123
|
+
def test_roundtrip_extension
|
124
|
+
entry = Atom::Entry.parse("<entry xmlns='http://www.w3.org/2005/Atom' xmlns:nil='http://necronomicorp.com/nil'><nil:ext/></entry>")
|
125
|
+
|
126
|
+
assert_match(/xmlns:nil='http:\/\/necronomicorp.com\/nil'/, entry.to_s)
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_app_control
|
130
|
+
entry = get_entry
|
131
|
+
|
132
|
+
assert !entry.draft
|
133
|
+
|
134
|
+
assert_nil get_elements(entry).elements["/entry/control"]
|
135
|
+
|
136
|
+
entry.draft = true
|
137
|
+
|
138
|
+
xml = get_elements entry
|
139
|
+
|
140
|
+
assert_equal Atom::PP_NS, xml.elements["/entry/control"].namespace
|
141
|
+
assert_equal Atom::PP_NS, xml.elements["/entry/control/draft"].namespace
|
142
|
+
assert_equal "yes", xml.elements["/entry/control/draft"].text
|
143
|
+
|
144
|
+
entry2 = Atom::Entry.parse xml
|
145
|
+
|
146
|
+
assert entry.draft
|
147
|
+
end
|
148
|
+
|
114
149
|
def test_extensive_enty_parsing
|
115
150
|
str = '<entry xmlns="http://www.w3.org/2005/Atom">
|
116
151
|
<title>Atom draft-07 snapshot</title>
|
@@ -141,10 +176,10 @@ str = '<entry xmlns="http://www.w3.org/2005/Atom">
|
|
141
176
|
</entry>'
|
142
177
|
|
143
178
|
entry = Atom::Entry.parse(str)
|
144
|
-
|
179
|
+
|
145
180
|
assert_equal("Atom draft-07 snapshot", entry.title.to_s)
|
146
181
|
assert_equal("tag:example.org,2003:3.2397", entry.id)
|
147
|
-
|
182
|
+
|
148
183
|
assert_equal(Time.parse("2005-07-31T12:29:29Z"), entry.updated)
|
149
184
|
assert_equal(Time.parse("2003-12-13T08:29:29-04:00"), entry.published)
|
150
185
|
|
@@ -162,16 +197,16 @@ str = '<entry xmlns="http://www.w3.org/2005/Atom">
|
|
162
197
|
assert_equal("Mark Pilgrim", entry.authors.first.name)
|
163
198
|
assert_equal("http://example.org/", entry.authors.first.uri)
|
164
199
|
assert_equal("f8dy@example.com", entry.authors.first.email)
|
165
|
-
|
200
|
+
|
166
201
|
assert_equal(2, entry.contributors.length)
|
167
202
|
assert_equal("Sam Ruby", entry.contributors.first.name)
|
168
203
|
assert_equal("Joe Gregorio", entry.contributors.last.name)
|
169
|
-
|
204
|
+
|
170
205
|
assert_equal("xhtml", entry.content["type"])
|
171
|
-
|
206
|
+
|
172
207
|
assert_match("<p><i>[Update: The Atom draft is finished.]</i></p>",
|
173
208
|
entry.content.to_s)
|
174
|
-
|
209
|
+
|
175
210
|
assert_equal("http://diveintomark.org/", entry.content.base)
|
176
211
|
# XXX unimplemented
|
177
212
|
# assert_equal("en", entry.content.lang)
|
@@ -239,7 +274,7 @@ END
|
|
239
274
|
# XXX unimplemented
|
240
275
|
# assert_equal("http://www.example.com/", feed.generator["uri"])
|
241
276
|
# assert_equal("1.0", feed.generator["version"])
|
242
|
-
|
277
|
+
|
243
278
|
assert_equal(1, feed.entries.length)
|
244
279
|
assert_equal "Atom draft-07 snapshot", feed.entries.first.title.to_s
|
245
280
|
end
|
@@ -259,6 +294,18 @@ END
|
|
259
294
|
assert_equal "<p>...& as a result of this, I submit that <var>pi</var> < 4", entry.summary.html.strip
|
260
295
|
end
|
261
296
|
|
297
|
+
def test_parse_goofy_entries
|
298
|
+
xml = <<END
|
299
|
+
<entry xmlns="http://www.w3.org/2005/Atom">
|
300
|
+
<content type="html"></content>
|
301
|
+
</entry>
|
302
|
+
END
|
303
|
+
|
304
|
+
entry = Atom::Entry.parse(xml)
|
305
|
+
|
306
|
+
assert_equal("", entry.content.to_s)
|
307
|
+
end
|
308
|
+
|
262
309
|
def test_parse_outofline_content
|
263
310
|
xml = <<END
|
264
311
|
<entry xmlns="http://www.w3.org/2005/Atom">
|
@@ -267,7 +314,7 @@ Summary doesn't have src.
|
|
267
314
|
</summary>
|
268
315
|
</entry>
|
269
316
|
END
|
270
|
-
|
317
|
+
|
271
318
|
entry = Atom::Entry.parse xml
|
272
319
|
|
273
320
|
assert_raises(RuntimeError) { entry.summary["src"] }
|
@@ -291,7 +338,7 @@ END
|
|
291
338
|
entry = Atom::Entry.new
|
292
339
|
|
293
340
|
entry.base = "http://necronomicorp.com/nil"
|
294
|
-
|
341
|
+
|
295
342
|
base = get_elements(entry).root.attributes["xml:base"]
|
296
343
|
assert_equal "http://necronomicorp.com/nil", base
|
297
344
|
|
@@ -304,11 +351,11 @@ END
|
|
304
351
|
def test_relative_base
|
305
352
|
base_url = "http://www.tbray.org/ongoing/ongoing.atom"
|
306
353
|
doc = "<entry xmlns='http://www.w3.org/2005/Atom' xml:base='When/200x/2006/10/11/'/>"
|
307
|
-
|
354
|
+
|
308
355
|
entry = Atom::Entry.parse(doc, base_url)
|
309
356
|
assert_equal("http://www.tbray.org/ongoing/When/200x/2006/10/11/", entry.base)
|
310
357
|
end
|
311
|
-
|
358
|
+
|
312
359
|
def test_edit_url
|
313
360
|
doc = <<END
|
314
361
|
<entry xmlns="http://www.w3.org/2005/Atom"><link rel="edit"/></entry>
|
@@ -324,7 +371,7 @@ END
|
|
324
371
|
entry = Atom::Entry.parse(doc)
|
325
372
|
|
326
373
|
assert_nil(entry.edit_url)
|
327
|
-
|
374
|
+
|
328
375
|
doc = <<END
|
329
376
|
<entry xmlns="http://www.w3.org/2005/Atom">
|
330
377
|
<link rel="edit" href="http://necronomicorp.com/nil"/>
|
@@ -336,7 +383,6 @@ END
|
|
336
383
|
assert_equal("http://necronomicorp.com/nil", entry.edit_url)
|
337
384
|
end
|
338
385
|
|
339
|
-
|
340
386
|
def assert_has_category xml, term
|
341
387
|
assert_not_nil(REXML::XPath.match(xml, "/entry/category[@term = #{term}]"))
|
342
388
|
end
|
@@ -353,10 +399,10 @@ END
|
|
353
399
|
def get_elements entry
|
354
400
|
xml = entry.to_xml
|
355
401
|
|
356
|
-
assert_equal(entry.to_s, Atom::Entry.parse(xml).to_s)
|
357
|
-
|
402
|
+
assert_equal(entry.to_s, Atom::Entry.parse(xml).to_s)
|
403
|
+
|
358
404
|
base_check xml
|
359
|
-
|
405
|
+
|
360
406
|
xml
|
361
407
|
end
|
362
408
|
|