1
/* Copyright 2002-2005 Elliotte Rusty Harold
3
This library is free software; you can redistribute it and/or modify
4
it under the terms of version 2.1 of the GNU Lesser General Public
5
License as published by the Free Software Foundation.
7
This library is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU Lesser General Public License for more details.
12
You should have received a copy of the GNU Lesser General Public
13
License along with this library; if not, write to the
14
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
15
Boston, MA 02111-1307 USA
17
You can contact Elliotte Rusty Harold by sending e-mail to
18
elharo@metalab.unc.edu. Please include the word "XOM" in the
19
subject line. The XOM home page is located at http://www.xom.nu/
25
import java.io.IOException;
27
import nu.xom.Attribute;
28
import nu.xom.Builder;
29
import nu.xom.Document;
30
import nu.xom.Element;
31
import nu.xom.IllegalDataException;
32
import nu.xom.IllegalNameException;
33
import nu.xom.MalformedURIException;
34
import nu.xom.NamespaceConflictException;
35
import nu.xom.ParsingException;
39
* Basic tests for the <code>Attribute</code> class.
42
* @author Elliotte Rusty Harold
46
public class AttributeTest extends XOMTestCase {
48
public AttributeTest(String name) {
57
protected void setUp() {
58
a1 = new Attribute("test", "value");
59
a2 = new Attribute("test", " value ");
63
public void testGetChildCount() {
64
assertEquals(0, a1.getChildCount());
68
public void testGetChild() {
71
fail("Didn't throw IndexOutofBoundsException");
73
catch (IndexOutOfBoundsException success) {
79
public void testConstructor() {
80
assertEquals("test", a1.getLocalName());
81
assertEquals("test", a1.getQualifiedName());
82
assertEquals("", a1.getNamespacePrefix());
83
assertEquals("", a1.getNamespaceURI());
84
assertEquals("value", a1.getValue());
85
assertEquals(" value ", a2.getValue());
89
public void testConstructor2() {
91
Attribute a1 = new Attribute("name", "value", Attribute.Type.CDATA);
92
assertEquals("name", a1.getLocalName());
93
assertEquals("name", a1.getQualifiedName());
94
assertEquals("", a1.getNamespacePrefix());
95
assertEquals("", a1.getNamespaceURI());
96
assertEquals("value", a1.getValue());
97
assertEquals(Attribute.Type.CDATA, a1.getType());
101
public void testGetExternalForm() {
103
Attribute a1 = new Attribute("test", "value contains a \"");
104
assertEquals("test=\"value contains a "\"", a1.toXML());
106
Attribute a2 = new Attribute("test", "value contains a '");
107
assertEquals("test=\"value contains a '\"", a2.toXML());
112
public void testSetLocalName() {
114
Attribute a = new Attribute("name", "value");
115
a.setLocalName("newname");
116
assertEquals("newname", a.getLocalName());
119
a.setLocalName("pre:a");
120
fail("Allowed local attribute name containing colon");
122
catch (IllegalNameException success) {
123
assertNotNull(success.getMessage());
129
public void testSetLocalNameInNamespaceQualifiedAttribute() {
131
Attribute a = new Attribute("pre:name", "http://www.example.org", "value");
132
a.setLocalName("newname");
133
assertEquals("newname", a.getLocalName());
134
assertEquals("pre:newname", a.getQualifiedName());
139
// No xmlns attributes or xmlns:prefix attributes are allowed
140
public void testXmlns() {
143
new Attribute("xmlns", "http://www.w3.org/TR");
144
fail("Created attribute with name xmlns");
146
catch (IllegalNameException success) {
147
assertNotNull(success.getMessage());
151
new Attribute("xmlns:prefix", "http://www.w3.org/TR");
152
fail("Created attribute with name xmlns:prefix");
154
catch (IllegalNameException success) {
155
assertNotNull(success.getMessage());
158
// Now try with namespace URI from errata
160
new Attribute("xmlns", "http://www.w3.org/2000/xmlns/", "http://www.w3.org/");
161
fail("created xmlns attribute");
163
catch (IllegalNameException success) {
164
assertNotNull(success.getMessage());
167
// Now try with namespace URI from errata
169
new Attribute("xmlns:pre", "http://www.w3.org/2000/xmlns/", "http://www.w3.org/");
170
fail("created xmlns:pre attribute");
172
catch (IllegalNameException success) {
173
assertNotNull(success.getMessage());
179
/* public void testInternLocalNameAndPrefix() {
181
Attribute a1 = new Attribute("a1:b", "http://www.exmaple.com", "test");
182
Attribute a2 = new Attribute("a2:b", "http://www.exmaple.com", "test");
183
Attribute a3 = new Attribute("a1:c", "http://www.exmaple.com", "test");
185
assertTrue(a1.getNamespacePrefix() == a3.getNamespacePrefix());
186
assertTrue(a1.getLocalName() == a2.getLocalName());
191
public void testXMLBase() {
193
String xmlNamespace = "http://www.w3.org/XML/1998/namespace";
194
Attribute a1 = new Attribute("xml:base", xmlNamespace, "http://www.w3.org/");
195
assertEquals( "base", a1.getLocalName());
196
assertEquals("xml:base", a1.getQualifiedName());
197
assertEquals(xmlNamespace, a1.getNamespaceURI());
199
a1.setValue("http://www.example.com/>");
200
assertEquals("http://www.example.com/>", a1.getValue());
202
a1.setValue("http://www.example.com/<");
203
assertEquals("http://www.example.com/<", a1.getValue());
205
a1.setValue("http://www.example.com/\u00FE");
206
assertEquals(a1.getValue(), "http://www.example.com/\u00FE");
211
public void testXmlPrefix() {
214
new Attribute("xml:base", "http://www.w3.org/TR");
215
fail("Created attribute with name xml:base");
217
catch (NamespaceConflictException success) {
218
assertNotNull(success.getMessage());
222
new Attribute("xml:space", "preserve");
223
fail("Created attribute with local name xml:space");
225
catch (NamespaceConflictException success) {
226
assertNotNull(success.getMessage());
230
new Attribute("xml:lang", "fr-FR");
231
fail("Created attribute with name xml:lang");
233
catch (NamespaceConflictException success) {
234
assertNotNull(success.getMessage());
237
String xmlNamespace = "http://www.w3.org/XML/1998/namespace";
238
Attribute a1 = new Attribute(
239
"xml:base", xmlNamespace, "http://www.w3.org/");
240
assertEquals("base", a1.getLocalName());
241
assertEquals("xml:base", a1.getQualifiedName());
242
assertEquals(xmlNamespace, a1.getNamespaceURI());
244
Attribute a2 = new Attribute("xml:space", xmlNamespace, "preserve");
245
assertEquals(a2.getLocalName(), "space");
246
assertEquals("xml:space", a2.getQualifiedName());
247
assertEquals(xmlNamespace, a2.getNamespaceURI());
250
= new Attribute("xml:lang", xmlNamespace, "en-UK");
251
assertEquals("lang", a3.getLocalName());
252
assertEquals("xml:lang", a3.getQualifiedName());
253
assertEquals(xmlNamespace, a3.getNamespaceURI());
256
new Attribute("xml:base", "http://www.notTheXMLNamespace",
257
"http://www.w3.org/");
258
fail("remapped xml prefix");
260
catch (NamespaceConflictException success) {
261
assertNotNull(success.getMessage());
267
public void testXMLLangAttributeCanBeEmpty() {
269
String xmlNamespace = "http://www.w3.org/XML/1998/namespace";
270
Attribute a = new Attribute("xml:lang", xmlNamespace, "");
271
assertEquals("", a.getValue());
276
public void testWrongPrefixNotAllowedWithXMLURI() {
279
new Attribute("test:base", "http://www.w3.org/XML/1998/namespace", "value");
280
fail("Allowed XML namespace to be associated with non-xml prefix");
282
catch (NamespaceConflictException success) {
283
assertNotNull(success.getMessage());
289
public void testToString() {
291
"[nu.xom.Attribute: test=\"value\"]", a1.toString());
293
"[nu.xom.Attribute: test=\" value \"]", a2.toString());
297
public void testToStringWithLineFeed() {
299
Attribute a = new Attribute("name", "content\ncontent");
300
assertEquals("[nu.xom.Attribute: name=\"content\\ncontent\"]", a.toString());
305
public void testToStringWithCarriageReturnLineFeed() {
307
Attribute a = new Attribute("name", "content\r\ncontent");
308
assertEquals("[nu.xom.Attribute: name=\"content\\r\\ncontent\"]", a.toString());
313
public void testToStringWithCarriageReturn() {
315
Attribute a = new Attribute("name", "content\rcontent");
316
assertEquals("[nu.xom.Attribute: name=\"content\\rcontent\"]", a.toString());
321
public void testToStringWithLotsOfData() {
323
Attribute a = new Attribute("name",
324
"012345678901234567890123456789012345678901234567890123456789");
325
String s = a.toString();
327
"[nu.xom.Attribute: name=\"01234567890123456789012345678901234...\"]",
333
public void testToXML() {
334
assertEquals("test=\"value\"", a1.toXML());
335
assertEquals("test=\" value \"", a2.toXML());
339
public void testEscapingWithToXML() {
342
assertEquals("test=\"<\"", a1.toXML());
344
assertEquals("test=\">\"", a1.toXML());
346
assertEquals("test=\""\"", a1.toXML());
348
assertEquals("test=\"'\"", a1.toXML());
350
assertEquals("test=\"&\"", a1.toXML());
355
public void testWhiteSpaceEscapingWithToXML() {
358
assertEquals("test=\" \"", a1.toXML());
360
assertEquals("test=\"
\"", a1.toXML());
362
assertEquals("test=\"
\"", a1.toXML());
364
assertEquals("test=\"	\"", a1.toXML());
369
public void testSetValue() {
374
" spaces on both ends ",
375
" quotes \" \" quotes",
376
" single \'\' quotes",
377
" both double and single \"\'\"\' quotes",
378
" angle brackets < > <<<",
379
" carriage returns \r\r\r",
380
" ampersands & &&& &name; "
383
// Things that shouldn't cause an exception
384
for (int i = 0; i < legal.length; i++) {
385
a1.setValue(legal[i]);
386
assertEquals(legal[i], a1.getValue());
390
a1.setValue("test \u0000 test ");
391
fail("Should raise an IllegalDataException");
393
catch (IllegalDataException ex) {
395
assertNotNull(ex.getMessage());
401
public void testNames() {
403
String prefix = "testPrefix";
404
String name = "testName";
405
String URI = "http://www.elharo.com/";
406
String value = " here's some data";
409
Attribute a1 = new Attribute(prefix + ":" + name, URI, value);
410
assertEquals(name, a1.getLocalName());
411
assertEquals(prefix + ":" + name, a1.getQualifiedName());
412
assertEquals(URI, a1.getNamespaceURI());
416
public void testEquals() {
417
Attribute c1 = new Attribute("test", "limit");
418
Attribute c2 = new Attribute("test", "limit");
419
Attribute c3 = new Attribute("retina", "retina test");
421
assertEquals(c1, c1);
422
assertEquals(c1.hashCode(), c1.hashCode());
423
assertTrue(!c1.equals(c2));
424
assertTrue(!c1.equals(c3));
425
assertTrue(!c1.equals(null));
426
assertFalse(c1.equals("limit"));
427
assertFalse(c1.equals(new Element("test")));
431
public void testTypeEquals() {
432
assertEquals(Attribute.Type.CDATA, Attribute.Type.CDATA);
433
assertTrue(!Attribute.Type.CDATA.equals(Attribute.Type.NMTOKEN));
434
assertTrue(!Attribute.Type.CDATA.equals(null));
435
assertFalse(Attribute.Type.CDATA.equals("CDATA"));
436
assertFalse(Attribute.Type.CDATA.equals(new Element("CDATA")));
440
public void testCopyConstructor() {
441
Attribute c1 = new Attribute("test", "data");
442
Attribute c2 = new Attribute(c1);
444
assertEquals(c1.getValue(), c2.getValue());
445
assertEquals(c1.getLocalName(), c2.getLocalName());
446
assertEquals(c1.getQualifiedName(), c2.getQualifiedName());
447
assertEquals(c1.getValue(), c2.getValue());
448
assertTrue(!c1.equals(c2));
449
assertNull(c2.getParent());
454
// Check passing in a string with broken surrogate pairs
455
// and with correct surrogate pairs
456
public void testSurrogates() {
458
String goodString = "test: \uD8F5\uDF80 ";
459
Attribute c = new Attribute("surrogate", goodString);
460
assertEquals(goodString, c.getValue());
464
new Attribute("surrogate", "test: \uD8F5\uDBF0 ");
465
fail("Should raise an IllegalDataException");
467
catch (IllegalDataException success) {
468
assertEquals("test: \uD8F5\uDBF0 ", success.getData());
469
assertNotNull(success.getMessage());
474
new Attribute("surrogate", "test: \uD8F5\uD8F5 ");
475
fail("Should raise an IllegalDataException");
477
catch (IllegalDataException success) {
478
assertEquals("test: \uD8F5\uD8F5 ", success.getData());
479
assertNotNull(success.getMessage());
484
new Attribute("surrogate", "test: \uD8F5 ");
485
fail("Should raise an IllegalDataException");
487
catch (IllegalDataException success) {
488
assertEquals("test: \uD8F5 ", success.getData());
489
assertNotNull(success.getMessage());
494
new Attribute("surrogate", "test: \uDF80 ");
495
fail("One low half");
497
catch (IllegalDataException success) {
498
assertEquals("test: \uDF80 ", success.getData());
499
assertNotNull(success.getMessage());
502
// Low half before high half
504
new Attribute("surrogate", "test: \uDCF5\uD8F5 ");
505
fail("Low half before high half");
507
catch (IllegalDataException success) {
508
assertEquals("test: \uDCF5\uD8F5 ", success.getData());
509
assertNotNull(success.getMessage());
516
public void testNullNamespace() {
517
Attribute a = new Attribute("red:prefix",
518
"http://www.example.com", "data");
519
a.setNamespace(null, null);
520
assertEquals("", a.getNamespaceURI());
521
assertEquals("", a.getNamespacePrefix());
525
public void testChangeNamespaceToSameNamespaceAsElement() {
526
Attribute a = new Attribute("red:prefix",
527
"http://www.example.com", "data");
528
Element e = new Element("pre:test", "http://www.example.org/");
530
a.setNamespace("pre", "http://www.example.org/");
531
assertEquals("http://www.example.org/", a.getNamespaceURI());
532
assertEquals("pre", a.getNamespacePrefix());
533
assertEquals("http://www.example.org/", e.getNamespaceURI());
534
assertEquals("pre", e.getNamespacePrefix());
538
public void testSetNamespaceURI() {
540
String name = "red:sakjdhjhd";
541
String uri = "http://www.red.com/";
542
String prefix = "red";
543
Attribute a = new Attribute(name, uri, "");
545
assertEquals(uri, a.getNamespaceURI());
547
String[] legal = {"http://www.is.edu/sakdsk#sjadh",
548
"http://www.is.edu/sakdsk?name=value&name=head",
549
"uri:isbn:0832473864",
550
"http://www.examples.com:80",
551
"http://www.examples.com:80/",
552
"http://www.is.edu/%20sakdsk#sjadh"};
555
"http://www.is.edu/%sakdsk#sjadh",
556
"http://www.is.edu/k\u0245kakdsk#sjadh",
563
for (int i = 0; i < legal.length; i++) {
564
a.setNamespace(prefix, legal[i]);
565
assertEquals(legal[i], a.getNamespaceURI());
568
for (int i = 0; i < illegal.length; i++) {
570
a.setNamespace(prefix, illegal[i]);
571
fail("Illegal namespace URI allowed");
573
catch (MalformedURIException success) {
574
assertEquals(illegal[i], success.getData());
576
catch (IllegalNameException success) {
577
assertNotNull(success.getMessage());
584
public void testSetNamespace() {
586
Attribute a = new Attribute("name", "value");
588
a.setNamespace("pre", "");
589
fail("Allowed prefix with empty URI");
591
catch (NamespaceConflictException success) {
592
assertNotNull(success.getMessage());
596
a.setNamespace("", "http://www.example.com");
597
fail("Allowed empty prefix with non-empty URI");
599
catch (NamespaceConflictException success) {
600
assertNotNull(success.getMessage());
606
public void testNodeProperties() {
608
Attribute a1 = new Attribute("test", "data");
610
assertNull(a1.getParent());
612
Element element = new Element("test");
613
element.addAttribute(a1);
614
assertEquals(element, a1.getParent());
615
assertEquals(a1, element.getAttribute("test"));
617
element.removeAttribute(a1);
618
assertNull(element.getAttribute("test"));
623
public void testDistinctTypes() {
625
assertTrue(!(Attribute.Type.CDATA.equals(Attribute.Type.UNDECLARED)));
627
assertTrue(!(Attribute.Type.ID.equals(Attribute.Type.CDATA)));
628
assertTrue(!(Attribute.Type.IDREF.equals(Attribute.Type.ID)));
629
assertTrue(!(Attribute.Type.IDREFS.equals(Attribute.Type.IDREF)));
630
assertTrue(!(Attribute.Type.NMTOKEN.equals(Attribute.Type.IDREFS)));
631
assertTrue(!(Attribute.Type.NMTOKENS.equals(Attribute.Type.NMTOKEN)));
632
assertTrue(!(Attribute.Type.NOTATION.equals(Attribute.Type.NMTOKENS)));
633
assertTrue(!(Attribute.Type.ENTITY.equals(Attribute.Type.NOTATION)));
634
assertTrue(!(Attribute.Type.ENTITIES.equals(Attribute.Type.ENTITY)));
635
assertTrue(!(Attribute.Type.ENUMERATION.equals(Attribute.Type.ENTITIES)));
636
assertTrue(!(Attribute.Type.CDATA.equals(Attribute.Type.ENUMERATION)));
640
public void testAdditionConstraints() {
642
Element element = new Element("test");
643
Attribute a1 = new Attribute(
644
"foo:data", "http://www.example.com", "valueFoo");
645
Attribute a2 = new Attribute(
646
"bar:data", "http://www.example.com", "valueBar");
647
Attribute a3 = new Attribute("data", "valueFoo");
648
Attribute a4 = new Attribute("data", "valueBar");
650
element.addAttribute(a1);
651
assertEquals("valueFoo",
652
element.getAttributeValue("data", "http://www.example.com"));
653
assertEquals(1, element.getAttributeCount());
654
element.addAttribute(a2);
656
element.getAttributeValue("data", "http://www.example.com"),
659
assertEquals(1, element.getAttributeCount());
660
element.addAttribute(a3);
661
assertEquals(element.getAttributeValue("data"), "valueFoo");
662
assertEquals("valueBar",
663
element.getAttributeValue("data", "http://www.example.com"));
664
assertEquals(2, element.getAttributeCount());
665
element.addAttribute(a4);
666
assertEquals("valueBar", element.getAttributeValue("data"));
667
assertEquals(2, element.getAttributeCount());
669
// an attribute can have two attributes in the same namespace
670
// with different prefixes
671
Attribute a5 = new Attribute(
672
"red:ab", "http://www.example.org", "valueRed");
673
Attribute a6 = new Attribute(
674
"green:cd", "http://www.example.org", "valueGreen");
675
element.addAttribute(a5);
676
element.addAttribute(a6);
677
assertEquals("valueRed",
678
element.getAttributeValue("ab", "http://www.example.org"));
679
assertEquals("valueGreen",
680
element.getAttributeValue("cd", "http://www.example.org"));
685
public void testXMLLangCanBeEmptyString() {
686
// per section 2.12 of the XML Rec
688
Attribute a = new Attribute("xml:lang", "http://www.w3.org/XML/1998/namespace", "");
689
assertEquals("", a.getValue());
694
public void testPunctuationCharactersInToXML() {
696
String data = "=,.!@#$%^*()_-'[]{}+/?;:`|\\";
697
Attribute a = new Attribute("a", data);
698
assertEquals("a=\"" + data + "\"", a.toXML());
702
// Test for a bug that was caught by other tests; but not
703
// sufficiently isolated by them
704
public void testPrefixedAttributeBug() throws ParsingException, IOException {
706
Builder builder = new Builder();
707
File f = new File("data");
708
f = new File(f, "xtest.xml");
709
Document input = builder.build(f);
710
String s = input.toXML();
711
Document output = builder.build(s, f.toURL().toExternalForm());
712
assertEquals(input, output);
b'\\ No newline at end of file'