xml_mapper 0.3.2

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.
@@ -0,0 +1,515 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "XmlMapper" do
4
+ before(:each) do
5
+ @mapper = XmlMapper.new
6
+ end
7
+
8
+ describe "#add_mapping" do
9
+ it "adds the correct mappings when only one symbol given" do
10
+ @mapper.add_mapping(:text, :title)
11
+ @mapper.mappings.should == [{ :type => :text, :xpath => "title", :key => :title, :options => {} }]
12
+ end
13
+
14
+ it "adds the correct mapping when type is not text" do
15
+ @mapper.add_mapping(:length, :title)
16
+ @mapper.mappings.should == [{ :type => :length, :xpath => "title", :key => :title, :options => {} }]
17
+ end
18
+
19
+ it "adds the correct mapping when type is node" do
20
+ @mapper.add_mapping(:node, :title)
21
+ @mapper.mappings.should == [{ :type => :node, :xpath => "title", :key => :title, :options => {} }]
22
+ end
23
+
24
+ it "adds multiple mappings when more symbols given" do
25
+ @mapper.add_mapping(:text, :first_name, :last_name)
26
+ @mapper.mappings.should == [
27
+ { :type => :text, :xpath => "first_name", :key => :first_name, :options => {} },
28
+ { :type => :text, :xpath => "last_name", :key => :last_name, :options => {} },
29
+ ]
30
+ end
31
+
32
+ it "adds mappings when mapping given as hash" do
33
+ @mapper.add_mapping(:text, :name => :first_name)
34
+ @mapper.mappings.should == [{ :type => :text, :xpath => "name", :key => :first_name, :options => {} }]
35
+ end
36
+
37
+ it "adds mappings with options when mapping given as symbols and last arg is hash" do
38
+ @mapper.add_mapping(:text, :name, :born, :after_map => :to_s)
39
+ @mapper.mappings.should == [
40
+ { :type => :text, :xpath => "name", :key => :name, :options => { :after_map => :to_s } },
41
+ { :type => :text, :xpath => "born", :key => :born, :options => { :after_map => :to_s } },
42
+ ]
43
+ end
44
+ end
45
+
46
+ describe "map attributes" do
47
+ before(:each) do
48
+ @xml = %(
49
+ <album>
50
+ <title>Black on Both Sides</title>
51
+ <artist_name>Mos Def</artist_name>
52
+ <track_number>7</track_number>
53
+ </album>)
54
+ end
55
+
56
+ it "maps the correct inner text when node found" do
57
+ @mapper.add_mapping(:text, :artist_name, :title)
58
+ @mapper.attributes_from_xml(@xml).should == { :title => "Black on Both Sides", :artist_name => "Mos Def" }
59
+ end
60
+
61
+ describe "#exists" do
62
+ it "returns true when node exists" do
63
+ xml = %(<album><title>Black on Both Sides</title><rights><country>DE</country></rights></album>)
64
+ @mapper.add_mapping(:exists, "rights[country='DE']" => :allows_streaming)
65
+ @mapper.attributes_from_xml(xml).should == { :allows_streaming => true }
66
+ end
67
+
68
+ it "returns false when node does not exist" do
69
+ xml = %(<album><title>Black on Both Sides</title><rights><country>DE</country></rights></album>)
70
+ @mapper.add_mapping(:exists, "rights[country='FR']" => :allows_streaming)
71
+ @mapper.attributes_from_xml(xml).should == { :allows_streaming => false }
72
+ end
73
+ end
74
+
75
+ describe "#node" do
76
+ it "returns a nokogiri node" do
77
+ @mapper.add_mapping(:node, :title)
78
+ @mapper.attributes_from_xml(@xml)[:title].should be_an_instance_of(Nokogiri::XML::Element)
79
+ end
80
+
81
+ it "returns nil when node not found" do
82
+ @mapper.add_mapping(:node, :rgne)
83
+ @mapper.attributes_from_xml(@xml)[:rgne].should be_nil
84
+ end
85
+
86
+ it "returns the correct nokogiri node" do
87
+ @mapper.add_mapping(:node, :title)
88
+ node = @mapper.attributes_from_xml(@xml)[:title]
89
+ node.inner_text.should == "Black on Both Sides"
90
+ end
91
+
92
+ it "can be combined with after_map" do
93
+ @mapper.add_mapping(:node, :title, :after_map => :inner_text)
94
+ @mapper.attributes_from_xml(@xml)[:title].should == "Black on Both Sides"
95
+ end
96
+ end
97
+
98
+ it "maps not found nodes to nil" do
99
+ @mapper.add_mapping(:text, :artist_name, :version_title, :long_title)
100
+ @mapper.attributes_from_xml(@xml).should == {
101
+ :version_title => nil, :long_title => nil, :artist_name => "Mos Def"
102
+ }
103
+ end
104
+
105
+ it "converts integers to integer when found" do
106
+ @mapper.add_mapping(:text, :artist_name)
107
+ @mapper.add_mapping(:integer, :track_number)
108
+ @mapper.attributes_from_xml(@xml).should == {
109
+ :track_number => 7, :artist_name => "Mos Def"
110
+ }
111
+ end
112
+
113
+ it "does not convert nil to integer for integer type" do
114
+ @mapper.add_mapping(:text, :artist_name)
115
+ @mapper.add_mapping(:integer, :track_number, :set_count)
116
+ @mapper.attributes_from_xml(@xml).should == {
117
+ :track_number => 7, :artist_name => "Mos Def", :set_count => nil
118
+ }
119
+ end
120
+
121
+ it "calls method with name type on value when found and responding" do
122
+ @mapper.add_mapping(:text, :artist_name, :after_map => :upcase)
123
+ @mapper.attributes_from_xml(@xml).should == {
124
+ :artist_name => "MOS DEF"
125
+ }
126
+ end
127
+
128
+ it "uses mapper method defined in xml_mapper when value does not respond to :after_map" do
129
+ class << @mapper
130
+ def double(value)
131
+ value.to_s * 2
132
+ end
133
+ end
134
+
135
+ @mapper.add_mapping(:text, :artist_name, :after_map => :double)
136
+ @mapper.attributes_from_xml(@xml).should == {
137
+ :artist_name => "Mos DefMos Def"
138
+ }
139
+ end
140
+
141
+ it "uses mapper method defined in xml_mapper when value does not respond to :after_map and given as hash" do
142
+ class << @mapper
143
+ def double(value)
144
+ value.to_s * 2
145
+ end
146
+ end
147
+ # [{:type=>:text, :xpath=>"Graphic/ImgFormat", :key=>:image_format, :options=>{:after_map=>:double}}]
148
+ @mapper.add_mapping(:text, { :artist_name => :name }, {:after_map => :double})
149
+ @mapper.attributes_from_xml(@xml).should == {
150
+ :name => "Mos DefMos Def"
151
+ }
152
+ end
153
+
154
+ it "takes a nokogiri node as argument" do
155
+ @mapper.add_mapping(:text, :artist_name)
156
+ @mapper.attributes_from_xml(Nokogiri::XML(@xml)).should == {
157
+ :artist_name => "Mos Def"
158
+ }
159
+ end
160
+
161
+ it "should also takes an array of nodes as argument" do
162
+ @mapper.add_mapping(:text, :artist_name)
163
+ @mapper.attributes_from_xml([Nokogiri::XML(@xml), Nokogiri::XML(@xml)]).should == [
164
+ { :artist_name => "Mos Def" },
165
+ { :artist_name => "Mos Def" }
166
+ ]
167
+ end
168
+
169
+ describe "mapping embedded attributes" do
170
+ before(:each) do
171
+ @xml = %(
172
+ <album>
173
+ <artist_name>Mos Def</artist_name>
174
+ <tracks>
175
+ <track>
176
+ <track_number>1</track_number>
177
+ <title>Track 1</title>
178
+ </track>
179
+ <track>
180
+ <track_number>2</track_number>
181
+ <title>Track 2</title>
182
+ </track>
183
+ </tracks>
184
+ </album>
185
+ )
186
+ end
187
+
188
+ it "maps all embedded attributes" do
189
+ submapper = XmlMapper.new
190
+ submapper.add_mapping(:integer, :track_number)
191
+ submapper.add_mapping(:text, :title)
192
+ @mapper.add_mapping(:text, :artist_name)
193
+ @mapper.add_mapping(:many, { "tracks/track" => :tracks }, :mapper => submapper)
194
+ @mapper.attributes_from_xml(@xml).should == {
195
+ :artist_name => "Mos Def",
196
+ :tracks => [
197
+ { :title => "Track 1", :track_number => 1 },
198
+ { :title => "Track 2", :track_number => 2 },
199
+ ]
200
+ }
201
+ end
202
+ end
203
+ end
204
+
205
+ describe "#attributes_from_xml_path" do
206
+ before(:each) do
207
+ @mapper.add_mapping(:text, :title)
208
+ @xml = %(
209
+ <album>
210
+ <title>Black on Both Sides</title>
211
+ </album>
212
+ )
213
+ File.stub(:read).and_return @xml
214
+ end
215
+
216
+ it "sets the xml_path" do
217
+ @mapper.attributes_from_xml_path("/some/path.xml").should == {
218
+ :title => "Black on Both Sides", :xml_path => "/some/path.xml"
219
+ }
220
+ end
221
+
222
+ it "calls File.read with correct parameters" do
223
+ File.should_receive(:read).with("/some/path.xml").and_return @xml
224
+ @mapper.attributes_from_xml_path("/some/path.xml")
225
+ end
226
+
227
+ it "allows using the xml_path in after_map block" do
228
+ @mapper.after_map do
229
+ self[:new_xml_path] = self[:xml_path]
230
+ end
231
+ @mapper.attributes_from_xml_path("/some/path.xml")[:new_xml_path].should == "/some/path.xml"
232
+ end
233
+
234
+ it "allows deleting the xml_path in after_map block" do
235
+ @mapper.after_map do
236
+ self.delete(:xml_path)
237
+ end
238
+ @mapper.attributes_from_xml_path("/some/path.xml").should_not have_key(:xml_path)
239
+ end
240
+ end
241
+
242
+ describe "#after_map" do
243
+ before(:each) do
244
+ @mapper.after_map do
245
+ self[:upc] = "1234"
246
+ end
247
+ end
248
+
249
+ it "assigns after_map block" do
250
+ @mapper.after_map_block.should_not be_nil
251
+ end
252
+
253
+ it "assigns a block to after_map_block" do
254
+ @mapper.after_map_block.should be_an_instance_of(Proc)
255
+ end
256
+
257
+ it "should executes after_map block after mapping" do
258
+ @mapper.attributes_from_xml("<album><title>Some Titel</title></album>").should == {
259
+ :upc => "1234"
260
+ }
261
+ end
262
+ end
263
+
264
+ describe "converting strings" do
265
+ describe "#string_to_boolean" do
266
+ {
267
+ "true" => true, "false" => false, "y" => true, "TRUE" => true, "" => nil, "YES" => true, "yes" => true,
268
+ "n" => false
269
+ }.each do |value, result|
270
+ it "converts #{value.inspect} to #{result}" do
271
+ @mapper.string_to_boolean(value).should == result
272
+ end
273
+ end
274
+ end
275
+ end
276
+
277
+ describe "defining a DSL" do
278
+ def create_class(base_class = "XmlMapper")
279
+ class_name = "TestMapping#{Time.now.to_f.to_s.gsub(".", "")}"
280
+ str = %(
281
+ class #{class_name} < #{base_class}
282
+ end
283
+ )
284
+ eval(str)
285
+ eval(class_name)
286
+ end
287
+
288
+ before(:each) do
289
+ # so that we have a new class in each spec
290
+ @clazz = create_class
291
+ end
292
+
293
+ it "initializes a mapper of the same class" do
294
+ @clazz.mapper.class.name.should == @clazz.name
295
+ end
296
+
297
+ it "sets the correct mapping for text keyword" do
298
+ @clazz.text(:title)
299
+ @clazz.mapper.mappings.should == [{ :type => :text, :key => :title, :xpath => "title", :options => {} }]
300
+ end
301
+
302
+ it "sets the correct mapping for node keyword" do
303
+ @clazz.node(:title)
304
+ @clazz.mapper.mappings.should == [{ :type => :node, :key => :title, :xpath => "title", :options => {} }]
305
+ end
306
+
307
+ it "sets the correct mapping for text keyword" do
308
+ @clazz.integer(:title)
309
+ @clazz.mapper.mappings.should == [{ :type => :integer, :key => :title, :xpath => "title", :options => {} }]
310
+ end
311
+
312
+ it "allows getting attributes form xml_path" do
313
+ File.stub(:read).and_return %(<album><title>Test Title</title></album>)
314
+ @clazz.text(:title)
315
+ @clazz.attributes_from_xml_path("/some/path.xml").should == {
316
+ :title => "Test Title",
317
+ :xml_path => "/some/path.xml"
318
+ }
319
+ end
320
+
321
+ it "allows defining a after_map block" do
322
+ @clazz.after_map do
323
+ self[:upc] = "1234"
324
+ end
325
+ @clazz.text(:title)
326
+ @clazz.attributes_from_xml(%(<album><title>Test Title</title></album>)).should == {
327
+ :upc => "1234", :title => "Test Title"
328
+ }
329
+ end
330
+
331
+ it "allows deleteing the xml path in after_block" do
332
+ @clazz.after_map do
333
+ self.delete(:xml_path)
334
+ end
335
+ File.stub(:read).and_return %(<album><title>Test Title</title></album>)
336
+ @clazz.attributes_from_xml_path("/some/path.xml").should_not have_key(:xml_path)
337
+ end
338
+
339
+ it "allows using attributes from superclass in after_map block"
340
+
341
+ it "allows using of instance methods of mapper for after_map" do
342
+ @clazz.class_eval do
343
+ def custom_mapper(txt)
344
+ txt * 2
345
+ end
346
+ end
347
+
348
+ @clazz.text(:title, :after_map => :custom_mapper)
349
+ @clazz.attributes_from_xml(%(<album><title>Test</title></album>)).should == {
350
+ :title => "TestTest"
351
+ }
352
+ end
353
+
354
+ it "accepts boolean as keyword" do
355
+ @clazz.boolean(:allows_streaming)
356
+ xml = %(<album><title>Test Title</title><allows_streaming>true</allows_streaming></album>)
357
+ @clazz.attributes_from_xml(xml).should == { :allows_streaming => true }
358
+ end
359
+
360
+ it "accepts exists as keyword" do
361
+ @clazz.exists("rights[country='DE']" => :allows_streaming)
362
+ xml = %(<album><title>Black on Both Sides</title><rights><country>DE</country></rights></album>)
363
+ @clazz.attributes_from_xml(xml).should == { :allows_streaming => true }
364
+ end
365
+
366
+ describe "#within" do
367
+ it "adds the within xpath to all xpath mappings" do
368
+ @clazz.within("artist") do
369
+ text :name => :artist_name
370
+ integer :id => :artist_id
371
+ end
372
+ @clazz.mapper.mappings.should == [
373
+ { :type => :text, :xpath => "artist/name", :key => :artist_name, :options => {} },
374
+ { :type => :integer, :xpath => "artist/id", :key => :artist_id, :options => {} },
375
+ ]
376
+ end
377
+
378
+ it "adds all nested within xpaths to xpath mappings" do
379
+ @clazz.within("contributions") do
380
+ within "artist" do
381
+ text :name => :artist_name
382
+ integer :id => :artist_id
383
+ end
384
+ end
385
+ @clazz.mapper.mappings.should == [
386
+ { :type => :text, :xpath => "contributions/artist/name", :key => :artist_name, :options => {} },
387
+ { :type => :integer, :xpath => "contributions/artist/id", :key => :artist_id, :options => {} },
388
+ ]
389
+ end
390
+
391
+ it "allows multiple within blocks on same level" do
392
+ @clazz.within "artist" do
393
+ text :name => :artist_name
394
+ end
395
+ @clazz.within "file" do
396
+ text :file_name
397
+ end
398
+ @clazz.mapper.mappings.should == [
399
+ { :type => :text, :xpath => "artist/name", :key => :artist_name, :options => {} },
400
+ { :type => :text, :xpath => "file/file_name", :key => :file_name, :options => {} },
401
+ ]
402
+ end
403
+ end
404
+
405
+ describe "with mapper hierarchy" do
406
+ it "attributes_from_xml includes superclass mapper as well" do
407
+ @clazz.text(:artist_name)
408
+ subclazz = create_class(@clazz.name)
409
+ subclazz.text(:title)
410
+ xml = %(
411
+ <album>
412
+ <artist_name>Mos Def</artist_name>
413
+ <title>Black on Both Sides</title>
414
+ </album>
415
+ )
416
+ subclazz.attributes_from_xml(xml).should == {
417
+ :artist_name => "Mos Def",
418
+ :title => "Black on Both Sides"
419
+ }
420
+ end
421
+
422
+ it "overwrites superclass mapper" do
423
+ @clazz.text(:artist_name)
424
+ subclazz = create_class(@clazz.name)
425
+ subclazz.text(:title)
426
+ subclazz.text(:artist_name, :after_map => :upcase)
427
+ xml = %(
428
+ <album>
429
+ <artist_name>Mos Def</artist_name>
430
+ <title>Black on Both Sides</title>
431
+ </album>
432
+ )
433
+ subclazz.attributes_from_xml(xml).should == {
434
+ :artist_name => "MOS DEF",
435
+ :title => "Black on Both Sides"
436
+ }
437
+ end
438
+
439
+ it "attributes_from_xml_path includes superclass mapper as well" do
440
+ @clazz.text(:artist_name)
441
+ subclazz = create_class(@clazz.name)
442
+ subclazz.text(:title)
443
+ xml = %(
444
+ <album>
445
+ <artist_name>Mos Def</artist_name>
446
+ <title>Black on Both Sides</title>
447
+ </album>
448
+ )
449
+ File.stub!(:read).and_return xml
450
+ subclazz.attributes_from_xml_path("/some_path/album.xml").should == {
451
+ :artist_name => "Mos Def",
452
+ :title => "Black on Both Sides",
453
+ :xml_path => "/some_path/album.xml"
454
+ }
455
+ end
456
+ end
457
+
458
+ describe "defining a submapper" do
459
+ before(:each) do
460
+ @clazz.many("tracks/track" => :tracks) do
461
+ text :title
462
+ integer :track_number
463
+ end
464
+ end
465
+
466
+ it "sets the mapping type to many" do
467
+ @clazz.mapper.mappings.first[:type].should == :many
468
+ end
469
+
470
+ it "sets the mapping key to track" do
471
+ @clazz.mapper.mappings.first[:key].should == :tracks
472
+ end
473
+
474
+ it "sets the mapping xpath to tracks/track" do
475
+ @clazz.mapper.mappings.first[:xpath].should == "tracks/track"
476
+ end
477
+
478
+ it "sets the correct submapper" do
479
+ @clazz.mapper.mappings.first[:options][:mapper].mappings.should == [
480
+ { :type => :text, :key => :title, :xpath => "title", :options => {} },
481
+ { :type => :integer, :key => :track_number, :xpath => "track_number", :options => {} },
482
+ ]
483
+ end
484
+
485
+ it "attributes_from_xml returns the correct attributes" do
486
+ @clazz.text(:artist_name)
487
+ @clazz.text(:title)
488
+ xml = %(
489
+ <album>
490
+ <artist_name>Mos Def</artist_name>
491
+ <title>Black on Both Sides</title>
492
+ <tracks>
493
+ <track>
494
+ <title>Track 1</title>
495
+ <track_number>1</track_number>
496
+ </track>
497
+ <track>
498
+ <title>Track 2</title>
499
+ <track_number>2</track_number>
500
+ </track>
501
+ </tracks>
502
+ </album>
503
+ )
504
+ @clazz.attributes_from_xml(xml).should == {
505
+ :artist_name => "Mos Def", :title => "Black on Both Sides",
506
+ :tracks => [
507
+ { :title => "Track 1", :track_number => 1 },
508
+ { :title => "Track 2", :track_number => 2 }
509
+ ]
510
+ }
511
+ end
512
+ end
513
+
514
+ end
515
+ end
@@ -0,0 +1,90 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{xml_mapper}
8
+ s.version = "0.3.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Tobias Schwab"]
12
+ s.date = %q{2010-11-26}
13
+ s.description = %q{Just check out the examples}
14
+ s.email = %q{tobias.schwab@dynport.de}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ ".rvmrc",
23
+ "Gemfile",
24
+ "Gemfile.lock",
25
+ "LICENSE.txt",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "autotest/discover.rb",
30
+ "features/step_definitions/xml_mapper_steps.rb",
31
+ "features/support/env.rb",
32
+ "features/xml_mapper.feature",
33
+ "lib/xml_mapper.rb",
34
+ "spec/example_spec.rb",
35
+ "spec/fixtures/base.xml",
36
+ "spec/my_mapper.rb",
37
+ "spec/spec_helper.rb",
38
+ "spec/xml_mapper_spec.rb",
39
+ "xml_mapper.gemspec"
40
+ ]
41
+ s.homepage = %q{http://github.com/tobstarr/xml_mapper}
42
+ s.licenses = ["MIT"]
43
+ s.require_paths = ["lib"]
44
+ s.rubygems_version = %q{1.3.7}
45
+ s.summary = %q{Declarative and clever XML to Ruby Mapping}
46
+ s.test_files = [
47
+ "spec/example_spec.rb",
48
+ "spec/my_mapper.rb",
49
+ "spec/spec_helper.rb",
50
+ "spec/xml_mapper_spec.rb"
51
+ ]
52
+
53
+ if s.respond_to? :specification_version then
54
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
55
+ s.specification_version = 3
56
+
57
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
58
+ s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
59
+ s.add_development_dependency(%q<autotest>, [">= 0"])
60
+ s.add_development_dependency(%q<autotest-growl>, [">= 0"])
61
+ s.add_development_dependency(%q<rspec>, ["~> 2.1.0"])
62
+ s.add_development_dependency(%q<ruby-debug>, [">= 0"])
63
+ s.add_development_dependency(%q<cucumber>, [">= 0"])
64
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
65
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
66
+ s.add_development_dependency(%q<rcov>, [">= 0"])
67
+ else
68
+ s.add_dependency(%q<nokogiri>, [">= 0"])
69
+ s.add_dependency(%q<autotest>, [">= 0"])
70
+ s.add_dependency(%q<autotest-growl>, [">= 0"])
71
+ s.add_dependency(%q<rspec>, ["~> 2.1.0"])
72
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
73
+ s.add_dependency(%q<cucumber>, [">= 0"])
74
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
75
+ s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
76
+ s.add_dependency(%q<rcov>, [">= 0"])
77
+ end
78
+ else
79
+ s.add_dependency(%q<nokogiri>, [">= 0"])
80
+ s.add_dependency(%q<autotest>, [">= 0"])
81
+ s.add_dependency(%q<autotest-growl>, [">= 0"])
82
+ s.add_dependency(%q<rspec>, ["~> 2.1.0"])
83
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
84
+ s.add_dependency(%q<cucumber>, [">= 0"])
85
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
86
+ s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
87
+ s.add_dependency(%q<rcov>, [">= 0"])
88
+ end
89
+ end
90
+