| 
12 | 12 | import static org.junit.jupiter.api.parallel.ExecutionMode.SAME_THREAD;  | 
13 | 13 | 
 
  | 
14 | 14 | import edu.wpi.first.networktables.NetworkTable;  | 
 | 15 | +import edu.wpi.first.networktables.NetworkTableEntry;  | 
 | 16 | +import edu.wpi.first.networktables.NetworkTableEvent;  | 
15 | 17 | import edu.wpi.first.networktables.NetworkTableInstance;  | 
 | 18 | +import edu.wpi.first.networktables.NetworkTableListener;  | 
16 | 19 | import edu.wpi.first.networktables.Topic;  | 
17 | 20 | import java.io.IOException;  | 
18 | 21 | import java.io.InputStream;  | 
19 | 22 | import java.nio.file.Files;  | 
20 | 23 | import java.nio.file.Path;  | 
21 | 24 | import java.util.ArrayList;  | 
22 | 25 | import java.util.Arrays;  | 
 | 26 | +import java.util.EnumSet;  | 
23 | 27 | import java.util.List;  | 
 | 28 | +import java.util.concurrent.Semaphore;  | 
 | 29 | +import java.util.concurrent.TimeUnit;  | 
24 | 30 | import java.util.stream.Stream;  | 
25 | 31 | import org.junit.jupiter.api.AfterEach;  | 
26 | 32 | import org.junit.jupiter.api.BeforeEach;  | 
 | 
31 | 37 | import org.junit.jupiter.api.parallel.Execution;  | 
32 | 38 | import org.junit.jupiter.params.ParameterizedTest;  | 
33 | 39 | import org.junit.jupiter.params.provider.MethodSource;  | 
 | 40 | +import org.junit.jupiter.params.provider.ValueSource;  | 
34 | 41 | 
 
  | 
35 | 42 | @Execution(SAME_THREAD)  | 
36 | 43 | class PreferencesTest {  | 
@@ -69,6 +76,7 @@ void setup(@TempDir Path tempDir) {  | 
69 | 76 | 
 
  | 
70 | 77 |   @AfterEach  | 
71 | 78 |   void cleanup() {  | 
 | 79 | +    m_inst.waitForListenerQueue(0.1);  | 
72 | 80 |     m_inst.close();  | 
73 | 81 |   }  | 
74 | 82 | 
 
  | 
@@ -121,6 +129,40 @@ void defaultValueTest() {  | 
121 | 129 |         () -> assertFalse(Preferences.getBoolean("checkedValueBoolean", true)));  | 
122 | 130 |   }  | 
123 | 131 | 
 
  | 
 | 132 | +  @ParameterizedTest  | 
 | 133 | +  @ValueSource(booleans = {true, false})  | 
 | 134 | +  void enableLegacyDashboardSupportTest(boolean enable) throws InterruptedException {  | 
 | 135 | +    // Publish a value, wait until we are sure the listener would have fired, and verify that the  | 
 | 136 | +    // topic is persistant only if legacy dashboard support is enabled.  | 
 | 137 | +    boolean wasEnabled = Preferences.enableLegacyDashboardSupport(enable);  | 
 | 138 | +    Semaphore semaphore = new Semaphore(0);  | 
 | 139 | +    NetworkTableEntry entry = m_table.getEntry("legacyDashboardValueLong");  | 
 | 140 | +    try (NetworkTableListener listener =  | 
 | 141 | +        NetworkTableListener.createListener(  | 
 | 142 | +            entry,  | 
 | 143 | +            EnumSet.of(NetworkTableEvent.Kind.kImmediate, NetworkTableEvent.Kind.kValueAll),  | 
 | 144 | +            event -> {  | 
 | 145 | +              if (event.valueData != null) {  | 
 | 146 | +                semaphore.release();  | 
 | 147 | +              }  | 
 | 148 | +            })) {  | 
 | 149 | +      // Publish a value, wait for listeners to fire, and do that again. This ensures any listener  | 
 | 150 | +      // installed by Preferences would have been called at least once.  | 
 | 151 | +      for (int value = 1; value < 3; value++) {  | 
 | 152 | +        entry.setInteger(value);  | 
 | 153 | +        m_inst.waitForListenerQueue(0.5);  | 
 | 154 | +        if (!semaphore.tryAcquire(100, TimeUnit.MILLISECONDS)) {  | 
 | 155 | +          fail("timed out waiting for event listener");  | 
 | 156 | +        }  | 
 | 157 | +      }  | 
 | 158 | +      assertEquals(enable, entry.isPersistent());  | 
 | 159 | +    } finally {  | 
 | 160 | +      if (wasEnabled != enable) {  | 
 | 161 | +        Preferences.enableLegacyDashboardSupport(wasEnabled);  | 
 | 162 | +      }  | 
 | 163 | +    }  | 
 | 164 | +  }  | 
 | 165 | + | 
124 | 166 |   @Nested  | 
125 | 167 |   class PutGetTests {  | 
126 | 168 |     @Test  | 
 | 
0 commit comments