sax-machine 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.travis.yml +14 -4
- data/Gemfile +5 -1
- data/Guardfile +2 -2
- data/HISTORY.md +23 -6
- data/README.md +111 -40
- data/Rakefile +4 -3
- data/lib/sax-machine.rb +11 -2
- data/lib/sax-machine/{sax_ancestor_config.rb → config/sax_ancestor.rb} +3 -7
- data/lib/sax-machine/{sax_attribute_config.rb → config/sax_attribute.rb} +4 -6
- data/lib/sax-machine/{sax_collection_config.rb → config/sax_collection.rb} +6 -10
- data/lib/sax-machine/{sax_element_config.rb → config/sax_element.rb} +16 -17
- data/lib/sax-machine/{sax_element_value_config.rb → config/sax_element_value.rb} +5 -7
- data/lib/sax-machine/{sax_handler.rb → handlers/sax_abstract_handler.rb} +28 -32
- data/lib/sax-machine/handlers/sax_nokogiri_handler.rb +16 -0
- data/lib/sax-machine/handlers/sax_ox_handler.rb +41 -0
- data/lib/sax-machine/sax_config.rb +9 -9
- data/lib/sax-machine/sax_configure.rb +1 -6
- data/lib/sax-machine/sax_document.rb +28 -17
- data/lib/sax-machine/version.rb +2 -2
- data/sax-machine.gemspec +8 -11
- data/spec/fixtures/atom-content.html +15 -0
- data/spec/{sax-machine → fixtures}/atom.xml +0 -0
- data/spec/sax-machine/sax_activerecord_spec.rb +23 -0
- data/spec/sax-machine/sax_configure_spec.rb +48 -0
- data/spec/sax-machine/sax_document_spec.rb +333 -280
- data/spec/sax-machine/sax_include_spec.rb +43 -0
- data/spec/spec_helper.rb +11 -2
- metadata +36 -41
- data/spec/benchmarks/amazon.xml +0 -40
- data/spec/benchmarks/benchmark.rb +0 -158
- data/spec/benchmarks/public_timeline.xml +0 -411
- data/spec/sax-machine/configure_sax_machine_spec.rb +0 -53
- data/spec/sax-machine/include_sax_machine_spec.rb +0 -42
File without changes
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
describe "ActiveRecord" do
|
5
|
+
describe "integration" do
|
6
|
+
before :each do
|
7
|
+
class MySaxModel < ActiveRecord::Base
|
8
|
+
SAXMachine.configure(MySaxModel) do |c|
|
9
|
+
c.element :title
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
after :each do
|
15
|
+
Object.send(:remove_const, :MySaxModel)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "parses document" do
|
19
|
+
document = MySaxModel.parse("<xml><title>My Title</title></xml>")
|
20
|
+
expect(document.title).to eq("My Title")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
class A
|
4
|
+
SAXMachine.configure(A) do |c|
|
5
|
+
c.element :title
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class B < A
|
10
|
+
SAXMachine.configure(B) do |c|
|
11
|
+
c.element :b
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class C < B
|
16
|
+
SAXMachine.configure(C) do |c|
|
17
|
+
c.element :c
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "SAXMachine configure" do
|
22
|
+
before do
|
23
|
+
xml = "<top><title>Test</title><b>Matched!</b><c>And Again</c></top>"
|
24
|
+
@a = A.new
|
25
|
+
@a.parse xml
|
26
|
+
@b = B.new
|
27
|
+
@b.parse xml
|
28
|
+
@c = C.new
|
29
|
+
@c.parse xml
|
30
|
+
end
|
31
|
+
|
32
|
+
it { expect(@a).to be_a(A) }
|
33
|
+
it { expect(@a).not_to be_a(B) }
|
34
|
+
it { expect(@a).to be_a(SAXMachine) }
|
35
|
+
it { expect(@a.title).to eq("Test") }
|
36
|
+
it { expect(@b).to be_a(A) }
|
37
|
+
it { expect(@b).to be_a(B) }
|
38
|
+
it { expect(@b).to be_a(SAXMachine) }
|
39
|
+
it { expect(@b.title).to eq("Test") }
|
40
|
+
it { expect(@b.b).to eq("Matched!") }
|
41
|
+
it { expect(@c).to be_a(A) }
|
42
|
+
it { expect(@c).to be_a(B) }
|
43
|
+
it { expect(@c).to be_a(C) }
|
44
|
+
it { expect(@c).to be_a(SAXMachine) }
|
45
|
+
it { expect(@c.title).to eq("Test") }
|
46
|
+
it { expect(@c.b).to eq("Matched!") }
|
47
|
+
it { expect(@c.c).to eq("And Again") }
|
48
|
+
end
|
@@ -10,22 +10,22 @@ describe "SAXMachine" do
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
it "
|
14
|
-
document = @klass.new(title:
|
15
|
-
document.title.
|
13
|
+
it "provides mass assignment through initialize method" do
|
14
|
+
document = @klass.new(title: "Title")
|
15
|
+
expect(document.title).to eq("Title")
|
16
16
|
end
|
17
17
|
|
18
|
-
it "
|
18
|
+
it "provides an accessor" do
|
19
19
|
document = @klass.new
|
20
20
|
document.title = "Title"
|
21
|
-
document.title.
|
21
|
+
expect(document.title).to eq("Title")
|
22
22
|
end
|
23
23
|
|
24
|
-
it "
|
25
|
-
@klass.column_names.
|
24
|
+
it "allows introspection of the elements" do
|
25
|
+
expect(@klass.column_names).to match_array([:title])
|
26
26
|
end
|
27
27
|
|
28
|
-
it "
|
28
|
+
it "does not overwrites the getter is there is already one present" do
|
29
29
|
@klass = Class.new do
|
30
30
|
def title
|
31
31
|
"#{@title} ***"
|
@@ -34,12 +34,13 @@ describe "SAXMachine" do
|
|
34
34
|
include SAXMachine
|
35
35
|
element :title
|
36
36
|
end
|
37
|
+
|
37
38
|
document = @klass.new
|
38
39
|
document.title = "Title"
|
39
|
-
document.title.
|
40
|
+
expect(document.title).to eq("Title ***")
|
40
41
|
end
|
41
42
|
|
42
|
-
it "
|
43
|
+
it "does not overwrites the setter if there is already one present" do
|
43
44
|
@klass = Class.new do
|
44
45
|
def title=(val)
|
45
46
|
@title = "#{val} **"
|
@@ -48,114 +49,119 @@ describe "SAXMachine" do
|
|
48
49
|
include SAXMachine
|
49
50
|
element :title
|
50
51
|
end
|
52
|
+
|
53
|
+
document = @klass.new
|
54
|
+
document.title = "Title"
|
55
|
+
expect(document.title).to eq("Title **")
|
56
|
+
end
|
57
|
+
|
58
|
+
it "does not overwrites the accessor when the element is not present" do
|
51
59
|
document = @klass.new
|
52
60
|
document.title = "Title"
|
53
|
-
document.
|
61
|
+
document.parse("<foo></foo>")
|
62
|
+
expect(document.title).to eq("Title")
|
63
|
+
end
|
64
|
+
|
65
|
+
it "overwrites the value when the element is present" do
|
66
|
+
document = @klass.new
|
67
|
+
document.title = "Old title"
|
68
|
+
document.parse("<title>New title</title>")
|
69
|
+
expect(document.title).to eq("New title")
|
70
|
+
end
|
71
|
+
|
72
|
+
it "saves the element text into an accessor" do
|
73
|
+
document = @klass.parse("<title>My Title</title>")
|
74
|
+
expect(document.title).to eq("My Title")
|
75
|
+
end
|
76
|
+
|
77
|
+
it "keeps the document encoding for elements" do
|
78
|
+
data = "<title>My Title</title>"
|
79
|
+
data.encode!("utf-8")
|
80
|
+
|
81
|
+
document = @klass.parse(data)
|
82
|
+
expect(document.title.encoding).to eq(data.encoding)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "saves cdata into an accessor" do
|
86
|
+
document = @klass.parse("<title><![CDATA[A Title]]></title>")
|
87
|
+
expect(document.title).to eq("A Title")
|
88
|
+
end
|
89
|
+
|
90
|
+
it "saves the element text into an accessor when there are multiple elements" do
|
91
|
+
document = @klass.parse("<xml><title>My Title</title><foo>bar</foo></xml>")
|
92
|
+
expect(document.title).to eq("My Title")
|
54
93
|
end
|
94
|
+
|
95
|
+
it "saves the first element text when there are multiple of the same element" do
|
96
|
+
document = @klass.parse("<xml><title>My Title</title><title>bar</title></xml>")
|
97
|
+
expect(document.title).to eq("My Title")
|
98
|
+
end
|
99
|
+
|
55
100
|
describe "the class attribute" do
|
56
101
|
before(:each) do
|
57
102
|
@klass = Class.new do
|
58
103
|
include SAXMachine
|
59
|
-
element :date, :
|
104
|
+
element :date, class: DateTime
|
60
105
|
end
|
106
|
+
|
61
107
|
@document = @klass.new
|
62
108
|
@document.date = Time.now.iso8601
|
63
109
|
end
|
64
|
-
|
65
|
-
|
110
|
+
|
111
|
+
it "is available" do
|
112
|
+
expect(@klass.data_class(:date)).to eq(DateTime)
|
66
113
|
end
|
67
|
-
|
68
|
-
it "
|
114
|
+
|
115
|
+
it "handles an integer class" do
|
69
116
|
@klass = Class.new do
|
70
117
|
include SAXMachine
|
71
|
-
element :number, :
|
118
|
+
element :number, class: Integer
|
72
119
|
end
|
120
|
+
|
73
121
|
document = @klass.parse("<number>5</number>")
|
74
|
-
document.number.
|
122
|
+
expect(document.number).to eq(5)
|
75
123
|
end
|
76
|
-
|
77
|
-
it "
|
124
|
+
|
125
|
+
it "handles an float class" do
|
78
126
|
@klass = Class.new do
|
79
127
|
include SAXMachine
|
80
|
-
element :number, :
|
128
|
+
element :number, class: Float
|
81
129
|
end
|
130
|
+
|
82
131
|
document = @klass.parse("<number>5.5</number>")
|
83
|
-
document.number.
|
84
|
-
end
|
132
|
+
expect(document.number).to eq(5.5)
|
133
|
+
end
|
85
134
|
|
86
|
-
it "
|
135
|
+
it "handles an string class" do
|
87
136
|
@klass = Class.new do
|
88
137
|
include SAXMachine
|
89
|
-
element :number, :
|
138
|
+
element :number, class: String
|
90
139
|
end
|
140
|
+
|
91
141
|
document = @klass.parse("<number>5.5</number>")
|
92
|
-
document.number.
|
142
|
+
expect(document.number).to eq("5.5")
|
93
143
|
end
|
94
|
-
|
95
|
-
it "
|
144
|
+
|
145
|
+
it "handles a time class" do
|
96
146
|
@klass = Class.new do
|
97
147
|
include SAXMachine
|
98
|
-
element :time, :
|
148
|
+
element :time, class: Time
|
99
149
|
end
|
150
|
+
|
100
151
|
document = @klass.parse("<time>1994-02-04T06:20:00Z</time>")
|
101
|
-
document.time.
|
152
|
+
expect(document.time).to eq(Time.utc(1994, 2, 4, 6, 20, 0, 0))
|
102
153
|
end
|
103
|
-
|
104
154
|
end
|
155
|
+
|
105
156
|
describe "the required attribute" do
|
106
|
-
it "
|
157
|
+
it "is available" do
|
107
158
|
@klass = Class.new do
|
108
159
|
include SAXMachine
|
109
|
-
element :date, :
|
160
|
+
element :date, required: true
|
110
161
|
end
|
111
|
-
@klass.required?(:date).
|
162
|
+
expect(@klass.required?(:date)).to be_truthy
|
112
163
|
end
|
113
164
|
end
|
114
|
-
|
115
|
-
it "should not overwrite the accessor when the element is not present" do
|
116
|
-
document = @klass.new
|
117
|
-
document.title = "Title"
|
118
|
-
document.parse("<foo></foo>")
|
119
|
-
document.title.should == "Title"
|
120
|
-
end
|
121
|
-
|
122
|
-
it "should overwrite the value when the element is present" do
|
123
|
-
document = @klass.new
|
124
|
-
document.title = "Old title"
|
125
|
-
document.parse("<title>New title</title>")
|
126
|
-
document.title.should == "New title"
|
127
|
-
end
|
128
|
-
|
129
|
-
it "should save the element text into an accessor" do
|
130
|
-
document = @klass.parse("<title>My Title</title>")
|
131
|
-
document.title.should == "My Title"
|
132
|
-
end
|
133
|
-
|
134
|
-
if RUBY_VERSION >= "1.9.0"
|
135
|
-
it "should keep the document encoding for elements" do
|
136
|
-
data = "<title>My Title</title>"
|
137
|
-
data.encode!("utf-8")
|
138
|
-
|
139
|
-
document = @klass.parse(data)
|
140
|
-
document.title.encoding.should == data.encoding
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
it "should save cdata into an accessor" do
|
145
|
-
document = @klass.parse("<title><![CDATA[A Title]]></title>")
|
146
|
-
document.title.should == "A Title"
|
147
|
-
end
|
148
|
-
|
149
|
-
it "should save the element text into an accessor when there are multiple elements" do
|
150
|
-
document = @klass.parse("<xml><title>My Title</title><foo>bar</foo></xml>")
|
151
|
-
document.title.should == "My Title"
|
152
|
-
end
|
153
|
-
|
154
|
-
it "should save the first element text when there are multiple of the same element" do
|
155
|
-
document = @klass.parse("<xml><title>My Title</title><title>bar</title></xml>")
|
156
|
-
document.title.should == "My Title"
|
157
|
-
|
158
|
-
end
|
159
165
|
end
|
160
166
|
|
161
167
|
describe "when parsing multiple elements" do
|
@@ -167,14 +173,13 @@ describe "SAXMachine" do
|
|
167
173
|
end
|
168
174
|
end
|
169
175
|
|
170
|
-
it "
|
176
|
+
it "saves the element text for a second tag" do
|
171
177
|
document = @klass.parse("<xml><title>My Title</title><name>Paul</name></xml>")
|
172
|
-
document.name.
|
173
|
-
document.title.
|
178
|
+
expect(document.name).to eq("Paul")
|
179
|
+
expect(document.title).to eq("My Title")
|
174
180
|
end
|
175
181
|
|
176
|
-
|
177
|
-
it "should not overwrite the getter is there is already one present" do
|
182
|
+
it "does not overwrites the getter is there is already one present" do
|
178
183
|
@klass = Class.new do
|
179
184
|
def items
|
180
185
|
[]
|
@@ -183,12 +188,13 @@ describe "SAXMachine" do
|
|
183
188
|
include SAXMachine
|
184
189
|
elements :items
|
185
190
|
end
|
191
|
+
|
186
192
|
document = @klass.new
|
187
193
|
document.items = [1, 2, 3, 4]
|
188
|
-
document.items.
|
194
|
+
expect(document.items).to eq([])
|
189
195
|
end
|
190
196
|
|
191
|
-
it "
|
197
|
+
it "does not overwrites the setter if there is already one present" do
|
192
198
|
@klass = Class.new do
|
193
199
|
def items=(val)
|
194
200
|
@items = [1, *val]
|
@@ -197,11 +203,11 @@ describe "SAXMachine" do
|
|
197
203
|
include SAXMachine
|
198
204
|
elements :items
|
199
205
|
end
|
206
|
+
|
200
207
|
document = @klass.new
|
201
208
|
document.items = [2, 3]
|
202
|
-
document.items.
|
209
|
+
expect(document.items).to eq([1, 2, 3])
|
203
210
|
end
|
204
|
-
|
205
211
|
end
|
206
212
|
|
207
213
|
describe "when using options for parsing elements" do
|
@@ -209,19 +215,19 @@ describe "SAXMachine" do
|
|
209
215
|
before :each do
|
210
216
|
@klass = Class.new do
|
211
217
|
include SAXMachine
|
212
|
-
element :description, :
|
218
|
+
element :description, as: :summary
|
213
219
|
end
|
214
220
|
end
|
215
221
|
|
216
|
-
it "
|
222
|
+
it "provides an accessor using the 'as' name" do
|
217
223
|
document = @klass.new
|
218
224
|
document.summary = "a small summary"
|
219
|
-
document.summary.
|
225
|
+
expect(document.summary).to eq("a small summary")
|
220
226
|
end
|
221
227
|
|
222
|
-
it "
|
228
|
+
it "saves the element text into the 'as' accessor" do
|
223
229
|
document = @klass.parse("<description>here is a description</description>")
|
224
|
-
document.summary.
|
230
|
+
expect(document.summary).to eq("here is a description")
|
225
231
|
end
|
226
232
|
end
|
227
233
|
|
@@ -230,35 +236,34 @@ describe "SAXMachine" do
|
|
230
236
|
before :each do
|
231
237
|
@klass = Class.new do
|
232
238
|
include SAXMachine
|
233
|
-
element :link, :
|
239
|
+
element :link, value: :href, with: { foo: "bar" }
|
234
240
|
end
|
235
241
|
end
|
236
242
|
|
237
|
-
it "
|
243
|
+
it "saves the value of a matching element" do
|
238
244
|
document = @klass.parse("<link href='test' foo='bar'>asdf</link>")
|
239
|
-
document.link.
|
245
|
+
expect(document.link).to eq("test")
|
240
246
|
end
|
241
247
|
|
242
|
-
it "
|
248
|
+
it "saves the value of the first matching element" do
|
243
249
|
document = @klass.parse("<xml><link href='first' foo='bar' /><link href='second' foo='bar' /></xml>")
|
244
|
-
document.link.
|
250
|
+
expect(document.link).to eq("first")
|
245
251
|
end
|
246
252
|
|
247
253
|
describe "and the :as option" do
|
248
254
|
before :each do
|
249
255
|
@klass = Class.new do
|
250
256
|
include SAXMachine
|
251
|
-
element :link, :
|
252
|
-
element :link, :
|
257
|
+
element :link, value: :href, as: :url, with: { foo: "bar" }
|
258
|
+
element :link, value: :href, as: :second_url, with: { asdf: "jkl" }
|
253
259
|
end
|
254
260
|
end
|
255
261
|
|
256
|
-
it "
|
262
|
+
it "saves the value of the first matching element" do
|
257
263
|
document = @klass.parse("<xml><link href='first' foo='bar' /><link href='second' asdf='jkl' /><link href='second' foo='bar' /></xml>")
|
258
|
-
document.url.
|
259
|
-
document.second_url.
|
264
|
+
expect(document.url).to eq("first")
|
265
|
+
expect(document.second_url).to eq("second")
|
260
266
|
end
|
261
|
-
|
262
267
|
end
|
263
268
|
end
|
264
269
|
|
@@ -266,29 +271,28 @@ describe "SAXMachine" do
|
|
266
271
|
before :each do
|
267
272
|
@klass = Class.new do
|
268
273
|
include SAXMachine
|
269
|
-
element :link, :
|
274
|
+
element :link, with: { foo: "bar" }
|
270
275
|
end
|
271
276
|
end
|
272
277
|
|
273
|
-
it "
|
278
|
+
it "saves the text of an element that has matching attributes" do
|
274
279
|
document = @klass.parse("<link foo=\"bar\">match</link>")
|
275
|
-
document.link.
|
280
|
+
expect(document.link).to eq("match")
|
276
281
|
end
|
277
282
|
|
278
|
-
it "
|
283
|
+
it "does not saves the text of an element that doesn't have matching attributes" do
|
279
284
|
document = @klass.parse("<link>no match</link>")
|
280
|
-
document.link.
|
285
|
+
expect(document.link).to be_nil
|
281
286
|
end
|
282
287
|
|
283
|
-
it "
|
288
|
+
it "saves the text of an element that has matching attributes when it is the second of that type" do
|
284
289
|
document = @klass.parse("<xml><link>no match</link><link foo=\"bar\">match</link></xml>")
|
285
|
-
document.link.
|
286
|
-
|
290
|
+
expect(document.link).to eq("match")
|
287
291
|
end
|
288
292
|
|
289
|
-
it "
|
293
|
+
it "saves the text of an element that has matching attributes plus a few more" do
|
290
294
|
document = @klass.parse("<xml><link>no match</link><link asdf='jkl' foo='bar'>match</link>")
|
291
|
-
document.link.
|
295
|
+
expect(document.link).to eq("match")
|
292
296
|
end
|
293
297
|
end
|
294
298
|
|
@@ -296,19 +300,19 @@ describe "SAXMachine" do
|
|
296
300
|
before :each do
|
297
301
|
@klass = Class.new do
|
298
302
|
include SAXMachine
|
299
|
-
element :link, :
|
300
|
-
element :link, :
|
303
|
+
element :link, as: :first, with: { foo: "bar" }
|
304
|
+
element :link, as: :second, with: { asdf: "jkl" }
|
301
305
|
end
|
302
306
|
end
|
303
307
|
|
304
|
-
it "
|
308
|
+
it "matches the first element" do
|
305
309
|
document = @klass.parse("<xml><link>no match</link><link foo=\"bar\">first match</link><link>no match</link></xml>")
|
306
|
-
document.first.
|
310
|
+
expect(document.first).to eq("first match")
|
307
311
|
end
|
308
312
|
|
309
|
-
it "
|
313
|
+
it "matches the second element" do
|
310
314
|
document = @klass.parse("<xml><link>no match</link><link foo='bar'>first match</link><link asdf='jkl'>second match</link><link>hi</link></xml>")
|
311
|
-
document.second.
|
315
|
+
expect(document.second).to eq("second match")
|
312
316
|
end
|
313
317
|
end
|
314
318
|
|
@@ -316,75 +320,77 @@ describe "SAXMachine" do
|
|
316
320
|
before :each do
|
317
321
|
@klass = Class.new do
|
318
322
|
include SAXMachine
|
319
|
-
element :link, :
|
323
|
+
element :link, with: { foo: /ar$/ }
|
320
324
|
end
|
321
325
|
end
|
322
326
|
|
323
|
-
it "
|
327
|
+
it "saves the text of an element that has matching attributes" do
|
324
328
|
document = @klass.parse("<link foo=\"bar\">match</link>")
|
325
|
-
document.link.
|
329
|
+
expect(document.link).to eq("match")
|
326
330
|
end
|
327
331
|
|
328
|
-
it "
|
332
|
+
it "does not saves the text of an element that doesn't have matching attributes" do
|
329
333
|
document = @klass.parse("<link>no match</link>")
|
330
|
-
document.link.
|
334
|
+
expect(document.link).to be_nil
|
331
335
|
end
|
332
336
|
|
333
|
-
it "
|
337
|
+
it "saves the text of an element that has matching attributes when it is the second of that type" do
|
334
338
|
document = @klass.parse("<xml><link>no match</link><link foo=\"bar\">match</link></xml>")
|
335
|
-
document.link.
|
339
|
+
expect(document.link).to eq("match")
|
336
340
|
end
|
337
341
|
|
338
|
-
it "
|
342
|
+
it "saves the text of an element that has matching attributes plus a few more" do
|
339
343
|
document = @klass.parse("<xml><link>no match</link><link asdf='jkl' foo='bar'>match</link>")
|
340
|
-
document.link.
|
344
|
+
expect(document.link).to eq("match")
|
341
345
|
end
|
342
346
|
end
|
343
|
-
end
|
347
|
+
end
|
344
348
|
|
345
349
|
describe "using the 'value' option" do
|
346
350
|
before :each do
|
347
351
|
@klass = Class.new do
|
348
352
|
include SAXMachine
|
349
|
-
element :link, :
|
353
|
+
element :link, value: :foo
|
350
354
|
end
|
351
355
|
end
|
352
356
|
|
353
|
-
it "
|
357
|
+
it "saves the attribute value" do
|
354
358
|
document = @klass.parse("<link foo='test'>hello</link>")
|
355
|
-
document.link.
|
359
|
+
expect(document.link).to eq("test")
|
356
360
|
end
|
357
361
|
|
358
|
-
it "
|
362
|
+
it "saves the attribute value when there is no text enclosed by the tag" do
|
359
363
|
document = @klass.parse("<link foo='test'></link>")
|
360
|
-
document.link.
|
364
|
+
expect(document.link).to eq("test")
|
361
365
|
end
|
362
366
|
|
363
|
-
it "
|
367
|
+
it "saves the attribute value when the tag close is in the open" do
|
364
368
|
document = @klass.parse("<link foo='test'/>")
|
365
|
-
document.link.
|
369
|
+
expect(document.link).to eq("test")
|
366
370
|
end
|
367
371
|
|
368
|
-
it "
|
372
|
+
it "saves two different attribute values on a single tag" do
|
369
373
|
@klass = Class.new do
|
370
374
|
include SAXMachine
|
371
|
-
element :link, :
|
372
|
-
element :link, :
|
375
|
+
element :link, value: :foo, as: :first
|
376
|
+
element :link, value: :bar, as: :second
|
373
377
|
end
|
378
|
+
|
374
379
|
document = @klass.parse("<link foo='foo value' bar='bar value'></link>")
|
375
|
-
document.first.
|
376
|
-
document.second.
|
380
|
+
expect(document.first).to eq("foo value")
|
381
|
+
expect(document.second).to eq("bar value")
|
377
382
|
end
|
378
383
|
|
379
|
-
it "
|
384
|
+
it "does not fail if one of the attribute hasn't been defined" do
|
380
385
|
@klass = Class.new do
|
381
386
|
include SAXMachine
|
382
|
-
element :link, :
|
383
|
-
element :link, :
|
387
|
+
element :link, value: :foo, as: :first
|
388
|
+
element :link, value: :bar, as: :second
|
384
389
|
end
|
390
|
+
|
385
391
|
document = @klass.parse("<link foo='foo value'></link>")
|
386
|
-
document.first.
|
387
|
-
document.second.
|
392
|
+
expect(document.first).to eq("foo value")
|
393
|
+
expect(document.second).to be_nil
|
388
394
|
end
|
389
395
|
end
|
390
396
|
|
@@ -393,19 +399,18 @@ describe "SAXMachine" do
|
|
393
399
|
@klass = Class.new do
|
394
400
|
include SAXMachine
|
395
401
|
element :link
|
396
|
-
element :link, :
|
397
|
-
element :link, :
|
402
|
+
element :link, value: :foo, as: :link_foo
|
403
|
+
element :link, value: :bar, as: :link_bar
|
398
404
|
end
|
399
405
|
end
|
400
406
|
|
401
|
-
it "
|
407
|
+
it "parses the element and attribute values" do
|
402
408
|
document = @klass.parse("<link foo='test1' bar='test2'>hello</link>")
|
403
|
-
document.link.
|
404
|
-
document.link_foo.
|
405
|
-
document.link_bar.
|
409
|
+
expect(document.link).to eq("hello")
|
410
|
+
expect(document.link_foo).to eq("test1")
|
411
|
+
expect(document.link_bar).to eq("test2")
|
406
412
|
end
|
407
413
|
end
|
408
|
-
|
409
414
|
end
|
410
415
|
end
|
411
416
|
|
@@ -414,33 +419,34 @@ describe "SAXMachine" do
|
|
414
419
|
before :each do
|
415
420
|
@klass = Class.new do
|
416
421
|
include SAXMachine
|
417
|
-
elements :entry, :
|
422
|
+
elements :entry, as: :entries
|
418
423
|
end
|
419
424
|
end
|
420
425
|
|
421
|
-
it "
|
426
|
+
it "provides a collection accessor" do
|
422
427
|
document = @klass.new
|
423
428
|
document.entries << :foo
|
424
|
-
document.entries.
|
429
|
+
expect(document.entries).to eq([:foo])
|
425
430
|
end
|
426
431
|
|
427
|
-
it "
|
432
|
+
it "parses a single element" do
|
428
433
|
document = @klass.parse("<entry>hello</entry>")
|
429
|
-
document.entries.
|
434
|
+
expect(document.entries).to eq(["hello"])
|
430
435
|
end
|
431
436
|
|
432
|
-
it "
|
437
|
+
it "parses multiple elements" do
|
433
438
|
document = @klass.parse("<xml><entry>hello</entry><entry>world</entry></xml>")
|
434
|
-
document.entries.
|
439
|
+
expect(document.entries).to eq(["hello", "world"])
|
435
440
|
end
|
436
441
|
|
437
|
-
it "
|
442
|
+
it "parses multiple elements when taking an attribute value" do
|
438
443
|
attribute_klass = Class.new do
|
439
444
|
include SAXMachine
|
440
|
-
elements :entry, :
|
445
|
+
elements :entry, as: :entries, value: :foo
|
441
446
|
end
|
447
|
+
|
442
448
|
doc = attribute_klass.parse("<xml><entry foo='asdf' /><entry foo='jkl' /></xml>")
|
443
|
-
doc.entries.
|
449
|
+
expect(doc.entries).to eq(["asdf", "jkl"])
|
444
450
|
end
|
445
451
|
end
|
446
452
|
|
@@ -458,22 +464,22 @@ describe "SAXMachine" do
|
|
458
464
|
|
459
465
|
class Item
|
460
466
|
include SAXMachine
|
461
|
-
|
462
467
|
end
|
468
|
+
|
463
469
|
@klass = Class.new do
|
464
470
|
include SAXMachine
|
465
|
-
elements :item, :
|
466
|
-
elements :item, :
|
471
|
+
elements :item, as: :items, with: { type: "Bar" }, class: Bar
|
472
|
+
elements :item, as: :items, with: { type: /Foo/ }, class: Foo
|
467
473
|
end
|
468
474
|
end
|
469
|
-
|
470
|
-
it "
|
475
|
+
|
476
|
+
it "casts into the correct class" do
|
471
477
|
document = @klass.parse("<items><item type=\"Bar\"><title>Bar title</title></item><item type=\"Foo\"><title>Foo title</title></item></items>")
|
472
|
-
document.items.size.
|
473
|
-
document.items.first.
|
474
|
-
document.items.first.title.
|
475
|
-
document.items.last.
|
476
|
-
document.items.last.title.
|
478
|
+
expect(document.items.size).to eq(2)
|
479
|
+
expect(document.items.first).to be_a(Bar)
|
480
|
+
expect(document.items.first.title).to eq("Bar title")
|
481
|
+
expect(document.items.last).to be_a(Foo)
|
482
|
+
expect(document.items.last.title).to eq("Foo title")
|
477
483
|
end
|
478
484
|
end
|
479
485
|
|
@@ -483,81 +489,85 @@ describe "SAXMachine" do
|
|
483
489
|
include SAXMachine
|
484
490
|
element :title
|
485
491
|
end
|
492
|
+
|
486
493
|
@klass = Class.new do
|
487
494
|
include SAXMachine
|
488
|
-
elements :entry, :
|
495
|
+
elements :entry, as: :entries, class: Foo
|
489
496
|
end
|
490
497
|
end
|
491
498
|
|
492
|
-
it "
|
499
|
+
it "parses a single element with children" do
|
493
500
|
document = @klass.parse("<entry><title>a title</title></entry>")
|
494
|
-
document.entries.size.
|
495
|
-
document.entries.first.title.
|
501
|
+
expect(document.entries.size).to eq(1)
|
502
|
+
expect(document.entries.first.title).to eq("a title")
|
496
503
|
end
|
497
504
|
|
498
|
-
it "
|
505
|
+
it "parses multiple elements with children" do
|
499
506
|
document = @klass.parse("<xml><entry><title>title 1</title></entry><entry><title>title 2</title></entry></xml>")
|
500
|
-
document.entries.size.
|
501
|
-
document.entries.first.title.
|
502
|
-
document.entries.last.title.
|
507
|
+
expect(document.entries.size).to eq(2)
|
508
|
+
expect(document.entries.first.title).to eq("title 1")
|
509
|
+
expect(document.entries.last.title).to eq("title 2")
|
503
510
|
end
|
504
511
|
|
505
|
-
it "
|
512
|
+
it "does not parse a top level element that is specified only in a child" do
|
506
513
|
document = @klass.parse("<xml><title>no parse</title><entry><title>correct title</title></entry></xml>")
|
507
|
-
document.entries.size.
|
508
|
-
document.entries.first.title.
|
514
|
+
expect(document.entries.size).to eq(1)
|
515
|
+
expect(document.entries.first.title).to eq("correct title")
|
509
516
|
end
|
510
517
|
|
511
|
-
it "
|
518
|
+
it "parses elements, and make attributes and inner text available" do
|
512
519
|
class Related
|
513
520
|
include SAXMachine
|
514
|
-
element
|
515
|
-
element
|
521
|
+
element "related", as: :item
|
522
|
+
element "related", as: :attr, value: "attr"
|
516
523
|
end
|
524
|
+
|
517
525
|
class Foo
|
518
|
-
elements
|
526
|
+
elements "related", as: "items", class: Related
|
519
527
|
end
|
520
528
|
|
521
529
|
doc = Foo.parse(%{<xml><collection><related attr='baz'>something</related><related>somethingelse</related></collection></xml>})
|
522
|
-
doc.items.first.
|
523
|
-
doc.items.size.
|
524
|
-
doc.items.first.item.
|
525
|
-
doc.items.last.item.
|
530
|
+
expect(doc.items.first).not_to be_nil
|
531
|
+
expect(doc.items.size).to eq(2)
|
532
|
+
expect(doc.items.first.item).to eq("something")
|
533
|
+
expect(doc.items.last.item).to eq("somethingelse")
|
526
534
|
end
|
527
535
|
|
528
|
-
it "
|
536
|
+
it "parses out an attribute value from the tag that starts the collection" do
|
529
537
|
class Foo
|
530
|
-
element :entry, :
|
538
|
+
element :entry, value: :href, as: :url
|
531
539
|
end
|
540
|
+
|
532
541
|
document = @klass.parse("<xml><entry href='http://pauldix.net'><title>paul</title></entry></xml>")
|
533
|
-
document.entries.size.
|
534
|
-
document.entries.first.title.
|
535
|
-
document.entries.first.url.
|
542
|
+
expect(document.entries.size).to eq(1)
|
543
|
+
expect(document.entries.first.title).to eq("paul")
|
544
|
+
expect(document.entries.first.url).to eq("http://pauldix.net")
|
536
545
|
end
|
537
546
|
end
|
538
547
|
end
|
539
|
-
|
548
|
+
|
540
549
|
describe "when dealing with element names containing dashes" do
|
541
|
-
it
|
550
|
+
it "converts dashes to underscores" do
|
542
551
|
class Dashes
|
543
552
|
include SAXMachine
|
544
553
|
element :dashed_element
|
545
554
|
end
|
546
|
-
|
547
|
-
parsed = Dashes.parse(
|
548
|
-
parsed.dashed_element.
|
555
|
+
|
556
|
+
parsed = Dashes.parse("<dashed-element>Text</dashed-element>")
|
557
|
+
expect(parsed.dashed_element).to eq "Text"
|
549
558
|
end
|
550
559
|
end
|
551
560
|
|
552
561
|
describe "full example" do
|
553
562
|
before :each do
|
554
|
-
@xml = File.read(
|
563
|
+
@xml = File.read("spec/fixtures/atom.xml")
|
564
|
+
|
555
565
|
class AtomEntry
|
556
566
|
include SAXMachine
|
557
567
|
element :title
|
558
|
-
element :name, :
|
559
|
-
element "feedburner:origLink", :
|
560
|
-
element :link, :
|
568
|
+
element :name, as: :author
|
569
|
+
element "feedburner:origLink", as: :url
|
570
|
+
element :link, as: :alternate, value: :href, with: { type: "text/html", rel: "alternate" }
|
561
571
|
element :summary
|
562
572
|
element :content
|
563
573
|
element :published
|
@@ -566,21 +576,25 @@ describe "SAXMachine" do
|
|
566
576
|
class Atom
|
567
577
|
include SAXMachine
|
568
578
|
element :title
|
569
|
-
element :link, :
|
570
|
-
element :link, :
|
571
|
-
elements :entry, :
|
579
|
+
element :link, value: :href, as: :url, with: { type: "text/html" }
|
580
|
+
element :link, value: :href, as: :feed_url, with: { type: "application/atom+xml" }
|
581
|
+
elements :entry, as: :entries, class: AtomEntry
|
572
582
|
end
|
573
|
-
end # before
|
574
583
|
|
575
|
-
|
576
|
-
|
577
|
-
|
584
|
+
@feed = Atom.parse(@xml)
|
585
|
+
end
|
586
|
+
|
587
|
+
it "parses the url" do
|
588
|
+
expect(@feed.url).to eq("http://www.pauldix.net/")
|
589
|
+
end
|
590
|
+
|
591
|
+
it "parses entry url" do
|
592
|
+
expect(@feed.entries.first.url).to eq("http://www.pauldix.net/2008/09/marshal-data-to.html?param1=1¶m2=2")
|
593
|
+
expect(@feed.entries.first.alternate).to eq("http://feeds.feedburner.com/~r/PaulDixExplainsNothing/~3/383536354/marshal-data-to.html?param1=1¶m2=2")
|
578
594
|
end
|
579
595
|
|
580
|
-
it "
|
581
|
-
|
582
|
-
f.entries.first.url.should == "http://www.pauldix.net/2008/09/marshal-data-to.html?param1=1¶m2=2"
|
583
|
-
f.entries.first.alternate.should == "http://feeds.feedburner.com/~r/PaulDixExplainsNothing/~3/383536354/marshal-data-to.html?param1=1¶m2=2"
|
596
|
+
it "parses content" do
|
597
|
+
expect(@feed.entries.first.content).to eq(File.read("spec/fixtures/atom-content.html"))
|
584
598
|
end
|
585
599
|
end
|
586
600
|
|
@@ -598,32 +612,35 @@ describe "SAXMachine" do
|
|
598
612
|
</category>
|
599
613
|
</categories>
|
600
614
|
]
|
601
|
-
|
602
|
-
end
|
615
|
+
|
616
|
+
class CategoryCollection; end
|
617
|
+
|
603
618
|
class Category
|
604
619
|
include SAXMachine
|
605
620
|
attr_accessor :id
|
606
|
-
element :category, :
|
621
|
+
element :category, value: :id, as: :id
|
607
622
|
element :title
|
608
|
-
element :categories, :
|
623
|
+
element :categories, as: :collection, class: CategoryCollection
|
609
624
|
ancestor :ancestor
|
610
625
|
end
|
626
|
+
|
611
627
|
class CategoryCollection
|
612
628
|
include SAXMachine
|
613
|
-
elements :category, :
|
629
|
+
elements :category, as: :categories, class: Category
|
614
630
|
end
|
631
|
+
|
615
632
|
@collection = CategoryCollection.parse(@xml)
|
616
633
|
end
|
617
634
|
|
618
|
-
it "
|
619
|
-
@collection.categories.first.id.
|
620
|
-
@collection.categories.first.title.
|
621
|
-
@collection.categories.first.ancestor.
|
635
|
+
it "parses the first category" do
|
636
|
+
expect(@collection.categories.first.id).to eq("1")
|
637
|
+
expect(@collection.categories.first.title).to eq("First")
|
638
|
+
expect(@collection.categories.first.ancestor).to eq(@collection)
|
622
639
|
end
|
623
640
|
|
624
|
-
it "
|
625
|
-
@collection.categories.first.collection.categories.first.id.
|
626
|
-
@collection.categories.first.collection.categories.first.title.
|
641
|
+
it "parses the nested category" do
|
642
|
+
expect(@collection.categories.first.collection.categories.first.id).to eq("2")
|
643
|
+
expect(@collection.categories.first.collection.categories.first.title).to eq("Second")
|
627
644
|
end
|
628
645
|
end
|
629
646
|
|
@@ -641,24 +658,26 @@ describe "SAXMachine" do
|
|
641
658
|
</category>
|
642
659
|
</categories>
|
643
660
|
]
|
661
|
+
|
644
662
|
class CategoryTree
|
645
663
|
include SAXMachine
|
646
664
|
attr_accessor :id
|
647
|
-
element :category, :
|
665
|
+
element :category, value: :id, as: :id
|
648
666
|
element :title
|
649
|
-
elements :category, :
|
667
|
+
elements :category, as: :categories, class: CategoryTree
|
650
668
|
end
|
669
|
+
|
651
670
|
@collection = CategoryTree.parse(@xml)
|
652
671
|
end
|
653
672
|
|
654
|
-
it "
|
655
|
-
@collection.categories.first.id.
|
656
|
-
@collection.categories.first.title.
|
673
|
+
it "parses the first category" do
|
674
|
+
expect(@collection.categories.first.id).to eq("1")
|
675
|
+
expect(@collection.categories.first.title).to eq("First")
|
657
676
|
end
|
658
677
|
|
659
|
-
it "
|
660
|
-
@collection.categories.first.categories.first.id.
|
661
|
-
@collection.categories.first.categories.first.title.
|
678
|
+
it "parses the nested category" do
|
679
|
+
expect(@collection.categories.first.categories.first.id).to eq("2")
|
680
|
+
expect(@collection.categories.first.categories.first.title).to eq("Second")
|
662
681
|
end
|
663
682
|
end
|
664
683
|
|
@@ -671,21 +690,23 @@ describe "SAXMachine" do
|
|
671
690
|
</texts>
|
672
691
|
</item>
|
673
692
|
]
|
693
|
+
|
674
694
|
@klass = Class.new do
|
675
695
|
include SAXMachine
|
676
696
|
attr_accessor :id
|
677
|
-
element :item, :
|
697
|
+
element :item, value: "id", as: :id
|
678
698
|
element :title
|
679
699
|
end
|
700
|
+
|
680
701
|
@item = @klass.parse(@xml)
|
681
702
|
end
|
682
703
|
|
683
|
-
it "
|
684
|
-
@item.id.
|
704
|
+
it "has an id" do
|
705
|
+
expect(@item.id).to eq("1")
|
685
706
|
end
|
686
707
|
|
687
|
-
it "
|
688
|
-
@item.title.
|
708
|
+
it "has a title" do
|
709
|
+
expect(@item.title).to eq("Hello")
|
689
710
|
end
|
690
711
|
end
|
691
712
|
|
@@ -696,28 +717,31 @@ describe "SAXMachine" do
|
|
696
717
|
<author name="John Doe" role="writer" />
|
697
718
|
</item>
|
698
719
|
]
|
720
|
+
|
699
721
|
class AuthorElement
|
700
722
|
include SAXMachine
|
701
723
|
attribute :name
|
702
724
|
attribute :role
|
703
725
|
end
|
726
|
+
|
704
727
|
class ItemElement
|
705
728
|
include SAXMachine
|
706
|
-
element :author, :
|
729
|
+
element :author, class: AuthorElement
|
707
730
|
end
|
731
|
+
|
708
732
|
@item = ItemElement.parse(@xml)
|
709
733
|
end
|
710
734
|
|
711
|
-
it
|
712
|
-
@item.author.
|
735
|
+
it "has the child element" do
|
736
|
+
expect(@item.author).not_to be_nil
|
713
737
|
end
|
714
738
|
|
715
|
-
it
|
716
|
-
@item.author.name.
|
739
|
+
it "has the author name" do
|
740
|
+
expect(@item.author.name).to eq("John Doe")
|
717
741
|
end
|
718
742
|
|
719
|
-
it
|
720
|
-
@item.author.role.
|
743
|
+
it "has the author role" do
|
744
|
+
expect(@item.author.role).to eq("writer")
|
721
745
|
end
|
722
746
|
end
|
723
747
|
|
@@ -729,31 +753,34 @@ describe "SAXMachine" do
|
|
729
753
|
<author name="Jane Doe" role="artist" />
|
730
754
|
</item>
|
731
755
|
]
|
756
|
+
|
732
757
|
class AuthorElement2
|
733
758
|
include SAXMachine
|
734
759
|
attribute :name
|
735
760
|
attribute :role
|
736
761
|
end
|
762
|
+
|
737
763
|
class ItemElement2
|
738
764
|
include SAXMachine
|
739
|
-
elements :author, :
|
765
|
+
elements :author, as: :authors, class: AuthorElement2
|
740
766
|
end
|
767
|
+
|
741
768
|
@item = ItemElement2.parse(@xml)
|
742
769
|
end
|
743
770
|
|
744
|
-
it
|
745
|
-
@item.authors.
|
746
|
-
@item.authors.count.
|
771
|
+
it "has the child elements" do
|
772
|
+
expect(@item.authors).not_to be_nil
|
773
|
+
expect(@item.authors.count).to eq(2)
|
747
774
|
end
|
748
775
|
|
749
|
-
it
|
750
|
-
@item.authors.first.name.
|
751
|
-
@item.authors.last.name.
|
776
|
+
it "has the author names" do
|
777
|
+
expect(@item.authors.first.name).to eq("John Doe")
|
778
|
+
expect(@item.authors.last.name).to eq("Jane Doe")
|
752
779
|
end
|
753
780
|
|
754
|
-
it
|
755
|
-
@item.authors.first.role.
|
756
|
-
@item.authors.last.role.
|
781
|
+
it "has the author roles" do
|
782
|
+
expect(@item.authors.first.role).to eq("writer")
|
783
|
+
expect(@item.authors.last.role).to eq("artist")
|
757
784
|
end
|
758
785
|
end
|
759
786
|
|
@@ -764,28 +791,31 @@ describe "SAXMachine" do
|
|
764
791
|
<author role="writer">John Doe</author>
|
765
792
|
</item>
|
766
793
|
]
|
794
|
+
|
767
795
|
class AuthorElement3
|
768
796
|
include SAXMachine
|
769
797
|
value :name
|
770
798
|
attribute :role
|
771
799
|
end
|
800
|
+
|
772
801
|
class ItemElement3
|
773
802
|
include SAXMachine
|
774
|
-
element :author, :
|
803
|
+
element :author, class: AuthorElement3
|
775
804
|
end
|
805
|
+
|
776
806
|
@item = ItemElement3.parse(@xml)
|
777
807
|
end
|
778
808
|
|
779
|
-
it
|
780
|
-
@item.author.
|
809
|
+
it "has the child elements" do
|
810
|
+
expect(@item.author).not_to be_nil
|
781
811
|
end
|
782
812
|
|
783
|
-
it
|
784
|
-
@item.author.name.
|
813
|
+
it "has the author names" do
|
814
|
+
expect(@item.author.name).to eq("John Doe")
|
785
815
|
end
|
786
816
|
|
787
|
-
it
|
788
|
-
@item.author.role.
|
817
|
+
it "has the author roles" do
|
818
|
+
expect(@item.author.role).to eq("writer")
|
789
819
|
end
|
790
820
|
end
|
791
821
|
|
@@ -798,41 +828,64 @@ describe "SAXMachine" do
|
|
798
828
|
<author role="artist">Jane Doe</author>
|
799
829
|
</item>
|
800
830
|
]
|
831
|
+
|
801
832
|
class AuthorElement4
|
802
833
|
include SAXMachine
|
803
834
|
value :name
|
804
835
|
attribute :role
|
805
836
|
end
|
837
|
+
|
806
838
|
class ItemElement4
|
807
839
|
include SAXMachine
|
808
840
|
element :title
|
809
|
-
elements :author, :
|
841
|
+
elements :author, as: :authors, class: AuthorElement4
|
810
842
|
|
811
843
|
def title=(blah)
|
812
|
-
#raise 'woo'
|
813
844
|
@title = blah
|
814
845
|
end
|
815
846
|
end
|
847
|
+
|
816
848
|
@item = ItemElement4.parse(@xml)
|
817
849
|
end
|
818
850
|
|
819
|
-
it
|
820
|
-
@item.title.
|
851
|
+
it "has the title" do
|
852
|
+
expect(@item.title).to eq("sweet")
|
821
853
|
end
|
822
854
|
|
823
|
-
it
|
824
|
-
@item.authors.
|
825
|
-
@item.authors.count.
|
855
|
+
it "has the child elements" do
|
856
|
+
expect(@item.authors).not_to be_nil
|
857
|
+
expect(@item.authors.count).to eq(2)
|
826
858
|
end
|
827
859
|
|
828
|
-
it
|
829
|
-
@item.authors.first.name.
|
830
|
-
@item.authors.last.name.
|
860
|
+
it "has the author names" do
|
861
|
+
expect(@item.authors.first.name).to eq("John Doe")
|
862
|
+
expect(@item.authors.last.name).to eq("Jane Doe")
|
863
|
+
end
|
864
|
+
|
865
|
+
it "has the author roles" do
|
866
|
+
expect(@item.authors.first.role).to eq("writer")
|
867
|
+
expect(@item.authors.last.role).to eq("artist")
|
868
|
+
end
|
869
|
+
end
|
870
|
+
|
871
|
+
describe "with error handling" do
|
872
|
+
before do
|
873
|
+
@xml = %[
|
874
|
+
<item id="1">
|
875
|
+
<title>sweet</title>
|
876
|
+
]
|
877
|
+
|
878
|
+
class ItemElement5
|
879
|
+
include SAXMachine
|
880
|
+
element :title
|
881
|
+
end
|
882
|
+
|
883
|
+
@errors = []
|
884
|
+
@item = ItemElement5.parse(@xml, ->(x) { @errors << x })
|
831
885
|
end
|
832
886
|
|
833
|
-
it
|
834
|
-
@
|
835
|
-
@item.authors.last.role.should == 'artist'
|
887
|
+
it "has error" do
|
888
|
+
expect(@errors.uniq.size).to eq(1)
|
836
889
|
end
|
837
890
|
end
|
838
891
|
end
|