Add Bundle#getString(String key, String defaultValue) support

Change-Id: I5b577de3876e3017f85ffd5bb88786309cc82f5c
diff --git a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowBundle.java b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowBundle.java
index 1794a79..cc458bc 100644
--- a/src/main/java/com/xtremelabs/robolectric/shadows/ShadowBundle.java
+++ b/src/main/java/com/xtremelabs/robolectric/shadows/ShadowBundle.java
@@ -8,6 +8,7 @@
 import java.util.Map;
 import java.util.Set;
 
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Parcelable;
 
@@ -51,6 +52,18 @@
     }
 
     @Implementation
+    public String getString(String key, String defaultValue) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) {
+            throw new RuntimeException(new NoSuchMethodException("Requires API_12"));
+        }
+        if (map.containsKey(key)) {
+            Object value = map.get(key);
+            return value == null || !(value instanceof String) ? null : (String) value;
+        }
+        return defaultValue;
+    }
+
+    @Implementation
     public void putLong(String key, long value) {
         map.put(key, value);
     }
diff --git a/src/test/java/com/xtremelabs/robolectric/shadows/BundleTest.java b/src/test/java/com/xtremelabs/robolectric/shadows/BundleTest.java
index cd845d4..c67b2f6 100644
--- a/src/test/java/com/xtremelabs/robolectric/shadows/BundleTest.java
+++ b/src/test/java/com/xtremelabs/robolectric/shadows/BundleTest.java
@@ -1,7 +1,9 @@
 package com.xtremelabs.robolectric.shadows;
 
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Parcelable;
+import com.xtremelabs.robolectric.Robolectric;
 import com.xtremelabs.robolectric.WithTestDefaultsRunner;
 import junit.framework.AssertionFailedError;
 import org.junit.Assert;
@@ -80,6 +82,106 @@
     }
 
     @Test
+    public void testStringHasValue() {
+        bundle.putString("key", "value");
+        assertEquals("value", bundle.getString("key"));
+    }
+
+    @Test
+    public void testStringDoesNotHaveValue() {
+        assertNull(bundle.getString("key"));
+    }
+
+    @Test
+    public void testStringNullKey() {
+        bundle.putString(null, "value");
+        assertEquals("value", bundle.getString(null));
+    }
+
+    @Test
+    public void testStringNullValue() {
+        bundle.putString("key", null);
+        assertNull(bundle.getString("key"));
+    }
+
+    @Test
+    public void testStringApi1() {
+        int previousApiLevel = Build.VERSION.SDK_INT;
+        Robolectric.Reflection.setFinalStaticField(Build.VERSION.class, "SDK_INT",
+                Build.VERSION_CODES.BASE);
+
+        try {
+            bundle.getString("value", "defaultValue");
+            fail();
+        } catch (RuntimeException e) {
+            // Expected
+        } finally {
+            Robolectric.Reflection.setFinalStaticField(Build.VERSION.class, "SDK_INT",
+                    previousApiLevel);
+        }
+    }
+
+    @Test
+    public void testStringApi12HasKey() {
+        int previousApiLevel = Build.VERSION.SDK_INT;
+        Robolectric.Reflection.setFinalStaticField(Build.VERSION.class, "SDK_INT",
+                Build.VERSION_CODES.HONEYCOMB_MR1);
+
+        try {
+            bundle.putString("key", "value");
+            assertEquals("value", bundle.getString("key", "defaultValue"));
+        } finally {
+            Robolectric.Reflection.setFinalStaticField(Build.VERSION.class, "SDK_INT",
+                    previousApiLevel);
+        }
+    }
+
+    @Test
+    public void testStringApi12DoesNotHaveKey() {
+        int previousApiLevel = Build.VERSION.SDK_INT;
+        Robolectric.Reflection.setFinalStaticField(Build.VERSION.class, "SDK_INT",
+                Build.VERSION_CODES.HONEYCOMB_MR1);
+
+        try {
+            bundle.putString("key", "value");
+            assertEquals("defaultValue", bundle.getString("foo", "defaultValue"));
+        } finally {
+            Robolectric.Reflection.setFinalStaticField(Build.VERSION.class, "SDK_INT",
+                    previousApiLevel);
+        }
+    }
+
+    @Test
+    public void testStringApi12NullKey() {
+        int previousApiLevel = Build.VERSION.SDK_INT;
+        Robolectric.Reflection.setFinalStaticField(Build.VERSION.class, "SDK_INT",
+                Build.VERSION_CODES.HONEYCOMB_MR1);
+
+        try {
+            bundle.putString(null, "value");
+            assertEquals("value", bundle.getString(null, "defaultValue"));
+        } finally {
+            Robolectric.Reflection.setFinalStaticField(Build.VERSION.class, "SDK_INT",
+                    previousApiLevel);
+        }
+    }
+
+    @Test
+    public void testStringApi12NullValue() {
+        int previousApiLevel = Build.VERSION.SDK_INT;
+        Robolectric.Reflection.setFinalStaticField(Build.VERSION.class, "SDK_INT",
+                Build.VERSION_CODES.HONEYCOMB_MR1);
+
+        try {
+            bundle.putString("key", null);
+            assertNull(bundle.getString("key", "defaultValue"));
+        } finally {
+            Robolectric.Reflection.setFinalStaticField(Build.VERSION.class, "SDK_INT",
+                    previousApiLevel);
+        }
+    }
+
+    @Test
     public void testGetOfWrongType() {
         bundle.putFloat("foo", 5f);
         assertEquals(0, bundle.getChar("foo"));