1 package org.robolectric.shadows; 2 3 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1; 4 import static java.nio.charset.StandardCharsets.UTF_8; 5 import static org.assertj.core.api.Assertions.assertThat; 6 7 import android.content.Context; 8 import android.content.Intent; 9 import android.content.res.Configuration; 10 import android.content.res.TypedArray; 11 import android.os.Build.VERSION_CODES; 12 import android.util.AttributeSet; 13 import java.io.File; 14 import java.io.FileInputStream; 15 import java.io.FileOutputStream; 16 import java.io.IOException; 17 import java.io.Writer; 18 import java.nio.file.Files; 19 import org.junit.Test; 20 import org.junit.runner.RunWith; 21 import org.robolectric.R; 22 import org.robolectric.Robolectric; 23 import org.robolectric.RobolectricTestRunner; 24 import org.robolectric.RuntimeEnvironment; 25 import org.robolectric.annotation.Config; 26 27 @RunWith(RobolectricTestRunner.class) 28 public class ShadowContextTest { 29 private final Context context = RuntimeEnvironment.application; 30 31 @Test 32 @Config(minSdk = JELLY_BEAN_MR1) createConfigurationContext()33 public void createConfigurationContext() { 34 assertThat(RuntimeEnvironment.application.createConfigurationContext(new Configuration())).isNotNull(); 35 } 36 37 @Test 38 @Config(minSdk = VERSION_CODES.O) startForegroundService()39 public void startForegroundService() { 40 Intent intent = new Intent(); 41 RuntimeEnvironment.application.startForegroundService(intent); 42 assertThat(ShadowApplication.getInstance().getNextStartedService()).isEqualTo(intent); 43 } 44 45 @Test shouldGetApplicationDataDirectory()46 public void shouldGetApplicationDataDirectory() throws IOException { 47 File dataDir = context.getDir("data", Context.MODE_PRIVATE); 48 assertThat(dataDir) 49 .isNotNull() 50 .exists(); 51 } 52 53 @Test shouldCreateIfDoesNotExistAndGetApplicationDataDirectory()54 public void shouldCreateIfDoesNotExistAndGetApplicationDataDirectory() throws Exception { 55 File dataDir = new File(context.getPackageManager() 56 .getPackageInfo("org.robolectric", 0).applicationInfo.dataDir, "data"); 57 58 assertThat(dataDir).doesNotExist(); 59 60 dataDir = context.getDir("data", Context.MODE_PRIVATE); 61 assertThat(dataDir) 62 .isNotNull() 63 .exists(); 64 } 65 66 @Test shouldStubThemeStuff()67 public void shouldStubThemeStuff() throws Exception { 68 assertThat(context.obtainStyledAttributes(new int[0])).isNotNull(); 69 assertThat(context.obtainStyledAttributes(0, new int[0])).isNotNull(); 70 assertThat(context.obtainStyledAttributes(null, new int[0])).isNotNull(); 71 assertThat(context.obtainStyledAttributes(null, new int[0], 0, 0)).isNotNull(); 72 } 73 74 @Test getCacheDir_shouldCreateDirectory()75 public void getCacheDir_shouldCreateDirectory() throws Exception { 76 assertThat(context.getCacheDir()).exists(); 77 } 78 79 @Test getExternalCacheDir_shouldCreateDirectory()80 public void getExternalCacheDir_shouldCreateDirectory() throws Exception { 81 assertThat(context.getExternalCacheDir()).exists(); 82 } 83 84 @Test shouldWriteToCacheDir()85 public void shouldWriteToCacheDir() throws Exception { 86 assertThat(context.getCacheDir()).isNotNull(); 87 File cacheTest = new File(context.getCacheDir(), "__test__"); 88 89 assertThat(cacheTest.getAbsolutePath()) 90 .startsWith(System.getProperty("java.io.tmpdir")) 91 .endsWith(File.separator + "__test__"); 92 93 try (FileOutputStream fos = new FileOutputStream(cacheTest)) { 94 fos.write("test".getBytes(UTF_8)); 95 } 96 assertThat(cacheTest).exists(); 97 } 98 99 @Test shouldWriteToExternalCacheDir()100 public void shouldWriteToExternalCacheDir() throws Exception { 101 assertThat(context.getExternalCacheDir()).isNotNull(); 102 File cacheTest = new File(context.getExternalCacheDir(), "__test__"); 103 104 assertThat(cacheTest.getAbsolutePath()) 105 .startsWith(System.getProperty("java.io.tmpdir")) 106 .endsWith(File.separator + "__test__"); 107 108 try (FileOutputStream fos = new FileOutputStream(cacheTest)) { 109 fos.write("test".getBytes(UTF_8)); 110 } 111 112 assertThat(cacheTest).exists(); 113 } 114 115 @Test getFilesDir_shouldCreateDirectory()116 public void getFilesDir_shouldCreateDirectory() throws Exception { 117 assertThat(context.getFilesDir()).exists(); 118 } 119 120 @Test fileList()121 public void fileList() throws Exception { 122 assertThat(context.fileList()).isEqualTo(context.getFilesDir().list()); 123 } 124 125 @Test getExternalFilesDir_shouldCreateDirectory()126 public void getExternalFilesDir_shouldCreateDirectory() throws Exception { 127 assertThat(context.getExternalFilesDir(null)).exists(); 128 } 129 130 @Test getExternalFilesDir_shouldCreateNamedDirectory()131 public void getExternalFilesDir_shouldCreateNamedDirectory() throws Exception { 132 File f = context.getExternalFilesDir("__test__"); 133 assertThat(f).exists(); 134 assertThat(f.getAbsolutePath()).endsWith("__test__"); 135 } 136 137 @Test getDatabasePath_shouldAllowAbsolutePaths()138 public void getDatabasePath_shouldAllowAbsolutePaths() throws Exception { 139 String testDbName; 140 141 if (System.getProperty("os.name").startsWith("Windows")) { 142 testDbName = "C:\\absolute\\full\\path\\to\\db\\abc.db"; 143 } else { 144 testDbName = "/absolute/full/path/to/db/abc.db"; 145 } 146 File dbFile = context.getDatabasePath(testDbName); 147 assertThat(dbFile).isEqualTo(new File(testDbName)); 148 } 149 150 @Test openFileInput_shouldReturnAFileInputStream()151 public void openFileInput_shouldReturnAFileInputStream() throws Exception { 152 String fileContents = "blah"; 153 154 File file = new File(context.getFilesDir(), "__test__"); 155 try (Writer fileWriter = Files.newBufferedWriter(file.toPath(), UTF_8)) { 156 fileWriter.write(fileContents); 157 } 158 159 try (FileInputStream fileInputStream = context.openFileInput("__test__")) { 160 byte[] bytes = new byte[fileContents.length()]; 161 fileInputStream.read(bytes); 162 assertThat(bytes).isEqualTo(fileContents.getBytes(UTF_8)); 163 } 164 } 165 166 @Test(expected = IllegalArgumentException.class) openFileInput_shouldNotAcceptPathsWithSeparatorCharacters()167 public void openFileInput_shouldNotAcceptPathsWithSeparatorCharacters() throws Exception { 168 try (FileInputStream fileInputStream = context.openFileInput("data" + File.separator + "test")) {} 169 } 170 171 @Test openFileOutput_shouldReturnAFileOutputStream()172 public void openFileOutput_shouldReturnAFileOutputStream() throws Exception { 173 File file = new File("__test__"); 174 String fileContents = "blah"; 175 try (FileOutputStream fileOutputStream = context.openFileOutput("__test__", Context.MODE_PRIVATE)) { 176 fileOutputStream.write(fileContents.getBytes(UTF_8)); 177 } 178 try (FileInputStream fileInputStream = new FileInputStream(new File(context.getFilesDir(), file.getName()))) { 179 byte[] readBuffer = new byte[fileContents.length()]; 180 fileInputStream.read(readBuffer); 181 assertThat(new String(readBuffer, UTF_8)).isEqualTo(fileContents); 182 } 183 } 184 185 @Test(expected = IllegalArgumentException.class) openFileOutput_shouldNotAcceptPathsWithSeparatorCharacters()186 public void openFileOutput_shouldNotAcceptPathsWithSeparatorCharacters() throws Exception { 187 try (FileOutputStream fos = context.openFileOutput(File.separator + "data" + File.separator + "test" + File.separator + "hi", 0)) {} 188 } 189 190 @Test openFileOutput_shouldAppendData()191 public void openFileOutput_shouldAppendData() throws Exception { 192 File file = new File("__test__"); 193 String initialFileContents = "foo"; 194 String appendedFileContents = "bar"; 195 String finalFileContents = initialFileContents + appendedFileContents; 196 try (FileOutputStream fileOutputStream = context.openFileOutput("__test__", Context.MODE_APPEND)) { 197 fileOutputStream.write(initialFileContents.getBytes(UTF_8)); 198 } 199 try (FileOutputStream fileOutputStream = context.openFileOutput("__test__", Context.MODE_APPEND)) { 200 fileOutputStream.write(appendedFileContents.getBytes(UTF_8)); 201 } 202 try (FileInputStream fileInputStream = new FileInputStream(new File(context.getFilesDir(), file.getName()))) { 203 byte[] readBuffer = new byte[finalFileContents.length()]; 204 fileInputStream.read(readBuffer); 205 assertThat(new String(readBuffer, UTF_8)).isEqualTo(finalFileContents); 206 } 207 } 208 209 @Test openFileOutput_shouldOverwriteData()210 public void openFileOutput_shouldOverwriteData() throws Exception { 211 File file = new File("__test__"); 212 String initialFileContents = "foo"; 213 String newFileContents = "bar"; 214 try (FileOutputStream fileOutputStream = context.openFileOutput("__test__", 0)) { 215 fileOutputStream.write(initialFileContents.getBytes(UTF_8)); 216 } 217 try (FileOutputStream fileOutputStream = context.openFileOutput("__test__", 0)) { 218 fileOutputStream.write(newFileContents.getBytes(UTF_8)); 219 } 220 try (FileInputStream fileInputStream = new FileInputStream(new File(context.getFilesDir(), file.getName()))) { 221 byte[] readBuffer = new byte[newFileContents.length()]; 222 fileInputStream.read(readBuffer); 223 assertThat(new String(readBuffer, UTF_8)).isEqualTo(newFileContents); 224 } 225 } 226 227 @Test deleteFile_shouldReturnTrue()228 public void deleteFile_shouldReturnTrue() throws IOException { 229 File filesDir = context.getFilesDir(); 230 File file = new File(filesDir, "test.txt"); 231 boolean successfully = file.createNewFile(); 232 assertThat(successfully).isTrue(); 233 successfully = context.deleteFile(file.getName()); 234 assertThat(successfully).isTrue(); 235 } 236 237 @Test deleteFile_shouldReturnFalse()238 public void deleteFile_shouldReturnFalse() throws IOException { 239 File filesDir = context.getFilesDir(); 240 File file = new File(filesDir, "test.txt"); 241 boolean successfully = context.deleteFile(file.getName()); 242 assertThat(successfully).isFalse(); 243 } 244 245 @Test obtainStyledAttributes_shouldExtractAttributesFromAttributeSet()246 public void obtainStyledAttributes_shouldExtractAttributesFromAttributeSet() throws Exception { 247 AttributeSet roboAttributeSet = Robolectric.buildAttributeSet() 248 .addAttribute(R.attr.itemType, "ungulate") 249 .addAttribute(R.attr.scrollBars, "horizontal|vertical") 250 .addAttribute(R.attr.quitKeyCombo, "^q") 251 .addAttribute(R.attr.aspectRatio, "1.5") 252 .addAttribute(R.attr.aspectRatioEnabled, "true") 253 .build(); 254 255 TypedArray a = context.obtainStyledAttributes(roboAttributeSet, R.styleable.CustomView); 256 assertThat(a.getInt(R.styleable.CustomView_itemType, -1234)).isEqualTo(1 /* ungulate */); 257 assertThat(a.getInt(R.styleable.CustomView_scrollBars, -1234)).isEqualTo(0x300); 258 assertThat(a.getString(R.styleable.CustomView_quitKeyCombo)).isEqualTo("^q"); 259 assertThat(a.getText(R.styleable.CustomView_quitKeyCombo).toString()).isEqualTo("^q"); 260 assertThat(a.getFloat(R.styleable.CustomView_aspectRatio, 1f)).isEqualTo(1.5f); 261 assertThat(a.getBoolean(R.styleable.CustomView_aspectRatioEnabled, false)).isTrue(); 262 263 TypedArray typedArray = context.obtainStyledAttributes(roboAttributeSet, new int[]{R.attr.quitKeyCombo, R.attr.itemType}); 264 assertThat(typedArray.getString(0)).isEqualTo("^q"); 265 assertThat(typedArray.getInt(1, -1234)).isEqualTo(1 /* ungulate */); 266 } 267 268 @Test whenStyleParentIsReference_obtainStyledAttributes_shouldResolveParent()269 public void whenStyleParentIsReference_obtainStyledAttributes_shouldResolveParent() throws Exception { 270 RuntimeEnvironment.application.setTheme(R.style.Theme_ThemeReferredToByParentAttrReference); 271 272 AttributeSet roboAttributeSet = Robolectric.buildAttributeSet() 273 .setStyleAttribute("@style/Theme.ThemeWithAttrReferenceAsParent") 274 .build(); 275 276 TypedArray a = context.obtainStyledAttributes(roboAttributeSet, new int[] { R.attr.string1, R.attr.string2 }); 277 assertThat(a.getString(0)).isEqualTo("string 1 from Theme.ThemeWithAttrReferenceAsParent"); 278 assertThat(a.getString(1)).isEqualTo("string 2 from StyleReferredToByParentAttrReference"); 279 } 280 } 281