| package org.robolectric.android; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| import static com.google.common.truth.Truth.assertWithMessage; |
| import static com.google.common.truth.TruthJUnit.assume; |
| import static java.nio.charset.StandardCharsets.UTF_8; |
| import static java.util.Arrays.asList; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import android.app.Application; |
| import android.content.res.XmlResourceParser; |
| import androidx.test.core.app.ApplicationProvider; |
| import androidx.test.ext.junit.runners.AndroidJUnit4; |
| import java.io.ByteArrayInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.StringReader; |
| import java.nio.file.Paths; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.robolectric.R; |
| import org.robolectric.RuntimeEnvironment; |
| import org.w3c.dom.Document; |
| import org.xmlpull.v1.XmlPullParser; |
| import org.xmlpull.v1.XmlPullParserException; |
| |
| @RunWith(AndroidJUnit4.class) |
| public class XmlResourceParserImplTest { |
| |
| private static final String RES_AUTO_NS = "http://schemas.android.com/apk/res-auto"; |
| private XmlResourceParser parser; |
| private Application context; |
| |
| @Before |
| public void setUp() throws Exception { |
| context = ApplicationProvider.getApplicationContext(); |
| parser = context.getResources().getXml(R.xml.preferences); |
| } |
| |
| @After |
| public void tearDown() throws Exception { |
| parser.close(); |
| } |
| |
| private void parseUntilNext(int event) throws Exception { |
| while (parser.next() != event) { |
| if (parser.getEventType() == XmlResourceParser.END_DOCUMENT) { |
| throw new RuntimeException("Impossible to find: " + |
| event + ". End of document reached."); |
| } |
| } |
| } |
| |
| private void forgeAndOpenDocument(String xmlValue) { |
| try { |
| DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
| factory.setNamespaceAware(true); |
| factory.setIgnoringComments(true); |
| factory.setIgnoringElementContentWhitespace(true); |
| DocumentBuilder documentBuilder = factory.newDocumentBuilder(); |
| Document document = documentBuilder.parse( |
| new ByteArrayInputStream(xmlValue.getBytes(UTF_8))); |
| |
| parser = |
| new XmlResourceParserImpl( |
| document, Paths.get("file"), R.class.getPackage().getName(), "org.robolectric", null); |
| // Navigate to the root element |
| parseUntilNext(XmlResourceParser.START_TAG); |
| } catch (Exception parsingException) { |
| // Wrap XML parsing exception with a runtime |
| // exception for convenience. |
| throw new RuntimeException( |
| "Cannot forge a Document from an invalid XML", |
| parsingException); |
| } |
| } |
| |
| private int attributeIndexOutOfIndex() { |
| return parser.getAttributeCount() + 1; |
| } |
| |
| @Test |
| public void testGetXmlInt() throws Exception { |
| assertThat(parser).isNotNull(); |
| int evt = parser.next(); |
| assertThat(evt).isEqualTo(XmlResourceParser.START_DOCUMENT); |
| } |
| |
| @Test |
| public void testGetXmlString() { |
| assertThat(parser).isNotNull(); |
| } |
| |
| @Test |
| public void testSetFeature() throws Exception { |
| for (String feature : XmlResourceParserImpl.AVAILABLE_FEATURES) { |
| parser.setFeature(feature, true); |
| try { |
| parser.setFeature(feature, false); |
| fail(feature + " should be true."); |
| } catch (XmlPullParserException ex) { |
| // pass |
| } |
| } |
| |
| for (String feature : XmlResourceParserImpl.UNAVAILABLE_FEATURES) { |
| try { |
| parser.setFeature(feature, false); |
| fail(feature + " should not be true."); |
| } catch (XmlPullParserException ex) { |
| // pass |
| } |
| try { |
| parser.setFeature(feature, true); |
| fail(feature + " should not be true."); |
| } catch (XmlPullParserException ex) { |
| // pass |
| } |
| } |
| } |
| |
| @Test |
| public void testGetFeature() { |
| for (String feature : XmlResourceParserImpl.AVAILABLE_FEATURES) { |
| assertThat(parser.getFeature(feature)).isTrue(); |
| } |
| |
| for (String feature : XmlResourceParserImpl.UNAVAILABLE_FEATURES) { |
| assertThat(parser.getFeature(feature)).isFalse(); |
| } |
| |
| assertThat(parser.getFeature(null)).isFalse(); |
| } |
| |
| @Test |
| public void testSetProperty() { |
| try { |
| parser.setProperty("foo", "bar"); |
| fail("Properties should not be supported"); |
| } catch (XmlPullParserException ex) { |
| // pass |
| } |
| } |
| |
| @Test |
| public void testGetProperty() { |
| // Properties are not supported |
| assertThat(parser.getProperty("foo")).isNull(); |
| } |
| |
| @Test |
| public void testSetInput_Reader() { |
| try { |
| parser.setInput(new StringReader("")); |
| fail("This method should not be supported"); |
| } catch (XmlPullParserException ex) { |
| // pass |
| } |
| } |
| |
| @Test |
| public void testSetInput_InputStreamString() throws IOException { |
| try (InputStream inputStream = |
| getClass().getResourceAsStream("src/test/resources/res/xml/preferences.xml")) { |
| parser.setInput(inputStream, "UTF-8"); |
| fail("This method should not be supported"); |
| } catch (XmlPullParserException ex) { |
| // pass |
| } |
| } |
| |
| @Test |
| public void testDefineEntityReplacementText() { |
| try { |
| parser.defineEntityReplacementText("foo", "bar"); |
| fail("This method should not be supported"); |
| } catch (XmlPullParserException ex) { |
| // pass |
| } |
| } |
| |
| @Test |
| public void testGetNamespacePrefix() { |
| try { |
| parser.getNamespacePrefix(0); |
| fail("This method should not be supported"); |
| } catch (XmlPullParserException ex) { |
| // pass |
| } |
| } |
| |
| @Test |
| public void testGetInputEncoding() { |
| assertThat(parser.getInputEncoding()).isNull(); |
| } |
| |
| @Test |
| public void testGetNamespace_String() { |
| try { |
| parser.getNamespace("bar"); |
| fail("This method should not be supported"); |
| } catch (RuntimeException ex) { |
| // pass |
| } |
| } |
| |
| @Test |
| public void testGetNamespaceCount() { |
| try { |
| parser.getNamespaceCount(0); |
| fail("This method should not be supported"); |
| } catch (XmlPullParserException ex) { |
| // pass |
| } |
| } |
| |
| @Test |
| public void testGetNamespaceUri() { |
| try { |
| parser.getNamespaceUri(0); |
| fail("This method should not be supported"); |
| } catch (XmlPullParserException ex) { |
| // pass |
| } |
| } |
| |
| @Test |
| public void testGetColumnNumber() { |
| assertThat(parser.getColumnNumber()).isEqualTo(-1); |
| } |
| |
| @Test |
| public void testGetDepth() throws Exception { |
| // Recorded depths from preference file elements |
| List<Integer> expectedDepths = asList(1, 2, 3, 2, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 3); |
| List<Integer> actualDepths = new ArrayList<>(); |
| int evt; |
| while ((evt = parser.next()) != XmlResourceParser.END_DOCUMENT) { |
| switch (evt) { |
| case (XmlResourceParser.START_TAG): { |
| actualDepths.add(parser.getDepth()); |
| break; |
| } |
| } |
| |
| } |
| assertThat(actualDepths).isEqualTo(expectedDepths); |
| } |
| |
| @Test |
| public void testGetText() { |
| forgeAndOpenDocument("<foo/>"); |
| assertThat(parser.getText()).isEqualTo(""); |
| |
| forgeAndOpenDocument("<foo>bar</foo>"); |
| assertThat(parser.getText()).isEqualTo("bar"); |
| } |
| |
| @Test |
| public void testGetEventType() throws Exception { |
| int evt; |
| while ((evt = parser.next()) != XmlResourceParser.END_DOCUMENT) { |
| assertThat(parser.getEventType()).isEqualTo(evt); |
| } |
| } |
| |
| @Test |
| public void testIsWhitespace() throws Exception { |
| assume().that(RuntimeEnvironment.useLegacyResources()).isTrue(); |
| |
| XmlResourceParserImpl parserImpl = (XmlResourceParserImpl) parser; |
| assertThat(parserImpl.isWhitespace("bar")).isFalse(); |
| assertThat(parserImpl.isWhitespace(" ")).isTrue(); |
| } |
| |
| @Test |
| public void testGetPrefix() { |
| try { |
| parser.getPrefix(); |
| fail("This method should not be supported"); |
| } catch (RuntimeException ex) { |
| // pass |
| } |
| } |
| |
| @Test |
| public void testGetNamespace() { |
| forgeAndOpenDocument("<foo xmlns=\"http://www.w3.org/1999/xhtml\">bar</foo>"); |
| assertThat(parser.getNamespace()).isEqualTo("http://www.w3.org/1999/xhtml"); |
| } |
| |
| @Test |
| public void testGetName_atStart() throws Exception { |
| assertThat(parser.getName()).isEqualTo(null); |
| parseUntilNext(XmlResourceParser.START_DOCUMENT); |
| assertThat(parser.getName()).isEqualTo(null); |
| parseUntilNext(XmlResourceParser.START_TAG); |
| assertThat(parser.getName()).isEqualTo("PreferenceScreen"); |
| } |
| |
| @Test |
| public void testGetName() { |
| forgeAndOpenDocument("<foo/>"); |
| assertThat(parser.getName()).isEqualTo("foo"); |
| } |
| |
| @Test |
| public void testGetAttribute() { |
| forgeAndOpenDocument("<foo xmlns:app=\"http://schemas.android.com/apk/res-auto\"" |
| + " app:bar=\"bar\"/>"); |
| XmlResourceParserImpl parserImpl = (XmlResourceParserImpl) parser; |
| assertThat(parserImpl.getAttribute(RES_AUTO_NS, "bar")).isEqualTo("bar"); |
| } |
| |
| @Test |
| public void testGetAttributeNamespace() { |
| forgeAndOpenDocument("<foo xmlns:app=\"http://schemas.android.com/apk/res-auto\"" |
| + " app:bar=\"bar\"/>"); |
| assertThat(parser.getAttributeNamespace(0)).isEqualTo(RES_AUTO_NS); |
| } |
| |
| @Test |
| public void testGetAttributeName() { |
| try { |
| parser.getAttributeName(0); |
| fail("Expected exception"); |
| } catch (IndexOutOfBoundsException expected) { |
| // Expected |
| } |
| |
| forgeAndOpenDocument("<foo bar=\"bar\"/>"); |
| assertThat(parser.getAttributeName(0)).isEqualTo("bar"); |
| |
| try { |
| parser.getAttributeName(attributeIndexOutOfIndex()); |
| fail("Expected exception"); |
| } catch (IndexOutOfBoundsException expected) { |
| // Expected |
| } |
| } |
| |
| @Test |
| public void testGetAttributePrefix() throws Exception { |
| parseUntilNext(XmlResourceParser.START_TAG); |
| try { |
| parser.getAttributePrefix(0); |
| fail("This method should not be supported"); |
| } catch (RuntimeException ex) { |
| // pass |
| } |
| } |
| |
| @Test |
| public void testIsEmptyElementTag() throws Exception { |
| assertWithMessage("Before START_DOCUMENT should return false.") |
| .that(parser.isEmptyElementTag()) |
| .isEqualTo(false); |
| |
| forgeAndOpenDocument("<foo><bar/></foo>"); |
| assertWithMessage("Not empty tag should return false.") |
| .that(parser.isEmptyElementTag()) |
| .isEqualTo(false); |
| |
| forgeAndOpenDocument("<foo/>"); |
| assertWithMessage("In the Android implementation this method always return false.") |
| .that(parser.isEmptyElementTag()) |
| .isEqualTo(false); |
| } |
| |
| @Test |
| public void testGetAttributeCount() { |
| assertWithMessage("When no node is being explored the number of attributes should be -1.") |
| .that(parser.getAttributeCount()) |
| .isEqualTo(-1); |
| |
| forgeAndOpenDocument("<foo bar=\"bar\"/>"); |
| assertThat(parser.getAttributeCount()).isEqualTo(1); |
| } |
| |
| @Test |
| public void testGetAttributeValue_Int() { |
| forgeAndOpenDocument("<foo bar=\"bar\"/>"); |
| assertThat(parser.getAttributeValue(0)).isEqualTo("bar"); |
| |
| try { |
| parser.getAttributeValue(attributeIndexOutOfIndex()); |
| fail(); |
| } catch (IndexOutOfBoundsException ex) { |
| // pass |
| } |
| } |
| |
| @Test |
| public void testGetAttributeEscapedValue() { |
| forgeAndOpenDocument("<foo bar=\"\\'\"/>"); |
| assertThat(parser.getAttributeValue(0)).isEqualTo("\'"); |
| } |
| |
| @Test |
| public void testGetAttributeEntityValue() { |
| forgeAndOpenDocument("<foo bar=\"\\u201e\"\"/>"); |
| assertThat(parser.getAttributeValue(0)).isEqualTo("„\""); |
| } |
| |
| @Test |
| public void testGetNodeTextEscapedValue() { |
| forgeAndOpenDocument("<foo>\'</foo>"); |
| assertThat(parser.getText()).isEqualTo("\'"); |
| } |
| |
| @Test |
| public void testGetNodeTextEntityValue() { |
| forgeAndOpenDocument("<foo>\\u201e\\"</foo>"); |
| assertThat(parser.getText()).isEqualTo("„\""); |
| } |
| |
| @Test |
| public void testGetAttributeType() { |
| // Hardcoded to always return CDATA |
| assertThat(parser.getAttributeType(attributeIndexOutOfIndex())).isEqualTo("CDATA"); |
| } |
| |
| @Test |
| public void testIsAttributeDefault() { |
| assertThat(parser.isAttributeDefault(attributeIndexOutOfIndex())).isFalse(); |
| } |
| |
| @Test |
| public void testGetAttributeValueStringString() { |
| forgeAndOpenDocument("<foo xmlns:app=\"http://schemas.android.com/apk/res-auto\"" |
| + " app:bar=\"bar\"/>"); |
| assertThat(parser.getAttributeValue(RES_AUTO_NS, "bar")).isEqualTo("bar"); |
| } |
| |
| @Test |
| public void testNext() throws Exception { |
| // Recorded events while parsing preferences from Android |
| List<String> expectedEvents = Arrays.asList( |
| "<xml>", |
| "<", // PreferenceScreen |
| "<", // PreferenceCategory |
| "<", // Preference |
| ">", |
| ">", |
| |
| "<", // PreferenceScreen |
| "<", // Preference |
| ">", |
| "<", // Preference |
| ">", |
| ">", |
| |
| "<", // CheckBoxPreference |
| ">", |
| "<", // EditTextPreference |
| ">", |
| "<", // ListPreference |
| ">", |
| "<", // Preference |
| ">", |
| "<", //RingtonePreference |
| ">", |
| "<", // Preference |
| ">", |
| "<", |
| ">", |
| "<", |
| "<", |
| ">", |
| ">", |
| ">", |
| "</xml>"); |
| List<String> actualEvents = new ArrayList<>(); |
| |
| int evt; |
| do { |
| evt = parser.next(); |
| switch (evt) { |
| case XmlPullParser.START_DOCUMENT: |
| actualEvents.add("<xml>"); |
| break; |
| case XmlPullParser.END_DOCUMENT: |
| actualEvents.add("</xml>"); |
| break; |
| case XmlPullParser.START_TAG: |
| actualEvents.add("<"); |
| break; |
| case XmlPullParser.END_TAG: |
| actualEvents.add(">"); |
| break; |
| } |
| } while (evt != XmlResourceParser.END_DOCUMENT); |
| assertThat(actualEvents).isEqualTo(expectedEvents); |
| } |
| |
| @Test |
| public void testRequire() throws Exception { |
| parseUntilNext(XmlResourceParser.START_TAG); |
| parser.require(XmlResourceParser.START_TAG, |
| parser.getNamespace(), parser.getName()); |
| |
| try { |
| parser.require(XmlResourceParser.END_TAG, |
| parser.getNamespace(), parser.getName()); |
| fail("Require with wrong event should have failed"); |
| } catch (XmlPullParserException ex) { |
| // pass |
| } |
| |
| try { |
| parser.require(XmlResourceParser.START_TAG, |
| "foo", parser.getName()); |
| fail("Require with wrong namespace should have failed"); |
| } catch (XmlPullParserException ex) { |
| // pass |
| } |
| |
| try { |
| parser.require(XmlResourceParser.START_TAG, |
| parser.getNamespace(), "foo"); |
| fail("Require with wrong tag name should have failed"); |
| } catch (XmlPullParserException ex) { |
| // pass |
| } |
| } |
| |
| @Test |
| public void testNextText_noText() throws Exception { |
| forgeAndOpenDocument("<foo><bar/></foo>"); |
| try { |
| assertThat(parser.nextText()).isEqualTo(parser.getText()); |
| fail("nextText on a document with no text should have failed"); |
| } catch (XmlPullParserException ex) { |
| assertThat(parser.getEventType()).isAnyOf(XmlResourceParser.START_TAG, XmlResourceParser.END_DOCUMENT); |
| } |
| } |
| |
| /** |
| * Test that next tag will only return tag events. |
| */ |
| @Test |
| public void testNextTag() throws Exception { |
| Set<Integer> acceptableTags = new HashSet<>(); |
| acceptableTags.add(XmlResourceParser.START_TAG); |
| acceptableTags.add(XmlResourceParser.END_TAG); |
| |
| forgeAndOpenDocument("<foo><bar/><text>message</text></foo>"); |
| int evt; |
| do { |
| evt = parser.next(); |
| assertTrue(acceptableTags.contains(evt)); |
| } while (evt == XmlResourceParser.END_TAG && |
| "foo".equals(parser.getName())); |
| } |
| |
| @Test |
| public void testGetAttributeListValue_StringStringStringArrayInt() { |
| String[] options = {"foo", "bar"}; |
| forgeAndOpenDocument("<foo xmlns:app=\"http://schemas.android.com/apk/res-auto\"" |
| + " app:bar=\"bar\"/>"); |
| assertThat(parser.getAttributeListValue(RES_AUTO_NS, "bar", options, 0)).isEqualTo(1); |
| |
| forgeAndOpenDocument("<foo xmlns:app=\"http://schemas.android.com/apk/res-auto\"" |
| + " app:bar=\"unexpected\"/>"); |
| assertThat(parser.getAttributeListValue(RES_AUTO_NS, "bar", options, 0)).isEqualTo(0); |
| } |
| |
| @Test |
| public void testGetAttributeBooleanValue_StringStringBoolean() { |
| forgeAndOpenDocument("<foo xmlns:app=\"http://schemas.android.com/apk/res-auto\"" |
| + " app:bar=\"true\"/>"); |
| assertThat(parser.getAttributeBooleanValue(RES_AUTO_NS, "bar", false)).isTrue(); |
| assertThat(parser.getAttributeBooleanValue(RES_AUTO_NS, "foo", false)).isFalse(); |
| } |
| |
| @Test |
| public void testGetAttributeBooleanValue_IntBoolean() { |
| forgeAndOpenDocument("<foo bar=\"true\"/>"); |
| assertThat(parser.getAttributeBooleanValue(0, false)).isTrue(); |
| assertThat(parser.getAttributeBooleanValue(attributeIndexOutOfIndex(), false)).isFalse(); |
| } |
| |
| @Test |
| public void testGetAttributeResourceValueIntInt() throws Exception { |
| parser = context.getResources().getXml(R.xml.has_attribute_resource_value); |
| parseUntilNext(XmlResourceParser.START_TAG); |
| |
| assertThat(parser.getAttributeResourceValue(0, 42)).isEqualTo(R.layout.main); |
| } |
| |
| @Test |
| public void testGetAttributeResourceValueStringStringInt() throws Exception { |
| parser = context.getResources().getXml(R.xml.has_attribute_resource_value); |
| parseUntilNext(XmlResourceParser.START_TAG); |
| |
| assertThat(parser.getAttributeResourceValue(RES_AUTO_NS, "bar", 42)).isEqualTo(R.layout.main); |
| assertThat(parser.getAttributeResourceValue(RES_AUTO_NS, "foo", 42)).isEqualTo(42); |
| } |
| |
| @Test |
| public void testGetAttributeResourceValueWhenNotAResource() { |
| forgeAndOpenDocument("<foo xmlns:app=\"http://schemas.android.com/apk/res-auto\"" |
| + " app:bar=\"banana\"/>"); |
| assertThat(parser.getAttributeResourceValue(RES_AUTO_NS, "bar", 42)).isEqualTo(42); |
| } |
| |
| @Test |
| public void testGetAttributeIntValue_StringStringInt() { |
| forgeAndOpenDocument("<foo xmlns:app=\"http://schemas.android.com/apk/res-auto\"" |
| + " app:app=\"http://schemas.android.com/apk/res-auto\"" |
| + " app:bar=\"-12\"/>"); |
| |
| assertThat(parser.getAttributeIntValue(RES_AUTO_NS, "bar", 0)).isEqualTo(-12); |
| assertThat(parser.getAttributeIntValue(RES_AUTO_NS, "foo", 0)).isEqualTo(0); |
| } |
| |
| @Test |
| public void testGetAttributeIntValue_IntInt() { |
| forgeAndOpenDocument("<foo bar=\"-12\"/>"); |
| |
| assertThat(parser.getAttributeIntValue(0, 0)).isEqualTo(-12); |
| |
| assertThat(parser.getAttributeIntValue(attributeIndexOutOfIndex(), 0)).isEqualTo(0); |
| |
| forgeAndOpenDocument("<foo bar=\"unexpected\"/>"); |
| assertThat(parser.getAttributeIntValue(0, 0)).isEqualTo(0); |
| } |
| |
| @Test |
| public void testGetAttributeUnsignedIntValue_StringStringInt() { |
| forgeAndOpenDocument("<foo xmlns:app=\"http://schemas.android.com/apk/res-auto\"" |
| + " app:bar=\"12\"/>"); |
| |
| assertThat(parser.getAttributeUnsignedIntValue(RES_AUTO_NS, "bar", 0)).isEqualTo(12); |
| |
| assertThat(parser.getAttributeUnsignedIntValue(RES_AUTO_NS, "foo", 0)).isEqualTo(0); |
| |
| // Negative unsigned int must be |
| forgeAndOpenDocument("<foo xmlns:app=\"http://schemas.android.com/apk/res-auto\"" |
| + " app:bar=\"-12\"/>"); |
| |
| assertWithMessage("Getting a negative number as unsigned should return the default value.") |
| .that(parser.getAttributeUnsignedIntValue(RES_AUTO_NS, "bar", 0)) |
| .isEqualTo(0); |
| } |
| |
| @Test |
| public void testGetAttributeUnsignedIntValue_IntInt() { |
| forgeAndOpenDocument("<foo bar=\"12\"/>"); |
| |
| assertThat(parser.getAttributeUnsignedIntValue(0, 0)).isEqualTo(12); |
| |
| assertThat(parser.getAttributeUnsignedIntValue(attributeIndexOutOfIndex(), 0)).isEqualTo(0); |
| |
| // Negative unsigned int must be |
| forgeAndOpenDocument("<foo bar=\"-12\"/>"); |
| |
| assertWithMessage("Getting a negative number as unsigned should return the default value.") |
| .that(parser.getAttributeUnsignedIntValue(0, 0)) |
| .isEqualTo(0); |
| } |
| |
| @Test |
| public void testGetAttributeFloatValue_StringStringFloat() { |
| forgeAndOpenDocument("<foo xmlns:app=\"http://schemas.android.com/apk/res-auto\"" |
| + " app:bar=\"12.01\"/>"); |
| |
| assertThat(parser.getAttributeFloatValue(RES_AUTO_NS, "bar", 0.0f)).isEqualTo(12.01f); |
| |
| assertThat(parser.getAttributeFloatValue(RES_AUTO_NS, "foo", 0.0f)).isEqualTo(0.0f); |
| |
| forgeAndOpenDocument("<foo bar=\"unexpected\"/>"); |
| assertThat(parser.getAttributeFloatValue(RES_AUTO_NS, "bar", 0.0f)).isEqualTo(0.0f); |
| } |
| |
| @Test |
| public void testGetAttributeFloatValue_IntFloat() { |
| forgeAndOpenDocument("<foo bar=\"12.01\"/>"); |
| |
| assertThat(parser.getAttributeFloatValue(0, 0.0f)).isEqualTo(12.01f); |
| |
| assertThat(parser.getAttributeFloatValue( |
| attributeIndexOutOfIndex(), 0.0f)).isEqualTo(0.0f); |
| |
| forgeAndOpenDocument("<foo bar=\"unexpected\"/>"); |
| assertThat(parser.getAttributeFloatValue(0, 0.0f)).isEqualTo(0.0f); |
| } |
| |
| @Test |
| public void testGetAttributeListValue_IntStringArrayInt() { |
| String[] options = {"foo", "bar"}; |
| forgeAndOpenDocument("<foo xmlns:app=\"http://schemas.android.com/apk/res-auto\"" |
| + " app:bar=\"bar\"/>"); |
| assertThat(parser.getAttributeListValue(0, options, 0)).isEqualTo(1); |
| |
| forgeAndOpenDocument("<foo xmlns:app=\"http://schemas.android.com/apk/res-auto\"" |
| + " app:bar=\"unexpected\"/>"); |
| assertThat(parser.getAttributeListValue( |
| 0, options, 0)).isEqualTo(0); |
| |
| assertThat(parser.getAttributeListValue( |
| attributeIndexOutOfIndex(), options, 0)).isEqualTo(0); |
| } |
| |
| @Test |
| public void testGetIdAttribute() { |
| forgeAndOpenDocument("<foo/>"); |
| assertThat(parser.getIdAttribute()).isEqualTo(null); |
| |
| forgeAndOpenDocument("<foo id=\"bar\"/>"); |
| assertThat(parser.getIdAttribute()).isEqualTo("bar"); |
| } |
| |
| @Test |
| public void testGetClassAttribute() { |
| forgeAndOpenDocument("<foo/>"); |
| assertThat(parser.getClassAttribute()).isEqualTo(null); |
| |
| forgeAndOpenDocument("<foo class=\"bar\"/>"); |
| assertThat(parser.getClassAttribute()).isEqualTo("bar"); |
| } |
| |
| @Test |
| public void testGetIdAttributeResourceValue_defaultValue() throws Exception { |
| assertThat(parser.getIdAttributeResourceValue(12)).isEqualTo(12); |
| |
| parser = context.getResources().getXml(R.xml.has_id); |
| parseUntilNext(XmlResourceParser.START_TAG); |
| assertThat(parser.getIdAttributeResourceValue(12)).isEqualTo(R.id.tacos); |
| } |
| |
| @Test |
| public void testGetStyleAttribute() { |
| forgeAndOpenDocument("<foo/>"); |
| assertThat(parser.getStyleAttribute()).isEqualTo(0); |
| } |
| |
| @Test |
| public void getStyleAttribute_allowStyleAttrReference() throws Exception { |
| parser = context.getResources().getXml(R.xml.has_style_attribute_reference); |
| parseUntilNext(XmlResourceParser.START_TAG); |
| assertThat(parser.getStyleAttribute()).isEqualTo(R.attr.parentStyleReference); |
| } |
| |
| @Test |
| public void getStyleAttribute_allowStyleAttrReferenceLackingExplicitAttrType() throws Exception { |
| parser = context.getResources().getXml(R.xml.has_parent_style_reference); |
| parseUntilNext(XmlResourceParser.START_TAG); |
| assertThat(parser.getStyleAttribute()).isEqualTo(R.attr.parentStyleReference); |
| } |
| |
| @Test |
| public void getStyleAttribute_withMeaninglessString_returnsZero() { |
| forgeAndOpenDocument("<foo style=\"android:style/whatever\"/>"); |
| assertThat(parser.getStyleAttribute()).isEqualTo(0); |
| } |
| } |