mida 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +18 -2
- data/README.rdoc +22 -11
- data/Rakefile +2 -2
- data/lib/mida.rb +1 -1
- data/lib/mida/datatype.rb +15 -0
- data/lib/mida/datatype/boolean.rb +18 -0
- data/lib/mida/datatype/float.rb +15 -0
- data/lib/mida/datatype/integer.rb +15 -0
- data/lib/mida/datatype/iso8601date.rb +17 -0
- data/lib/mida/datatype/number.rb +15 -0
- data/lib/mida/datatype/text.rb +13 -0
- data/lib/mida/document.rb +21 -19
- data/lib/mida/genericvocabulary.rb +13 -0
- data/lib/mida/item.rb +83 -71
- data/lib/mida/itemprop.rb +55 -30
- data/lib/mida/itemscope.rb +82 -0
- data/lib/mida/propertydesc.rb +36 -0
- data/lib/mida/vocabulary.rb +60 -6
- data/spec/datatype/boolean_spec.rb +27 -0
- data/spec/datatype/float_spec.rb +23 -0
- data/spec/datatype/integer_spec.rb +23 -0
- data/spec/datatype/iso8601date_spec.rb +20 -0
- data/spec/datatype/number_spec.rb +23 -0
- data/spec/datatype/text_spec.rb +14 -0
- data/spec/document_spec.rb +31 -487
- data/spec/item_spec.rb +163 -472
- data/spec/itemprop_spec.rb +40 -45
- data/spec/itemscope_spec.rb +287 -0
- data/spec/propertydesc_spec.rb +56 -0
- data/spec/spec_helper.rb +13 -36
- data/spec/vocabulary_spec.rb +148 -0
- metadata +22 -6
- data/lib/mida/vocabulary/generic.rb +0 -15
- data/lib/mida/vocabularydesc.rb +0 -57
- data/spec/vocabularydesc_spec.rb +0 -106
data/spec/item_spec.rb
CHANGED
@@ -1,584 +1,275 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'mida/item'
|
3
|
+
require 'mida/vocabulary'
|
3
4
|
|
4
|
-
describe Mida::Item, 'when initialized with an itemscope
|
5
|
+
describe Mida::Item, 'when initialized with an incomplete itemscope' do
|
5
6
|
before do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@ln = mock_element('span', {'itemprop' => 'last_name'}, 'Woodman')
|
11
|
-
end
|
12
|
-
|
13
|
-
context 'when there is no itemtype' do
|
14
|
-
before do
|
15
|
-
# The surrounding reviewer itemscope element
|
16
|
-
itemscope_el = mock_element('div', {'itemprop' => 'reviewer', 'itemscope' => true}, nil, [@fn,@ln])
|
17
|
-
@item = Mida::Item.new(itemscope_el)
|
18
|
-
end
|
19
|
-
|
20
|
-
it '#vocabulary should return the correct vocabulary' do
|
21
|
-
@item.vocabulary.should == Mida::Vocabulary::Generic
|
22
|
-
end
|
23
|
-
|
24
|
-
it '#type should return the correct type' do
|
25
|
-
@item.type.should == nil
|
26
|
-
end
|
27
|
-
|
28
|
-
it '#id should return the correct id' do
|
29
|
-
@item.id.should == nil
|
30
|
-
end
|
31
|
-
|
32
|
-
it '#properties should return the correct name/value pairs' do
|
33
|
-
@item.properties.should == {
|
34
|
-
'first_name' => ['Lorry'],
|
35
|
-
'last_name' => ['Woodman']
|
36
|
-
}
|
37
|
-
end
|
38
|
-
|
39
|
-
it '#to_h should return the correct type and properties' do
|
40
|
-
@item.to_h.should == {
|
41
|
-
vocabulary: Mida::Vocabulary::Generic, type: nil, id: nil, properties: {
|
42
|
-
'first_name' => ['Lorry'],
|
43
|
-
'last_name' => ['Woodman']
|
44
|
-
}
|
45
|
-
}
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
context 'when there is an itemtype' do
|
50
|
-
before do
|
51
|
-
# The surrounding reviewer itemscope element
|
52
|
-
itemscope_el = mock_element('div', {'itemprop' => 'reviewer', 'itemtype' => 'person', 'itemscope' => true}, nil, [@fn,@ln])
|
53
|
-
@item = Mida::Item.new(itemscope_el)
|
54
|
-
end
|
55
|
-
|
56
|
-
it '#vocabulary should return the correct vocabulary' do
|
57
|
-
@item.vocabulary.should == Mida::Vocabulary::Generic
|
58
|
-
end
|
59
|
-
|
60
|
-
it '#type should return the correct type' do
|
61
|
-
@item.type.should == 'person'
|
62
|
-
end
|
63
|
-
|
64
|
-
it '#id should return the correct id' do
|
65
|
-
@item.id.should == nil
|
66
|
-
end
|
67
|
-
|
68
|
-
it '#properties should return the correct name/value pairs' do
|
69
|
-
@item.properties.should == {
|
70
|
-
'first_name' => ['Lorry'],
|
71
|
-
'last_name' => ['Woodman']
|
72
|
-
}
|
73
|
-
end
|
74
|
-
|
75
|
-
it '#to_h should return the correct type and properties' do
|
76
|
-
@item.to_h.should == {
|
77
|
-
vocabulary: Mida::Vocabulary::Generic,
|
78
|
-
type: 'person',
|
79
|
-
id: nil,
|
80
|
-
properties: {
|
81
|
-
'first_name' => ['Lorry'],
|
82
|
-
'last_name' => ['Woodman']
|
83
|
-
}
|
84
|
-
}
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
describe Mida::Item, 'when initialized with an itemscope containing an itemprop with a relative url' do
|
90
|
-
before do
|
91
|
-
@url = mock_element('a', {'itemprop' => 'url', 'href' => 'home/lorry'})
|
92
|
-
itemscope_el = mock_element('div', {'itemscope' => true}, nil, [@url])
|
93
|
-
@item = Mida::Item.new(itemscope_el, "http://example.com")
|
94
|
-
end
|
95
|
-
|
96
|
-
it 'should return the url as an absolute url' do
|
97
|
-
@item.properties['url'].should == ['http://example.com/home/lorry']
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
describe Mida::Item, 'when initialized with an itemscope containing itemprops surrounded by a non microdata element' do
|
102
|
-
before do
|
103
|
-
# The first_name element
|
104
|
-
fn = mock_element('span', {'itemprop' => 'first_name'}, 'Lorry')
|
105
|
-
|
106
|
-
# The last_name element
|
107
|
-
ln = mock_element('span', {'itemprop' => 'last_name'}, 'Woodman')
|
108
|
-
|
109
|
-
# A non microdata element surrounding last_name
|
110
|
-
surround = mock_element('span', {}, nil, [ln])
|
111
|
-
|
112
|
-
# The surrounding reviewer itemscope element
|
113
|
-
itemscope_el = mock_element('div', {'itemprop' => 'reviewer',
|
114
|
-
'itemtype' => 'person',
|
115
|
-
'itemscope' => true},
|
116
|
-
nil, [fn,surround])
|
117
|
-
@item = Mida::Item.new(itemscope_el)
|
118
|
-
end
|
119
|
-
|
120
|
-
it '#type should return the correct type' do
|
121
|
-
@item.type.should == 'person'
|
122
|
-
end
|
123
|
-
|
124
|
-
it '#vocabulary should return the correct vocabulary' do
|
125
|
-
@item.vocabulary.should == Mida::Vocabulary::Generic
|
126
|
-
end
|
127
|
-
|
128
|
-
it '#id should return the correct id' do
|
129
|
-
@item.id.should == nil
|
130
|
-
end
|
131
|
-
|
132
|
-
it '#properties should return the correct name/value pairs' do
|
133
|
-
@item.properties.should == {
|
134
|
-
'first_name' => ['Lorry'],
|
135
|
-
'last_name' => ['Woodman']
|
136
|
-
}
|
137
|
-
end
|
138
|
-
|
139
|
-
it '#to_h should return the correct type and properties' do
|
140
|
-
@item.to_h.should == {
|
141
|
-
vocabulary: Mida::Vocabulary::Generic,
|
142
|
-
type: 'person',
|
143
|
-
id: nil,
|
144
|
-
properties: {
|
145
|
-
'first_name' => ['Lorry'],
|
146
|
-
'last_name' => ['Woodman']
|
147
|
-
}
|
148
|
-
}
|
149
|
-
end
|
150
|
-
|
151
|
-
end
|
152
|
-
|
153
|
-
describe Mida::Item, "when initialized with an itemscope containing itemprops
|
154
|
-
who's inner text is surrounded by non-microdata elements" do
|
155
|
-
before do
|
156
|
-
html = '<div itemscope><span itemprop="reviewer">Lorry <em>Woodman</em></span></div>'
|
157
|
-
doc = Nokogiri(html)
|
158
|
-
itemscope = doc.search('./*').first
|
7
|
+
itemscope = mock(Mida::Itemscope)
|
8
|
+
itemscope.stub!(:type).and_return(nil)
|
9
|
+
itemscope.stub!(:id).and_return(nil)
|
10
|
+
itemscope.stub!(:properties).and_return({})
|
159
11
|
@item = Mida::Item.new(itemscope)
|
160
12
|
end
|
161
13
|
|
162
|
-
it '#
|
163
|
-
@item.
|
14
|
+
it '#type should return the same type as the itemscope' do
|
15
|
+
@item.type.should == nil
|
164
16
|
end
|
165
17
|
|
166
|
-
it '#
|
167
|
-
@item.
|
18
|
+
it '#vocabulary should return the correct vocabulary' do
|
19
|
+
@item.vocabulary.should == Mida::GenericVocabulary
|
168
20
|
end
|
169
21
|
|
170
|
-
it '#id should return the
|
22
|
+
it '#id should return the same id as the itemscope' do
|
171
23
|
@item.id.should == nil
|
172
24
|
end
|
173
25
|
|
174
|
-
it '#properties should return the
|
175
|
-
@item.properties.should == {
|
176
|
-
'reviewer' => ['Lorry Woodman']
|
177
|
-
}
|
26
|
+
it '#properties should return the same properties as the itemscope' do
|
27
|
+
@item.properties.should == {}
|
178
28
|
end
|
179
29
|
|
180
30
|
it '#to_h should return the correct type and properties' do
|
181
31
|
@item.to_h.should == {
|
182
|
-
vocabulary: Mida::Vocabulary::Generic,
|
183
32
|
type: nil,
|
184
33
|
id: nil,
|
185
|
-
properties: {
|
186
|
-
'reviewer' => ['Lorry Woodman']
|
187
|
-
}
|
34
|
+
properties: {}
|
188
35
|
}
|
189
36
|
end
|
190
|
-
|
191
37
|
end
|
192
38
|
|
193
|
-
describe Mida::Item,
|
194
|
-
nested within another itemprop" do
|
39
|
+
describe Mida::Item, 'when initialized with a complete itemscope of an unknown type' do
|
195
40
|
before do
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
itemscope = doc.search('./*').first
|
41
|
+
itemscope = mock(Mida::Itemscope)
|
42
|
+
itemscope.stub!(:type).and_return("book")
|
43
|
+
itemscope.stub!(:id).and_return("urn:isbn:978-1-849510-50-9")
|
44
|
+
itemscope.stub!(:properties).and_return(
|
45
|
+
{'first_name' => ['Lorry'], 'last_name' => ['Woodman']}
|
46
|
+
)
|
203
47
|
@item = Mida::Item.new(itemscope)
|
204
48
|
end
|
205
49
|
|
206
|
-
it '#
|
207
|
-
@item.
|
50
|
+
it '#type should return the same type as the itemscope' do
|
51
|
+
@item.type.should == "book"
|
208
52
|
end
|
209
53
|
|
210
|
-
it '#
|
211
|
-
@item.
|
54
|
+
it '#vocabulary should return the correct vocabulary' do
|
55
|
+
@item.vocabulary.should == Mida::GenericVocabulary
|
212
56
|
end
|
213
57
|
|
214
|
-
it '#id should return the
|
215
|
-
@item.id.should ==
|
58
|
+
it '#id should return the same id as the itemscope' do
|
59
|
+
@item.id.should == "urn:isbn:978-1-849510-50-9"
|
216
60
|
end
|
217
61
|
|
218
|
-
it '#properties should return the
|
62
|
+
it '#properties should return the same properties as the itemscope' do
|
219
63
|
@item.properties.should == {
|
220
|
-
'
|
221
|
-
'
|
64
|
+
'first_name' => ['Lorry'],
|
65
|
+
'last_name' => ['Woodman']
|
222
66
|
}
|
223
67
|
end
|
224
68
|
|
225
69
|
it '#to_h should return the correct type and properties' do
|
226
70
|
@item.to_h.should == {
|
227
|
-
|
228
|
-
|
229
|
-
id: nil,
|
71
|
+
type: 'book',
|
72
|
+
id: "urn:isbn:978-1-849510-50-9",
|
230
73
|
properties: {
|
231
|
-
'
|
232
|
-
'
|
74
|
+
'first_name' => ['Lorry'],
|
75
|
+
'last_name' => ['Woodman']
|
233
76
|
}
|
234
77
|
}
|
235
78
|
end
|
236
|
-
|
237
79
|
end
|
238
80
|
|
239
|
-
describe Mida::Item, 'when initialized with an itemscope
|
81
|
+
describe Mida::Item, 'when initialized with an itemscope of a known type' do
|
240
82
|
before do
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
# Homemade icecream
|
251
|
-
style = mock_element('span', {'itemprop' => 'style'}, 'Homemade')
|
252
|
-
|
253
|
-
# The surrounding icecreame-type itemscope
|
254
|
-
@sb_flavour = mock_element('div', {'itemprop' => 'flavour',
|
255
|
-
'itemtype' => 'icecream-type',
|
256
|
-
'itemscope' => true},
|
257
|
-
nil, [fruit,style])
|
83
|
+
class Person < Mida::Vocabulary
|
84
|
+
itemtype %r{http://example.com/vocab/person}
|
85
|
+
has_one 'name'
|
86
|
+
has_many 'date' do
|
87
|
+
extract Mida::DataType::ISO8601Date, Mida::DataType::Text
|
88
|
+
end
|
89
|
+
has_many 'url'
|
90
|
+
end
|
258
91
|
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
92
|
+
itemscope = mock(Mida::Itemscope)
|
93
|
+
itemscope.stub!(:type).and_return("http://example.com/vocab/person")
|
94
|
+
itemscope.stub!(:id).and_return(nil)
|
95
|
+
itemscope.stub!(:properties).and_return(
|
96
|
+
{ 'name' => ['Lorry Woodman'],
|
97
|
+
'date' => ['2nd October 2009', '2009-10-02'],
|
98
|
+
'url' => ['http://example.com/user/lorry']
|
99
|
+
}
|
100
|
+
)
|
101
|
+
@item = Mida::Item.new(itemscope)
|
264
102
|
end
|
265
103
|
|
266
104
|
it '#vocabulary should return the correct vocabulary' do
|
267
|
-
@item.vocabulary.should ==
|
105
|
+
@item.vocabulary.should == Person
|
268
106
|
end
|
269
107
|
|
270
|
-
it '
|
271
|
-
@item.
|
108
|
+
it 'should return has_one properties as a single value' do
|
109
|
+
@item.properties['name'].should == 'Lorry Woodman'
|
272
110
|
end
|
273
111
|
|
274
|
-
it '
|
275
|
-
@item.
|
112
|
+
it 'should return has_many properties as an array' do
|
113
|
+
@item.properties['url'].should == ['http://example.com/user/lorry']
|
276
114
|
end
|
277
115
|
|
278
|
-
it '
|
279
|
-
@item.properties.should ==
|
280
|
-
'flavour' => [
|
281
|
-
'Lemon Sorbet',
|
282
|
-
'Apricot Sorbet',
|
283
|
-
Mida::Item.new(@sb_flavour)
|
284
|
-
]
|
285
|
-
}
|
116
|
+
it 'should reject datatypes that are not valid' do
|
117
|
+
@item.properties['date'][0].should == '2nd October 2009'
|
286
118
|
end
|
287
119
|
|
288
|
-
it '
|
289
|
-
@item.
|
290
|
-
vocabulary: Mida::Vocabulary::Generic,
|
291
|
-
type: 'icecreams',
|
292
|
-
id: nil,
|
293
|
-
properties: {
|
294
|
-
'flavour' => [
|
295
|
-
'Lemon Sorbet',
|
296
|
-
'Apricot Sorbet',
|
297
|
-
{ vocabulary: Mida::Vocabulary::Generic,
|
298
|
-
type: 'icecream-type',
|
299
|
-
id: nil,
|
300
|
-
properties: {
|
301
|
-
'fruit' => ['Strawberry'],
|
302
|
-
'style' => ['Homemade']
|
303
|
-
}
|
304
|
-
}
|
305
|
-
]
|
306
|
-
}
|
307
|
-
}
|
120
|
+
it 'should accept datatypes that are valid' do
|
121
|
+
@item.properties['date'][1].should == Date.iso8601('2009-10-02')
|
308
122
|
end
|
309
123
|
|
310
|
-
|
311
|
-
|
312
|
-
describe Mida::Item, 'when initialized with an itemscope containing itemrefs' do
|
313
|
-
|
314
|
-
before do
|
315
|
-
|
316
|
-
name = mock_element('span', {'itemprop' => 'name'}, 'Amanda')
|
317
|
-
name_p = mock_element('p', {'id' => 'a'}, nil, [name])
|
318
|
-
|
319
|
-
band_name = mock_element('span', {'itemprop' => 'band_name'}, 'Jazz Band')
|
320
|
-
band_size = mock_element('span', {'itemprop' => 'band_size'}, '12')
|
321
|
-
band_div = mock_element('div', {'id' => 'c'}, nil, [band_name, band_size])
|
322
|
-
@empty_band_div = mock_element('div', {'id' => 'b',
|
323
|
-
'itemprop' => 'band',
|
324
|
-
'itemref' => 'c',
|
325
|
-
'itemscope' => true},
|
326
|
-
nil, [],
|
327
|
-
{'c' => band_div})
|
328
|
-
|
329
|
-
|
330
|
-
age = mock_element('span', {'itemprop' => 'age'}, '30')
|
331
|
-
age_div = mock_element('div', {'itemref' => 'a b',
|
332
|
-
'itemscope' => true},
|
333
|
-
nil, [age],
|
334
|
-
{'a' => name_p, 'b' => @empty_band_div})
|
335
|
-
|
336
|
-
@item = Mida::Item.new(age_div)
|
124
|
+
it 'should reject datatypes that are not valid' do
|
125
|
+
@item.properties['date'][1].should == Date.iso8601('2009-10-02')
|
337
126
|
end
|
338
127
|
|
339
|
-
it '#
|
340
|
-
@item.vocabulary.should == Mida::Vocabulary::Generic
|
341
|
-
end
|
342
|
-
|
343
|
-
it '#type should return the correct type' do
|
344
|
-
@item.type.should == nil
|
345
|
-
end
|
346
|
-
|
347
|
-
it '#id should return the correct id' do
|
348
|
-
@item.id.should == nil
|
349
|
-
end
|
350
|
-
|
351
|
-
it '#properties should return the correct name/value pairs' do
|
128
|
+
it '#properties should return the same properties as the itemscope' do
|
352
129
|
@item.properties.should == {
|
353
|
-
'
|
354
|
-
'
|
355
|
-
'
|
130
|
+
'name' => 'Lorry Woodman',
|
131
|
+
'date' => ['2nd October 2009', Date.iso8601('2009-10-02')],
|
132
|
+
'url' => ['http://example.com/user/lorry']
|
356
133
|
}
|
357
134
|
end
|
358
135
|
|
359
136
|
it '#to_h should return the correct type and properties' do
|
360
137
|
@item.to_h.should == {
|
361
|
-
|
362
|
-
type: nil,
|
138
|
+
type: 'http://example.com/vocab/person',
|
363
139
|
id: nil,
|
364
140
|
properties: {
|
365
|
-
'
|
366
|
-
'
|
367
|
-
'
|
368
|
-
vocabulary: Mida::Vocabulary::Generic,
|
369
|
-
type: nil,
|
370
|
-
id: nil,
|
371
|
-
properties: {
|
372
|
-
'band_name' => ['Jazz Band'],
|
373
|
-
'band_size' => ['12']
|
374
|
-
}
|
375
|
-
}]
|
141
|
+
'name' => 'Lorry Woodman',
|
142
|
+
'date' => ['2nd October 2009', Date.iso8601('2009-10-02')],
|
143
|
+
'url' => ['http://example.com/user/lorry']
|
376
144
|
}
|
377
145
|
}
|
378
146
|
end
|
379
147
|
|
380
148
|
end
|
381
149
|
|
382
|
-
describe Mida::Item, 'when initialized with an itemscope
|
383
|
-
|
150
|
+
describe Mida::Item, 'when initialized with an itemscope of a known type that does not fully match vocabulary' do
|
384
151
|
before do
|
152
|
+
# Make sure the class is redefined afresh to make sure that
|
153
|
+
# inherited() hook is called
|
154
|
+
Mida::Vocabulary.unregister(Person)
|
155
|
+
Object.send(:remove_const, :Person)
|
156
|
+
class Person < Mida::Vocabulary
|
157
|
+
itemtype %r{http://example.com/vocab/person}
|
158
|
+
has_one 'name', 'tel'
|
159
|
+
has_many 'url', 'city'
|
160
|
+
end
|
385
161
|
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
'
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
162
|
+
itemscope = mock(Mida::Itemscope)
|
163
|
+
itemscope.stub!(:type).and_return("http://example.com/vocab/person")
|
164
|
+
itemscope.stub!(:id).and_return(nil)
|
165
|
+
itemscope.stub!(:properties).and_return(
|
166
|
+
{ 'name' => ['Lorry Woodman'],
|
167
|
+
'tel' => ['000004847582', '111111857485'],
|
168
|
+
'url' => ['http://example.com/user/lorry'],
|
169
|
+
'city' => ['Bristol']
|
170
|
+
}
|
171
|
+
)
|
172
|
+
@item = Mida::Item.new(itemscope)
|
395
173
|
end
|
396
174
|
|
397
175
|
it '#vocabulary should return the correct vocabulary' do
|
398
|
-
@item.vocabulary.should ==
|
399
|
-
end
|
400
|
-
|
401
|
-
it '#type should return the correct type' do
|
402
|
-
@item.type.should == 'book'
|
403
|
-
end
|
404
|
-
|
405
|
-
it '#id should return the correct id' do
|
406
|
-
@item.id.should == 'urn:isbn:978-1-849510-50-9'
|
176
|
+
@item.vocabulary.should == Person
|
407
177
|
end
|
408
178
|
|
409
|
-
it '
|
410
|
-
@item.properties.
|
411
|
-
'title' => ['Hacking Vim 7.2'],
|
412
|
-
'author' => ['Kim Schulz']
|
413
|
-
}
|
179
|
+
it 'should not keep properties that have too many values' do
|
180
|
+
@item.properties.should_not have_key('tel')
|
414
181
|
end
|
415
182
|
|
416
|
-
it '
|
417
|
-
@item.
|
418
|
-
vocabulary: Mida::Vocabulary::Generic,
|
419
|
-
type: 'book',
|
420
|
-
id: 'urn:isbn:978-1-849510-50-9',
|
421
|
-
properties: {
|
422
|
-
'title' => ['Hacking Vim 7.2'],
|
423
|
-
'author' => ['Kim Schulz']
|
424
|
-
}
|
425
|
-
}
|
183
|
+
it 'should keep have_many properties even if they have only one value' do
|
184
|
+
@item.properties.should have_key('city')
|
426
185
|
end
|
427
186
|
|
428
187
|
end
|
429
188
|
|
430
|
-
describe Mida::Item, 'when initialized with an itemscope containing
|
189
|
+
describe Mida::Item, 'when initialized with an itemscope containing another correct itemscope' do
|
431
190
|
before do
|
191
|
+
class Tel < Mida::Vocabulary
|
192
|
+
itemtype %r{http://example.com/vocab/tel}
|
193
|
+
has_one 'dial_code', 'number'
|
194
|
+
end
|
432
195
|
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
@fn = mock_element('span', {'itemprop' => 'first_name'}, 'Lorry')
|
441
|
-
|
442
|
-
# The last_name
|
443
|
-
@ln = mock_element('span', {'itemprop' => 'last_name'}, 'Woodman')
|
444
|
-
|
445
|
-
# The organization name
|
446
|
-
@org_name = mock_element('span', {'itemprop' => 'name'}, 'Acme')
|
447
|
-
|
448
|
-
# The surrounding organization itemscope
|
449
|
-
@org_el = mock_element('div', {'itemprop' => 'represents',
|
450
|
-
'itemtype' => 'organization',
|
451
|
-
'itemscope' => true}, nil, [@org_name])
|
452
|
-
|
453
|
-
# The surrounding reviewer itemscope
|
454
|
-
@reviewer_el = mock_element('div', {'itemprop' => 'reviewer',
|
455
|
-
'itemtype' => 'person',
|
456
|
-
'itemscope' => true},
|
457
|
-
nil, [@fn,@ln, @org_el])
|
458
|
-
|
459
|
-
# The surrounding reviewer itemscope
|
460
|
-
@review_el = mock_element('div', {'itemtype' => 'review', 'itemscope' => true}, nil, [@item_name, @rating, @reviewer_el])
|
461
|
-
|
462
|
-
@item = Mida::Item.new(@review_el)
|
463
|
-
|
464
|
-
end
|
196
|
+
class Person < Mida::Vocabulary
|
197
|
+
itemtype %r{http://example.com/vocab/person}
|
198
|
+
has_one 'name'
|
199
|
+
has_many 'tel' do
|
200
|
+
extract Tel, Mida::DataType::Text
|
201
|
+
end
|
202
|
+
end
|
465
203
|
|
466
|
-
|
204
|
+
tel_itemscope = mock(Mida::Itemscope)
|
205
|
+
tel_itemscope.stub!(:kind_of?).any_number_of_times.with(Mida::Itemscope).and_return(true)
|
206
|
+
tel_itemscope.stub!(:type).and_return("http://example.com/vocab/tel")
|
207
|
+
tel_itemscope.stub!(:id).and_return(nil)
|
208
|
+
tel_itemscope.stub!(:properties).and_return(
|
209
|
+
{ 'dial_code' => ['0248583'],
|
210
|
+
'number' => ['000004847582'],
|
211
|
+
}
|
212
|
+
)
|
213
|
+
person_itemscope = mock(Mida::Itemscope)
|
214
|
+
person_itemscope.stub!(:type).and_return("http://example.com/vocab/person")
|
215
|
+
person_itemscope.stub!(:id).and_return(nil)
|
216
|
+
person_itemscope.stub!(:properties).and_return(
|
217
|
+
{ 'name' => ['Lorry Woodman'],
|
218
|
+
'tel' => ['000004847582', tel_itemscope],
|
219
|
+
}
|
220
|
+
)
|
221
|
+
@item = Mida::Item.new(person_itemscope)
|
467
222
|
end
|
468
223
|
|
469
224
|
it '#vocabulary should return the correct vocabulary' do
|
470
|
-
@item.vocabulary.should ==
|
471
|
-
end
|
472
|
-
|
473
|
-
it '#type should return the correct type' do
|
474
|
-
@item.type.should == 'review'
|
475
|
-
end
|
476
|
-
|
477
|
-
it '#id should return the correct id' do
|
478
|
-
@item.id.should == nil
|
225
|
+
@item.vocabulary.should == Person
|
479
226
|
end
|
480
227
|
|
481
|
-
it '
|
482
|
-
@item.properties.should ==
|
483
|
-
|
484
|
-
'
|
485
|
-
'
|
228
|
+
it 'should validate and convert the nested itemscope' do
|
229
|
+
@item.properties['tel'][1].vocabulary.should == Tel
|
230
|
+
@item.properties['tel'][1].properties.should == {
|
231
|
+
'dial_code' => '0248583',
|
232
|
+
'number' => '000004847582',
|
486
233
|
}
|
487
234
|
end
|
488
235
|
|
489
|
-
it '
|
490
|
-
@item.
|
491
|
-
vocabulary: Mida::Vocabulary::Generic,
|
492
|
-
type: 'review',
|
493
|
-
id: nil,
|
494
|
-
properties: {
|
495
|
-
'item_name' => ['Acme Anvil'],
|
496
|
-
'rating' => ['5'],
|
497
|
-
'reviewer' => [{
|
498
|
-
vocabulary: Mida::Vocabulary::Generic,
|
499
|
-
type: 'person',
|
500
|
-
id: nil,
|
501
|
-
properties: {
|
502
|
-
'first_name' => ['Lorry'],
|
503
|
-
'last_name' => ['Woodman'],
|
504
|
-
'represents' => [{
|
505
|
-
vocabulary: Mida::Vocabulary::Generic,
|
506
|
-
type: 'organization',
|
507
|
-
id: nil,
|
508
|
-
properties: {
|
509
|
-
'name' => ['Acme']
|
510
|
-
}
|
511
|
-
}]
|
512
|
-
}
|
513
|
-
}]
|
514
|
-
}
|
515
|
-
}
|
236
|
+
it 'should accept the text tel' do
|
237
|
+
@item.properties['tel'][0].should == '000004847582'
|
516
238
|
end
|
239
|
+
|
517
240
|
end
|
518
241
|
|
519
|
-
describe Mida::Item, 'when initialized with an itemscope
|
242
|
+
describe Mida::Item, 'when initialized with an itemscope containing another invalid itemscope' do
|
520
243
|
before do
|
521
|
-
|
522
|
-
class Colour < Mida::VocabularyDesc
|
523
|
-
itemtype %r{http://example.com/vocab/colour}
|
524
|
-
has_one 'red', 'green', 'blue'
|
525
|
-
end
|
526
|
-
Mida::Vocabulary.register(Colour)
|
527
|
-
|
528
|
-
class Person < Mida::VocabularyDesc
|
244
|
+
class Person < Mida::Vocabulary
|
529
245
|
itemtype %r{http://example.com/vocab/person}
|
530
246
|
has_one 'name'
|
531
|
-
|
532
|
-
has_many 'limbs'
|
533
|
-
has_many 'favourite-colours' do
|
534
|
-
types Colour
|
535
|
-
end
|
247
|
+
has_many 'tel'
|
536
248
|
end
|
537
|
-
Mida::Vocabulary.register(Person)
|
538
|
-
|
539
|
-
red = mock_element('span', {'itemprop' => 'red'}, '0xFF')
|
540
|
-
green = mock_element('span', {'itemprop' => 'green'}, '0x00')
|
541
|
-
blue = mock_element('span', {'itemprop' => 'blue'}, '0xFF')
|
542
|
-
purple = mock_element('div', {'itemscope' => true,
|
543
|
-
'itemtype' => 'http://example.com/vocab/colour',
|
544
|
-
'itemprop' => 'favourite-colours'},
|
545
|
-
nil, [red, green, blue])
|
546
|
-
orange = mock_element('span', {'itemprop' => 'favourite-colours'}, 'Orange')
|
547
|
-
|
548
|
-
name1 = mock_element('span', {'itemprop' => 'name'}, 'Lawrence Woodman')
|
549
|
-
name2 = mock_element('span', {'itemprop' => 'name'}, 'Lorry Woodman')
|
550
|
-
url = mock_element('a', {'itemprop' => 'url', 'href' => 'http://example.com/myhomepage'})
|
551
|
-
arm = mock_element('span', {'itemprop' => 'limbs'}, 'Arm')
|
552
|
-
leg = mock_element('span', {'itemprop' => 'limbs'}, 'Leg')
|
553
|
-
robert_wilson = mock_element('span', {'itemprop' => 'favourite-author'}, 'Robert Wilson')
|
554
|
-
itemscope_el = mock_element('div', {'itemscope' => true,
|
555
|
-
'itemtype' =>'http://example.com/vocab/person'
|
556
|
-
}, nil, [name1, name2, url, arm, leg, purple, orange, robert_wilson])
|
557
|
-
@item = Mida::Item.new(itemscope_el, "http://example.com")
|
558
|
-
end
|
559
|
-
|
560
|
-
it '#vocabulary should return the correct vocabulary' do
|
561
|
-
@item.vocabulary.should == Person
|
562
|
-
end
|
563
|
-
|
564
|
-
it 'should reject properties that have multiple values if has_one specified' do
|
565
|
-
@item.properties.should_not have_key('name')
|
566
|
-
end
|
567
|
-
|
568
|
-
it 'should accept properties that have a single value if has_one specified' do
|
569
|
-
@item.properties['url'].should == ['http://example.com/myhomepage']
|
570
|
-
end
|
571
249
|
|
572
|
-
|
573
|
-
|
250
|
+
tel_itemscope = mock(Mida::Itemscope)
|
251
|
+
tel_itemscope.stub!(:kind_of?).any_number_of_times.with(Mida::Itemscope).and_return(true)
|
252
|
+
tel_itemscope.stub!(:type).and_return("http://example.com/vocab/tel")
|
253
|
+
tel_itemscope.stub!(:id).and_return(nil)
|
254
|
+
tel_itemscope.stub!(:properties).and_return(
|
255
|
+
{ 'dial_code' => ['0248583'],
|
256
|
+
'number' => ['000004847582'],
|
257
|
+
}
|
258
|
+
)
|
259
|
+
person_itemscope = mock(Mida::Itemscope)
|
260
|
+
person_itemscope.stub!(:type).and_return("http://example.com/vocab/person")
|
261
|
+
person_itemscope.stub!(:id).and_return(nil)
|
262
|
+
person_itemscope.stub!(:properties).and_return(
|
263
|
+
{ 'name' => ['Lorry Woodman'],
|
264
|
+
'tel' => ['000004847582', tel_itemscope],
|
265
|
+
}
|
266
|
+
)
|
267
|
+
@item = Mida::Item.new(person_itemscope)
|
574
268
|
end
|
575
269
|
|
576
|
-
it 'should
|
577
|
-
@item.properties['
|
578
|
-
@item.properties['
|
270
|
+
it 'should only accept values of the correct type' do
|
271
|
+
@item.properties['tel'].size.should == 1
|
272
|
+
@item.properties['tel'][0].should == '000004847582'
|
579
273
|
end
|
580
274
|
|
581
|
-
it 'should reject properties that are not specified' do
|
582
|
-
@item.properties.should_not have_key('favourite-author')
|
583
|
-
end
|
584
275
|
end
|