1 // Copyright 2018 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.base; 6 7 import androidx.test.filters.SmallTest; 8 9 import org.junit.Assert; 10 import org.junit.Test; 11 import org.junit.runner.RunWith; 12 13 import org.chromium.base.test.BaseJUnit4ClassRunner; 14 15 /** Test class for {@link UserDataHost}. */ 16 @RunWith(BaseJUnit4ClassRunner.class) 17 public class UserDataHostTest { 18 private final UserDataHost mHost = new UserDataHost(); 19 20 private static class TestObjectA implements UserData { 21 private boolean mDestroyed; 22 23 @Override destroy()24 public void destroy() { 25 mDestroyed = true; 26 } 27 isDestroyed()28 private boolean isDestroyed() { 29 return mDestroyed; 30 } 31 } 32 33 private static class TestObjectB implements UserData { 34 private boolean mDestroyed; 35 36 @Override destroy()37 public void destroy() { 38 mDestroyed = true; 39 } 40 isDestroyed()41 private boolean isDestroyed() { 42 return mDestroyed; 43 } 44 } 45 getUserDataException( Class<T> key, Class<E> exceptionType)46 private <T extends UserData, E extends RuntimeException> void getUserDataException( 47 Class<T> key, Class<E> exceptionType) { 48 try { 49 mHost.getUserData(key); 50 } catch (Exception e) { 51 if (!exceptionType.isInstance(e)) throw e; 52 } 53 } 54 setUserDataException( Class<T> key, T obj, Class<E> exceptionType)55 private <T extends UserData, E extends RuntimeException> void setUserDataException( 56 Class<T> key, T obj, Class<E> exceptionType) { 57 try { 58 mHost.setUserData(key, obj); 59 } catch (Exception e) { 60 if (!exceptionType.isInstance(e)) throw e; 61 } 62 } 63 removeUserDataException( Class<T> key, Class<E> exceptionType)64 private <T extends UserData, E extends RuntimeException> void removeUserDataException( 65 Class<T> key, Class<E> exceptionType) { 66 try { 67 mHost.removeUserData(key); 68 } catch (Exception e) { 69 if (!exceptionType.isInstance(e)) throw e; 70 } 71 } 72 73 /** Verifies basic operations. */ 74 @Test 75 @SmallTest testBasicOperations()76 public void testBasicOperations() { 77 TestObjectA obj = new TestObjectA(); 78 mHost.setUserData(TestObjectA.class, obj); 79 Assert.assertEquals(obj, mHost.getUserData(TestObjectA.class)); 80 Assert.assertEquals(obj, mHost.removeUserData(TestObjectA.class)); 81 Assert.assertNull(mHost.getUserData(TestObjectA.class)); 82 removeUserDataException(TestObjectA.class, IllegalStateException.class); 83 } 84 85 /** Verifies nulled key or data are not allowed. */ 86 @Test 87 @SmallTest testNullKeyOrDataAreDisallowed()88 public void testNullKeyOrDataAreDisallowed() { 89 TestObjectA obj = new TestObjectA(); 90 setUserDataException(null, null, IllegalArgumentException.class); 91 setUserDataException(TestObjectA.class, null, IllegalArgumentException.class); 92 setUserDataException(null, obj, IllegalArgumentException.class); 93 getUserDataException(null, IllegalArgumentException.class); 94 removeUserDataException(null, IllegalArgumentException.class); 95 } 96 97 /** Verifies {@link #setUserData()} overwrites current data. */ 98 @Test 99 @SmallTest testSetUserDataOverwrites()100 public void testSetUserDataOverwrites() { 101 TestObjectA obj1 = new TestObjectA(); 102 mHost.setUserData(TestObjectA.class, obj1); 103 Assert.assertEquals(obj1, mHost.getUserData(TestObjectA.class)); 104 105 TestObjectA obj2 = new TestObjectA(); 106 mHost.setUserData(TestObjectA.class, obj2); 107 Assert.assertEquals(obj2, mHost.getUserData(TestObjectA.class)); 108 } 109 110 /** Verifies operation on a different thread is not allowed. */ 111 @Test 112 @SmallTest testSingleThreadPolicy()113 public void testSingleThreadPolicy() { 114 TestObjectA obj = new TestObjectA(); 115 mHost.setUserData(TestObjectA.class, obj); 116 ThreadUtils.runOnUiThreadBlocking( 117 () -> getUserDataException(TestObjectA.class, IllegalStateException.class)); 118 } 119 120 /** Verifies {@link UserHostData#destroy()} detroyes each {@link UserData} object. */ 121 @Test 122 @SmallTest testDestroy()123 public void testDestroy() { 124 TestObjectA objA = new TestObjectA(); 125 TestObjectB objB = new TestObjectB(); 126 mHost.setUserData(TestObjectA.class, objA); 127 mHost.setUserData(TestObjectB.class, objB); 128 Assert.assertEquals(objA, mHost.getUserData(TestObjectA.class)); 129 Assert.assertEquals(objB, mHost.getUserData(TestObjectB.class)); 130 131 mHost.destroy(); 132 Assert.assertTrue(objA.isDestroyed()); 133 Assert.assertTrue(objB.isDestroyed()); 134 } 135 136 /** Verifies that no operation is allowed after {@link #destroy()} is called. */ 137 @Test 138 @SmallTest testOperationsDisallowedAfterDestroy()139 public void testOperationsDisallowedAfterDestroy() { 140 TestObjectA obj = new TestObjectA(); 141 mHost.setUserData(TestObjectA.class, obj); 142 Assert.assertEquals(obj, mHost.getUserData(TestObjectA.class)); 143 144 mHost.destroy(); 145 getUserDataException(TestObjectA.class, IllegalStateException.class); 146 setUserDataException(TestObjectA.class, obj, IllegalStateException.class); 147 removeUserDataException(TestObjectA.class, IllegalStateException.class); 148 } 149 } 150