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