1 // Copyright 2023 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 static junit.framework.Assert.assertEquals; 8 import static junit.framework.Assert.assertNull; 9 10 import org.junit.After; 11 import org.junit.AfterClass; 12 import org.junit.Assert; 13 import org.junit.Before; 14 import org.junit.BeforeClass; 15 import org.junit.Test; 16 import org.junit.runner.RunWith; 17 import org.robolectric.annotation.Config; 18 19 import org.chromium.base.test.BaseRobolectricTestRunner; 20 21 /** Unit tests for {@link ResettersForTesting}. */ 22 @RunWith(BaseRobolectricTestRunner.class) 23 @Config(manifest = Config.NONE) 24 public class ResettersForTestingTest { 25 private static class ResetsToNull { 26 public static String str; 27 setStrForTesting(String newStr)28 public static void setStrForTesting(String newStr) { 29 str = newStr; 30 ResettersForTesting.register(() -> str = null); 31 } 32 } 33 34 private static class ResetsToOldValue { 35 public static String str; 36 setStrForTesting(String newStr)37 public static void setStrForTesting(String newStr) { 38 String oldValue = str; 39 str = newStr; 40 ResettersForTesting.register(() -> str = oldValue); 41 } 42 } 43 44 private static class ResetsToNullAndIncrements { 45 public static String str; 46 public static int resetCount; 47 setStrForTesting(String newStr)48 public static void setStrForTesting(String newStr) { 49 str = newStr; 50 ResettersForTesting.register( 51 () -> { 52 str = null; 53 resetCount++; 54 }); 55 } 56 } 57 58 private static class ResetsToNullAndIncrementsWithOneShotResetter { 59 public static String str; 60 public static int resetCount; 61 private static Runnable sResetter = 62 () -> { 63 str = null; 64 resetCount++; 65 }; 66 setStrForTesting(String newStr)67 public static void setStrForTesting(String newStr) { 68 str = newStr; 69 ResettersForTesting.register(sResetter); 70 } 71 } 72 73 @BeforeClass setUpClass()74 public static void setUpClass() { 75 assertNull(ResetsToOldValue.str); 76 ResetsToOldValue.setStrForTesting("setUpClass"); 77 } 78 79 @AfterClass tearDownClass()80 public static void tearDownClass() { 81 assertEquals("setUpClass", ResetsToOldValue.str); 82 // There's no way to test that the runner's afterClass calls this, so at least test that 83 // calling it manually works. 84 ResettersForTesting.onAfterClass(); 85 assertNull(ResetsToOldValue.str); 86 } 87 88 @Before setUp()89 public void setUp() { 90 assertEquals("setUpClass", ResetsToOldValue.str); 91 ResetsToOldValue.setStrForTesting("setUp"); 92 } 93 94 @After tearDown()95 public void tearDown() { 96 ResettersForTesting.onAfterMethod(); 97 assertEquals("setUpClass", ResetsToOldValue.str); 98 } 99 100 @Test testTypicalUsage()101 public void testTypicalUsage() { 102 ResetsToNull.setStrForTesting("foo"); 103 assertEquals("foo", ResetsToNull.str); 104 ResettersForTesting.onAfterMethod(); 105 Assert.assertNull(ResetsToNull.str); 106 } 107 108 @Test testResetsToPreviousValue()109 public void testResetsToPreviousValue() { 110 assertEquals("setUp", ResetsToOldValue.str); 111 112 ResetsToOldValue.setStrForTesting("foo"); 113 assertEquals("foo", ResetsToOldValue.str); 114 115 // After resetting the value, it should be back to the value set before setUp(). 116 ResettersForTesting.onAfterMethod(); 117 assertEquals("setUpClass", ResetsToOldValue.str); 118 } 119 120 @Test testMultipleResets()121 public void testMultipleResets() { 122 assertEquals("setUp", ResetsToOldValue.str); 123 124 // Then set the next value. 125 ResetsToOldValue.setStrForTesting("foo"); 126 assertEquals("foo", ResetsToOldValue.str); 127 128 // Now, next that value into another one to ensure the unwinding works. 129 ResetsToOldValue.setStrForTesting("bar"); 130 assertEquals("bar", ResetsToOldValue.str); 131 132 // After resetting the value, it should be back to the value set before setUp(). 133 ResettersForTesting.onAfterMethod(); 134 assertEquals("setUpClass", ResetsToOldValue.str); 135 } 136 137 @Test testResettersExecutedOnlyOnce()138 public void testResettersExecutedOnlyOnce() { 139 // Force set this to 0 for this particular test. 140 ResetsToNullAndIncrements.resetCount = 0; 141 ResetsToNullAndIncrements.str = null; 142 143 // Set the initial value and register the resetter. 144 ResetsToNullAndIncrements.setStrForTesting("some value"); 145 assertEquals("some value", ResetsToNullAndIncrements.str); 146 147 // Now, execute all resetters and ensure it's only executed once. 148 ResettersForTesting.onAfterMethod(); 149 assertEquals(1, ResetsToNullAndIncrements.resetCount); 150 151 // Execute the resetters again, and verify it does not invoke the same resetter again. 152 ResettersForTesting.onAfterMethod(); 153 assertEquals(1, ResetsToNullAndIncrements.resetCount); 154 } 155 156 @Test testResettersExecutedOnlyOnceForOneShotResetters()157 public void testResettersExecutedOnlyOnceForOneShotResetters() { 158 // Force set this to 0 for this particular test. 159 ResetsToNullAndIncrementsWithOneShotResetter.resetCount = 0; 160 ResetsToNullAndIncrementsWithOneShotResetter.str = null; 161 162 // Set the initial value and register the resetter twice. 163 ResetsToNullAndIncrementsWithOneShotResetter.setStrForTesting("some value"); 164 ResetsToNullAndIncrementsWithOneShotResetter.setStrForTesting("some other value"); 165 assertEquals("some other value", ResetsToNullAndIncrementsWithOneShotResetter.str); 166 167 // Now, execute all resetters and ensure it's only executed once, since it is a single 168 // instance of the same resetter. 169 ResettersForTesting.onAfterMethod(); 170 assertEquals(1, ResetsToNullAndIncrementsWithOneShotResetter.resetCount); 171 172 // Execute the resetters again, and verify it does not invoke the same resetter again. 173 ResettersForTesting.onAfterMethod(); 174 assertEquals(1, ResetsToNullAndIncrementsWithOneShotResetter.resetCount); 175 } 176 } 177