root/test/test_contrib.rb

Revision 549:e07d72733cae, 17.2 kB (checked in by Sean Russell <ser@…>, 7 months ago)

Moved and renamed files to conform to Ruby's test suite.

Line 
1# coding: binary
2require "test/unit/testcase"
3
4require "rexml/document"
5require "rexml/parseexception"
6require "rexml/formatters/default"
7
8class ContribTester < Test::Unit::TestCase
9        include REXML
10
11XML_STRING_01 = <<DELIMITER
12<?xml version="1.0" encoding="UTF-8"?>
13<biblio>
14  <entry type="Book">
15    <author>Thomas, David; Hunt, Andrew</author>
16    <language>english</language>
17    <publisher>Addison-Wesley</publisher>
18    <title>Programming Ruby. The Pragmatic Programmer's Guide</title>
19    <year>2000</year>
20  </entry>
21  <entry type="Book">
22    <author>Blammo, Blah</author>
23    <language>english</language>
24    <publisher>Hubbabubba</publisher>
25    <title>Foozboozer's Life</title>
26    <type>Book</type>
27    <year>2002</year>
28  </entry>
29</biblio>
30DELIMITER
31
32XML_STRING_02 = <<DELIMITER
33<biblio>
34  <entry type="Book">
35    <language>english</language>
36    <publisher>Addison-Wesley</publisher>
37    <title>Programming Ruby. The Pragmatic Programmer's Guide</title>
38    <type>Book</type>
39    <year>2000</year>
40  </entry>
41  <entry type="Book">
42    <author>Blammo, Blah</author>
43    <language>english</language>
44    <publisher>Hubbabubba</publisher>
45    <title>Foozboozer's Life</title>
46    <type>Book</type>
47    <year>2002</year>
48  </entry>
49</biblio>
50DELIMITER
51
52        # Tobias Reif <tobiasreif@pinkjuice.com>
53        def test_bad_doctype_Tobias
54                source = <<-EOF
55                 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
56                                "http://www.w3.org/TR/SVG/DTD/svg10.dtd"
57                         [
58                         <!-- <!ENTITY % fast-slow "0 0  .5 1">-->
59                         <!--<!ENTITY % slow-fast ".5 0  1 1">-->
60                         <!ENTITY hover_ani
61                                '<animateTransform attributeName="transform"
62                                 type="scale" restart="whenNotActive" values="1;0.96"
63                                 dur="0.5s" calcMode="spline" keySplines="0 0  .5 1"
64                                 fill="freeze" begin="mouseover"/>
65                                 <animateTransform  attributeName="transform"
66                                 type="scale" restart="whenNotActive" values="0.96;1"
67                                 dur="0.5s" calcMode="spline" keySplines=".5 0  1 1"
68                                 fill="freeze" begin="mouseover+0.5s"/>'
69                         >
70                         ]
71                 >
72                EOF
73                doc = REXML::Document.new source
74                doc.write(out="")
75                assert(out[/>'>/] != nil, "Couldn't find >'>")
76                assert(out[/\]>/] != nil, "Couldn't find ]>")
77        end
78
79        # Peter Verhage
80        def test_namespace_Peter
81                source = <<-EOF
82                <?xml version="1.0"?>
83                <config:myprog-config xmlns:config="http://someurl/program/version">
84                <!-- main options -->
85                        <config:main>
86                                <config:parameter name="name"  value="value"/>
87                        </config:main>
88                </config:myprog-config>
89                EOF
90                doc = REXML::Document.new source
91                assert_equal "myprog-config", doc.root.name
92                count = 0
93                REXML::XPath.each(doc, "x:myprog-config/x:main/x:parameter",
94                        {"x"=>"http://someurl/program/version"}) { |element|
95                                assert_equal "name", element.attributes["name"]
96                        count += 1;
97                }
98                assert_equal 1, count
99                assert_equal "myprog-config", doc.elements["config:myprog-config"].name
100        end
101
102        # Tobias Reif <tobiasreif@pinkjuice.com>
103        def test_complex_xpath_Tobias
104                source = <<-EOF
105                <root>
106                        <foo>
107                                <bar style="baz"/>
108                                <blah style="baz"/>
109                                <blam style="baz"/>
110                        </foo>
111                        <wax>
112                                <fudge>
113                                        <noodle/>
114                                </fudge>
115                        </wax>
116                </root>
117                EOF
118                # elements that have child elements
119                #  but not grandchildren
120                #  and not children that don't have a style attribute
121                #  and not children that have a unique style attribute
122                complex_path = "*[* "+
123                        "and not(*/node()) "+
124                        "and not(*[not(@style)]) "+
125                        "and not(*/@style != */@style)]"
126                doc = REXML::Document.new source
127                results = REXML::XPath.match( doc.root, complex_path )
128                assert(results)
129                assert_equal 1, results.size
130                assert_equal "foo", results[0].name
131        end
132
133        # "Chris Morris" <chrismo@charter.net>
134        def test_extra_newline_on_read_Chris
135                text = 'test text'
136                e = REXML::Element.new('Test')
137                e.add_text(text)
138    REXML::Formatters::Default.new.write(e,out="")
139
140                doc = REXML::Document.new(out)
141                outtext = doc.root.text
142
143                assert_equal(text, outtext)
144        end
145
146        # Tobias Reif <tobiasreif@pinkjuice.com>
147        def test_other_xpath_Tobias
148                schema = <<-DELIM
149                <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
150                        elementFormDefault="qualified">
151                        <xs:element name="rect">
152                                <xs:complexType>
153                                        <xs:attribute name="width" type="xs:byte" use="required"/>
154                                        <xs:attribute name="height" type="xs:byte" use="required"/>
155                                </xs:complexType>
156                        </xs:element>
157                        <xs:element name="svg">
158                                <xs:complexType>
159                                        <xs:sequence>
160                                                <xs:element ref="rect"/>
161                                        </xs:sequence>
162                                </xs:complexType>
163                        </xs:element>
164                </xs:schema>
165                DELIM
166
167                doc = REXML::Document.new schema
168
169                result = REXML::XPath.first(doc.root, 'xs:element[descendant::xs:element[@ref]]')
170                assert result
171                assert_equal "svg", result.attributes['name']
172                result = REXML::XPath.first(doc, 'element[descendant::element[@ref]]')
173                assert_nil result
174        end
175
176  #this first test succeeds, to check if stuff is set up correctly
177  def test_xpath_01_TobiasReif
178    doc = Document.new XML_STRING_01.dup
179    desired_result = Document.new '<author>Thomas, David; Hunt, Andrew</author>'
180    xpath = '//author'
181    result = XPath.first(doc, xpath)
182    assert_equal desired_result.to_s, result.to_s
183  end
184 
185  def test_xpath_whitespace_TobiasReif
186    # same as above, with whitespace in XPath
187    doc = Document.new(XML_STRING_01.dup)
188    desired_result = Document.new('<author>Thomas, David; Hunt, Andrew</author>')
189    xpath = "\/\/author\n \n"
190    result = XPath.first(doc, xpath)
191    failure_message = "\n[[[TR: AFAIK, whitespace should be allowed]]]\n"
192    assert_equal(desired_result.to_s, result.to_s, failure_message)
193  end
194 
195  def test_xpath_02_TobiasReif
196    doc = Document.new XML_STRING_01.dup
197    desired_result = Document.new '<author>Thomas, David; Hunt, Andrew</author>'
198    # Could that quirky
199    #  Programmer',&quot;'&quot;,'s
200    # be handled automatically, somehow?
201    # Or is there a simpler way? (the below XPath should match the author element above,
202    # AFAIK; I tested it inside an XSLT)
203    xpath = %q{/biblio/entry[
204    title/text()=concat('Programming Ruby. The Pragmatic Programmer',"'",'s Guide')
205    and
206    year='2000'
207    ]/author}
208    result = XPath.first(doc, xpath)
209    failure_message = "\nHow to handle the apos inside the string inside the XPath?\nXPath = #{xpath}\n"
210    assert_equal desired_result.to_s, result.to_s, failure_message
211  end
212 
213  def test_xpath_03_TobiasReif
214    doc = Document.new XML_STRING_02.dup
215    desired_result_string = "<entry type='Book'>
216    <language>english</language>
217    <publisher>Addison-Wesley</publisher>
218    <title>Programming Ruby. The Pragmatic Programmer's Guide</title>
219    <type>Book</type>
220    <year>2000</year>
221  </entry>"
222    desired_result_tree = Document.new desired_result_string
223    xpath = "/biblio/entry[not(author)]"
224    result = XPath.first(doc, xpath)
225    assert_equal desired_result_string, result.to_s
226  end
227
228  def test_umlaut
229                koln_iso = "K\xf6ln"
230                koln_utf = "K\xc3\xb6ln"
231    source_iso = "<?xml version='1.0' encoding='ISO-8859-1'?><test>#{koln_iso}</test>"
232    source_utf = "<?xml version='1.0' encoding='UTF-8'?><test>#{koln_utf}</test>"
233
234    if String.method_defined? :encode
235      koln_iso.force_encoding('iso-8859-1')
236      koln_utf.force_encoding('utf-8')
237      source_iso.force_encoding('iso-8859-1')
238      source_utf.force_encoding('utf-8')
239    end
240
241                doc = REXML::Document.new(source_iso)
242                assert_equal('ISO-8859-1', doc.xml_decl.encoding)
243                assert_equal(koln_utf, doc.root.text)
244                doc.write(out="")
245                assert_equal(source_iso, out )
246                doc.xml_decl.encoding = 'UTF-8'
247                doc.write(out="")
248                assert_equal(source_utf, out)
249
250                doc = Document.new <<-EOF
251<?xml version="1.0" encoding="ISO-8859-1"?>
252<intranet>
253<position><aktuell datum="01-10-11">Technik</aktuell></position>
254<hauptspalte>
255<headline>Technik</headline>
256Die Technik ist das Rückgrat der meisten Geschäftsprozesse bei Home of the Brave. Deshalb sollen hier alle relevanten technischen Abläufe, Daten und Einrichtungen beschrieben werden, damit jeder im Bedarfsfall die nötigen Informationen, Anweisungen und Verhaltensempfehlungen nachlesen und/oder abrufen kann.
257</hauptspalte>
258<nebenspalte>
259  <link ziel="Flash/">Flash</link><umbruch/>
260  Nützliches von Flashern für Flasher.<umbruch/>
261  <link neu="ja" ziel="Cvs/">CVS-FAQ</link><umbruch/>
262  FAQ zur Benutzung von CVS bei HOB
263</nebenspalte>
264</intranet>
265EOF
266                tn = XPath.first(doc, "//nebenspalte/text()[2]")
267                expected_iso = "Nützliches von Flashern für Flasher."
268                expected_utf = expected_iso.unpack('C*').pack('U*')
269                if expected_utf.respond_to? :encode
270                  expected_iso.force_encoding("iso-8859-1")
271                  expected_utf.force_encoding(Encoding::UTF_8)
272                end
273                assert_equal(expected_utf, tn.to_s.strip)
274    f = REXML::Formatters::Default.new
275    f.write( tn, Output.new(o = "", "ISO-8859-1") )
276                assert_equal(expected_iso, o.strip)
277
278                doc = Document.new File.new('test/data/xmlfile-bug.xml')
279                tn = XPath.first(doc, "//nebenspalte/text()[2]")
280                assert_equal(expected_utf, tn.to_s.strip)
281    f.write( tn, Output.new(o = "", "ISO-8859-1") )
282                assert_equal(expected_iso, o.strip)
283  end
284
285        def test_element_cloning_namespace_Chris
286                aDoc = REXML::Document.new '<h1 tpl:content="title" xmlns:tpl="1">Dummy title</h1>'
287
288                anElement = anElement = aDoc.elements[1]
289                elementAttrPrefix = anElement.attributes.get_attribute('content').prefix
290
291                aClone = anElement.clone
292                cloneAttrPrefix = aClone.attributes.get_attribute('content').prefix
293
294                assert_equal( elementAttrPrefix , cloneAttrPrefix )
295        end
296
297        def test_namespaces_in_attlist_tobias
298                in_string = File.open('test/data/foo.xml', 'r') do |file|
299                         file.read
300                end
301
302                doc = Document.new in_string
303
304                assert_nil XPath.first(doc,'//leg')
305                assert_equal 'http://www.foo.com/human', doc.root.elements[1].namespace
306                assert_equal 'human leg', 
307                        XPath.first(doc, '//x:leg/text()', {'x'=>'http://www.foo.com/human'}).to_s
308        end
309
310        #  Alun ap Rhisiart
311        def test_less_than_in_element_content
312                source = File.new('test/data/ProductionSupport.xml')
313                h = Hash.new
314                doc = REXML::Document.new source
315                doc.elements.each("//CommonError") { |el| 
316                        h[el.elements['Key'].text] = 'okay' 
317                }
318                assert(h.include?('MotorInsuranceContract(Object)>>#error:'))
319        end
320
321        # XPaths provided by Thomas Sawyer
322        def test_various_xpath
323                #@doc = REXML::Document.new('<r a="1"><p><c b="2"/></p></r>')
324                doc = REXML::Document.new('<r a="1"><p><c b="2">3</c></p></r>')
325
326                [['/r', REXML::Element],
327                 ['/r/p/c', REXML::Element],
328                 ['/r/attribute::a', Attribute],
329                 ['/r/@a', Attribute],
330                 ['/r/attribute::*', Attribute],
331                 ['/r/@*', Attribute],
332                 ['/r/p/c/attribute::b', Attribute],
333                 ['/r/p/c/@b', Attribute],
334                 ['/r/p/c/attribute::*', Attribute],
335                 ['/r/p/c/@*', Attribute],
336                 ['//c/attribute::b', Attribute],
337                 ['//c/@b', Attribute],
338                 ['//c/attribute::*', Attribute],
339                 ['//c/@*', Attribute],
340                 ['.//node()', REXML::Node ],
341                 ['.//node()[@a]', REXML::Element ],
342                 ['.//node()[@a="1"]', REXML::Element ],
343                 ['.//node()[@b]', REXML::Element ], # no show, why?
344                 ['.//node()[@b="2"]', REXML::Element ]
345                ].each do |xpath,kind|
346                        begin
347                                REXML::XPath.each( doc, xpath ) do |what|
348                                        assert_kind_of( kind, what, "\n\nWrong type (#{what.class}) returned for #{xpath} (expected #{kind.name})\n\n" )
349                                end
350                        rescue Exception
351                                puts "PATH WAS: #{xpath}"
352                                raise
353                        end
354                end
355
356                [
357                 ['/r', 'attribute::a', Attribute ],
358                 ['/r', '@a', Attribute ],
359                 ['/r', 'attribute::*', Attribute ],
360                 ['/r', '@*', Attribute ],
361                 ['/r/p/c', 'attribute::b', Attribute ],
362                 ['/r/p/c', '@b', Attribute ],
363                 ['/r/p/c', 'attribute::*', Attribute ],
364                 ['/r/p/c', '@*', Attribute ]
365                ].each do |nodepath, xpath, kind|
366                        begin
367                                context = REXML::XPath.first(doc, nodepath)
368                                REXML::XPath.each( context, xpath ) do |what|
369                                        assert_kind_of kind, what, "Wrong type (#{what.class}) returned for #{xpath} (expected #{kind.name})\n"
370                                end
371                        rescue Exception
372                                puts "PATH WAS: #{xpath}"
373                                raise
374                        end
375                end
376        end
377
378        def test_entities_Holden_Glova
379                document = <<-EOL
380                <?xml version="1.0" encoding="UTF-8"?>
381                <!DOCTYPE rubynet [
382                <!ENTITY rbconfig.MAJOR "1">
383                <!ENTITY rbconfig.MINOR "7">
384                <!ENTITY rbconfig.TEENY "2">
385                <!ENTITY rbconfig.ruby_version "&rbconfig.MAJOR;.&rbconfig.MINOR;">
386                <!ENTITY rbconfig.arch "i386-freebsd5">
387                <!ENTITY rbconfig.prefix "/usr/local">
388                <!ENTITY rbconfig.libdir "&rbconfig.prefix;/lib">
389                <!ENTITY rbconfig.includedir "&rbconfig.prefix;/include">
390                <!ENTITY rbconfig.sitedir "&rbconfig.prefix;/lib/ruby/site_ruby">
391                <!ENTITY rbconfig.sitelibdir "&rbconfig.sitedir;/&rbconfig.ruby_version;">
392                <!ENTITY rbconfig.sitearchdir "&rbconfig.sitelibdir;/&rbconfig.arch;">
393                ]>
394                <rubynet>
395                        <pkg version="version1.0">
396                                <files>
397                                        <file>
398                                                <filename>uga.rb</filename>
399                                                <mode>0444</mode>
400                                                <path>&rbconfig.libdir;/rexml</path>
401                                                <content encoding="xml">... the file here</content>
402                                        </file>
403                                        <file>
404                                                <filename>booga.h</filename>
405                                                <mode>0444</mode>
406                                                <path>&rbconfig.includedir;</path>
407                                                <content encoding="xml">... the file here</content>
408                                        </file>
409                                        <file>
410                                                <filename>foo.so</filename>
411                                                <mode>0555</mode>
412                                                <path>&rbconfig.sitearchdir;/rexml</path>
413                                                <content encoding="mime64">Li4uIHRoZSBmaWxlIGhlcmU=\n</content>
414                                        </file>
415                                </files>
416                        </pkg>
417                </rubynet>
418                EOL
419
420                file_xpath = '/rubynet/pkg/files/file'
421
422                root = REXML::Document.new(document)
423
424                root.elements.each(file_xpath) do |metadata|
425                        text = metadata.elements['path'].get_text.value
426                        assert text !~ /&rbconfig/, "'#{text}' failed"
427                end
428
429                #Error occurred in test_package_file_opens(TC_PackageInstall):
430                # ArgumentError:
431                #illegal access mode &rbconfig.prefix;/lib/rexml
432                #
433                #[synack@Evergreen] src $ ruby --version
434                #ruby 1.6.7 (2002-03-01) [i686-linux-gnu]
435                #
436                #It looks like it expanded the first entity, but didn't reparse it for more
437                #entities. possible bug - or have I mucked this up?
438        end
439
440        def test_whitespace_after_xml_decl
441                d = Document.new <<EOL
442<?xml version='1.0'?>
443  <blo>
444                <wak>
445                </wak>
446</blo>
447EOL
448        end
449
450        def test_external_entity
451                xp = '//channel/title'
452
453                %w{data/working.rss data/broken.rss}.each do |path|
454                        File.open(File.join( "test", path )) do |file|
455                                doc = REXML::Document.new file.readlines.join('')
456
457                                # check to make sure everything is kosher
458                                assert_equal( doc.root.class, REXML::Element )
459                                assert_equal( doc.root.elements.class, REXML::Elements )
460
461                                # get the title of the feed
462                                assert( doc.root.elements[xp].kind_of?( REXML::Element ) )
463                        end
464                end
465        end
466
467        def test_maintain_dtd 
468                src = %q{<?xml version="1.0" encoding="UTF-8"?>
469<!DOCTYPE ivattacks SYSTEM "../../ivacm.dtd" [
470<!ENTITY % extern-packages SYSTEM "../../ivpackages.dtd">
471<!ENTITY % extern-packages SYSTEM "../../common-declarations.dtd">
472%extern-packages;
473%extern-common;
474]>}
475                doc = Document.new( src )
476                doc.write( out="" )
477                src = src.tr('"', "'")
478                out = out.tr('"', "'")
479                assert_equal( src, out )
480        end
481
482        def test_text_nodes_nomatch
483                source = "<root><child>test</child></root>"
484                d = REXML::Document.new( source )
485                r = REXML::XPath.match( d, %q{/root/child[text()="no-test"]} )
486                assert_equal( 0, r.size )
487        end
488
489  def test_raw_Terje_Elde
490    f = REXML::Formatters::Default.new
491    txt = 'abc&#248;def'
492    a = Text.new( txt,false,nil,true )
493    f.write(a,out="")
494    assert_equal( txt, out )
495
496    txt = '<sean><russell>abc&#248;def</russell></sean>'
497    a = Document.new( txt, { :raw => ["russell"] } )
498    f.write(a,out="")
499    assert_equal( txt, out )
500  end
501
502  def test_indenting_error
503    a=Element.new("test1")
504    b=Element.new("test2")
505    c=Element.new("test3")
506    b << c
507    a << b
508
509    REXML::Formatters::Pretty.new.write(a,s="")
510  end
511
512  def test_pos
513    testfile = "/tmp/tidal#{$$}"
514    testdata = %Q{<calibration>
515<section name="parameters">
516<param name="barpress">760</param>
517<param name="hertz">50</param>
518</section>
519</calibration>
520}
521
522    File.open(testfile, 'w') do |f|
523        f.puts testdata
524    end
525    File.open(testfile) do |f|
526        d = REXML::Document.new(f)
527    end
528    #File.unlink(testfile)
529  end
530
531  def test_deep_clone
532    a = Document.new( '<?xml version="1.0"?><!DOCTYPE html PUBLIC
533    "-//W3C//DTD
534    XHTML 1.0 Transitional//EN"
535    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html
536    xmlns="http:///www.w3.org/1999/xhtml"></html>' )
537    b = a.deep_clone
538    assert_equal a.to_s, b.to_s
539  end
540
541  def test_double_escaping
542    data = '<title>AT&amp;T</title>'
543    xml = "<description><![CDATA[#{data}]]></description>"
544
545    doc = REXML::Document.new(xml)
546    description = doc.find {|e| e.name=="description"}
547    assert_equal data, description.text
548  end
549
550  def test_ticket_12
551    cfg = "<element><anotherelement><child1>a</child1><child2>b</child2></anotherelement></element>"
552
553    config = REXML::Document.new( cfg )
554
555    assert_equal( "a", config.elements[ "//child1" ].text )
556  end
557
558=begin
559 # This is a silly test, and is low priority
560 def test_namespace_serialization_tobi_reif
561         doc = Document.new '<doc xmlns:b="http://www.foo.foo">
562 <b:p/>
563</doc>'
564         ns = 'http://www.foo.foo'
565         ns_declaration={'f'=>ns}
566         returned = XPath.match(doc,'//f:p',ns_declaration)
567         # passes:
568         assert( (returned[0].namespace==ns), 'namespace should be '+ns)
569         serialized = returned.to_s
570         serialized_and_parsed = Document.new(serialized)
571         puts 'serialized: '+serialized
572                 # ... currently brings <b:p/>
573                 # prefix b is undeclared (!)
574         assert( (serialized_and_parsed.namespace==ns),
575                 'namespace should still be '+ns.inspect+
576                 ' and not '+serialized_and_parsed.namespace.inspect)
577         # ... currently results in a failure:
578         # 'namespace should still be "http://www.foo.foo" and not ""'
579 end
580=end
581end
Note: See TracBrowser for help on using the browser.