1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package tests.xml; 18 19 import dalvik.annotation.KnownFailure; 20 import junit.framework.TestCase; 21 import org.xml.sax.Attributes; 22 import org.xml.sax.ContentHandler; 23 import org.xml.sax.InputSource; 24 import org.xml.sax.XMLReader; 25 import org.xml.sax.helpers.DefaultHandler; 26 27 import javax.xml.parsers.SAXParser; 28 import javax.xml.parsers.SAXParserFactory; 29 import java.io.StringReader; 30 import java.util.Arrays; 31 import java.util.List; 32 33 /** 34 * Initiate and observe a SAX parse session. 35 */ 36 public class SaxTest extends TestCase { 37 38 public void testNoPrefixesNoNamespaces() throws Exception { 39 parse(false, false, "<foo bar=\"baz\"/>", new DefaultHandler() { 40 @Override public void startElement(String uri, String localName, 41 String qName, Attributes attributes) { 42 assertEquals("", uri); 43 assertEquals("", localName); 44 assertEquals("foo", qName); 45 assertEquals(1, attributes.getLength()); 46 assertEquals("", attributes.getURI(0)); 47 assertOneOf("bar", "", attributes.getLocalName(0)); 48 assertEquals("bar", attributes.getQName(0)); 49 } 50 }); 51 52 parse(false, false, "<a:foo a:bar=\"baz\"/>", new DefaultHandler() { 53 @Override public void startElement(String uri, String localName, 54 String qName, Attributes attributes) { 55 assertEquals("", uri); 56 assertEquals("", localName); 57 assertEquals("a:foo", qName); 58 assertEquals(1, attributes.getLength()); 59 assertEquals("", attributes.getURI(0)); 60 assertOneOf("a:bar", "", attributes.getLocalName(0)); 61 assertEquals("a:bar", attributes.getQName(0)); 62 } 63 }); 64 } 65 66 public void testNoPrefixesYesNamespaces() throws Exception { 67 parse(false, true, "<foo bar=\"baz\"/>", new DefaultHandler() { 68 @Override public void startElement(String uri, String localName, 69 String qName, Attributes attributes) { 70 assertEquals("", uri); 71 assertEquals("foo", localName); 72 assertEquals("foo", qName); 73 assertEquals(1, attributes.getLength()); 74 assertEquals("", attributes.getURI(0)); 75 assertEquals("bar", attributes.getLocalName(0)); 76 assertEquals("bar", attributes.getQName(0)); 77 } 78 }); 79 80 parse(false, true, "<a:foo a:bar=\"baz\" xmlns:a=\"http://quux\"/>", new DefaultHandler() { 81 @Override public void startElement(String uri, String localName, 82 String qName, Attributes attributes) { 83 assertEquals("http://quux", uri); 84 assertEquals("foo", localName); 85 assertEquals("a:foo", qName); 86 assertEquals(1, attributes.getLength()); 87 assertEquals("http://quux", attributes.getURI(0)); 88 assertEquals("bar", attributes.getLocalName(0)); 89 assertEquals("a:bar", attributes.getQName(0)); 90 } 91 }); 92 } 93 94 /** 95 * Android's Expat-based SAX parser fails this test because Expat doesn't 96 * supply us with our much desired {@code xmlns="http://..."} attributes. 97 */ 98 @KnownFailure("No xmlns attributes from Expat") 99 public void testYesPrefixesYesNamespaces() throws Exception { 100 parse(true, true, "<foo bar=\"baz\"/>", new DefaultHandler() { 101 @Override public void startElement(String uri, String localName, 102 String qName, Attributes attributes) { 103 assertEquals("", uri); 104 assertEquals("foo", localName); 105 assertEquals("foo", qName); 106 assertEquals(1, attributes.getLength()); 107 assertEquals("", attributes.getURI(0)); 108 assertEquals("bar", attributes.getLocalName(0)); 109 assertEquals("bar", attributes.getQName(0)); 110 } 111 }); 112 113 parse(true, true, "<a:foo a:bar=\"baz\" xmlns:a=\"http://quux\"/>", new DefaultHandler() { 114 @Override public void startElement(String uri, String localName, 115 String qName, Attributes attributes) { 116 assertEquals("http://quux", uri); 117 assertEquals("foo", localName); 118 assertEquals("a:foo", qName); 119 assertEquals(2, attributes.getLength()); 120 assertEquals("http://quux", attributes.getURI(0)); 121 assertEquals("bar", attributes.getLocalName(0)); 122 assertEquals("a:bar", attributes.getQName(0)); 123 assertEquals("", attributes.getURI(1)); 124 assertEquals("", attributes.getLocalName(1)); 125 assertEquals("xmlns:a", attributes.getQName(1)); 126 } 127 }); 128 } 129 130 public void testYesPrefixesNoNamespaces() throws Exception { 131 parse(true, false, "<foo bar=\"baz\"/>", new DefaultHandler() { 132 @Override public void startElement(String uri, String localName, 133 String qName, Attributes attributes) { 134 assertEquals("", uri); 135 assertEquals("", localName); 136 assertEquals("foo", qName); 137 assertEquals(1, attributes.getLength()); 138 assertEquals("", attributes.getURI(0)); 139 assertOneOf("bar", "", attributes.getLocalName(0)); 140 assertEquals("bar", attributes.getQName(0)); 141 } 142 }); 143 144 parse(true, false, "<a:foo a:bar=\"baz\"/>", new DefaultHandler() { 145 @Override public void startElement(String uri, String localName, 146 String qName, Attributes attributes) { 147 assertEquals("", uri); 148 assertEquals("", localName); 149 assertEquals("a:foo", qName); 150 assertEquals(1, attributes.getLength()); 151 assertEquals("", attributes.getURI(0)); 152 assertOneOf("a:bar", "", attributes.getLocalName(0)); 153 assertEquals("a:bar", attributes.getQName(0)); 154 } 155 }); 156 } 157 158 private void parse(boolean prefixes, boolean namespaces, String xml, 159 ContentHandler handler) throws Exception { 160 SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); 161 XMLReader reader = parser.getXMLReader(); 162 reader.setFeature("http://xml.org/sax/features/namespace-prefixes", prefixes); 163 reader.setFeature("http://xml.org/sax/features/namespaces", namespaces); 164 reader.setContentHandler(handler); 165 reader.parse(new InputSource(new StringReader(xml))); 166 } 167 168 /** 169 * @param expected an optional value that may or may have not been supplied 170 * @param sentinel a marker value that means the expected value was omitted 171 */ 172 private void assertOneOf(String expected, String sentinel, String actual) { 173 List<String> optionsList = Arrays.asList(sentinel, expected); 174 assertTrue("Expected one of " + optionsList + " but was " + actual, 175 optionsList.contains(actual)); 176 } 177 } 178