[wpilib] Remove Shuffleboard API (#7730)

This commit is contained in:
Peter Johnson
2025-01-24 23:47:42 -08:00
committed by GitHub
parent 01e71e73ce
commit adbe95e610
82 changed files with 60 additions and 6776 deletions

View File

@@ -1,22 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.wpilibj.shuffleboard;
import edu.wpi.first.util.sendable.Sendable;
import edu.wpi.first.util.sendable.SendableBuilder;
import edu.wpi.first.util.sendable.SendableRegistry;
/** A mock sendable that marks itself as an actuator. */
public class MockActuatorSendable implements Sendable {
@SuppressWarnings("this-escape")
public MockActuatorSendable(String name) {
SendableRegistry.add(this, name);
}
@Override
public void initSendable(SendableBuilder builder) {
builder.setActuator(true);
}
}

View File

@@ -1,65 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.wpilibj.shuffleboard;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import edu.wpi.first.networktables.NetworkTableInstance;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class SendableCameraWrapperTest {
NetworkTableInstance m_inst;
@BeforeEach
void setup() {
m_inst = NetworkTableInstance.create();
SendableCameraWrapper.clearWrappers();
}
@AfterEach
void tearDown() {
m_inst.close();
}
@Test
void testNullCameraName() {
assertThrows(NullPointerException.class, () -> SendableCameraWrapper.wrap(null, ""));
}
@Test
void testEmptyCameraName() {
assertThrows(IllegalArgumentException.class, () -> SendableCameraWrapper.wrap("", ""));
}
@Test
void testNullUrlArray() {
assertThrows(
NullPointerException.class, () -> SendableCameraWrapper.wrap("name", (String[]) null));
}
@Test
void testNullUrlInArray() {
assertThrows(NullPointerException.class, () -> SendableCameraWrapper.wrap("name", "url", null));
}
@Test
void testEmptyUrlArray() {
assertThrows(IllegalArgumentException.class, () -> SendableCameraWrapper.wrap("name"));
}
@Test
void testUrlsAddedToNt() {
SendableCameraWrapper.wrap("name", "url1", "url2");
assertArrayEquals(
new String[] {"url1", "url2"},
NetworkTableInstance.getDefault()
.getEntry("/CameraPublisher/name/streams")
.getValue()
.getStringArray());
}
}

View File

@@ -1,158 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.wpilibj.shuffleboard;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import edu.wpi.first.networktables.GenericEntry;
import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.networktables.NetworkTableEvent.Kind;
import edu.wpi.first.networktables.NetworkTableInstance;
import edu.wpi.first.networktables.PubSubOption;
import edu.wpi.first.networktables.StringSubscriber;
import java.util.EnumSet;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
class ShuffleboardInstanceTest {
private NetworkTableInstance m_ntInstance;
private ShuffleboardInstance m_shuffleboardInstance;
@BeforeEach
void setupInstance() {
m_ntInstance = NetworkTableInstance.create();
m_shuffleboardInstance = new ShuffleboardInstance(m_ntInstance);
}
@AfterEach
void tearDownInstance() {
m_ntInstance.close();
}
@Test
void testPathFluent() {
GenericEntry entry =
m_shuffleboardInstance
.getTab("Tab Title")
.getLayout("Layout Title", "List Layout")
.add("Data", "string")
.withWidget("Text View")
.getEntry();
assertAll(
() -> assertEquals("string", entry.getString(null), "Wrong entry value"),
() ->
assertEquals(
"/Shuffleboard/Tab Title/Layout Title/Data",
entry.getTopic().getName(),
"Entry path generated incorrectly"));
}
@Test
void testNestedLayoutsFluent() {
GenericEntry entry =
m_shuffleboardInstance
.getTab("Tab")
.getLayout("First", "List")
.getLayout("Second", "List")
.getLayout("Third", "List")
.getLayout("Fourth", "List")
.add("Value", "string")
.getEntry();
assertAll(
() -> assertEquals("string", entry.getString(null), "Wrong entry value"),
() ->
assertEquals(
"/Shuffleboard/Tab/First/Second/Third/Fourth/Value",
entry.getTopic().getName(),
"Entry path generated incorrectly"));
}
@Test
void testNestedLayoutsOop() {
ShuffleboardTab tab = m_shuffleboardInstance.getTab("Tab");
ShuffleboardLayout first = tab.getLayout("First", "List");
ShuffleboardLayout second = first.getLayout("Second", "List");
ShuffleboardLayout third = second.getLayout("Third", "List");
ShuffleboardLayout fourth = third.getLayout("Fourth", "List");
SimpleWidget widget = fourth.add("Value", "string");
GenericEntry entry = widget.getEntry();
assertAll(
() -> assertEquals("string", entry.getString(null), "Wrong entry value"),
() ->
assertEquals(
"/Shuffleboard/Tab/First/Second/Third/Fourth/Value",
entry.getTopic().getName(),
"Entry path generated incorrectly"));
}
@Test
void testLayoutTypeIsSet() {
String layoutType = "Type";
m_shuffleboardInstance.getTab("Tab").getLayout("Title", layoutType);
m_shuffleboardInstance.update();
NetworkTableEntry entry =
m_ntInstance.getEntry("/Shuffleboard/.metadata/Tab/Title/PreferredComponent");
assertEquals(layoutType, entry.getString("Not Set"), "Layout type not set");
}
@Test
void testNestedActuatorWidgetsAreDisabled() {
m_shuffleboardInstance
.getTab("Tab")
.getLayout("Title", "Layout")
.add(new MockActuatorSendable("Actuator"));
NetworkTableEntry controllableEntry =
m_ntInstance.getEntry("/Shuffleboard/Tab/Title/Actuator/.controllable");
m_shuffleboardInstance.update();
// Note: we use the unsafe `getBoolean()` method because if the value is NOT a boolean, or if it
// is not present, then something has clearly gone very, very wrong
boolean controllable = controllableEntry.getValue().getBoolean();
// Sanity check
assertTrue(controllable, "The nested actuator widget should be enabled by default");
m_shuffleboardInstance.disableActuatorWidgets();
controllable = controllableEntry.getValue().getBoolean();
assertFalse(controllable, "The nested actuator widget should have been disabled");
}
@Disabled("Fails often at counter assertion 'expected: <2> but was: <1>'")
@Test
void testDuplicateSelectTabs() {
int listener = 0;
AtomicInteger counter = new AtomicInteger();
try (StringSubscriber subscriber =
m_ntInstance
.getStringTopic("/Shuffleboard/.metadata/Selected")
.subscribe("", PubSubOption.keepDuplicates(true))) {
listener =
m_ntInstance.addListener(
subscriber,
EnumSet.of(Kind.kValueAll, Kind.kImmediate),
event -> counter.incrementAndGet());
// There shouldn't be anything there
assertEquals(0, counter.get());
m_shuffleboardInstance.selectTab("tab1");
m_shuffleboardInstance.selectTab("tab1");
assertTrue(m_ntInstance.waitForListenerQueue(1.0), "Listener queue timed out!");
assertEquals(2, counter.get());
} finally {
m_ntInstance.removeListener(listener);
}
}
}

View File

@@ -1,25 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.wpilibj.shuffleboard;
import static org.junit.jupiter.api.Assertions.assertSame;
import edu.wpi.first.wpilibj.UtilityClassTest;
import org.junit.jupiter.api.Test;
class ShuffleboardTest extends UtilityClassTest<Shuffleboard> {
ShuffleboardTest() {
super(Shuffleboard.class);
}
// Most relevant tests are in ShuffleboardTabTest
@Test
void testTabObjectsCached() {
ShuffleboardTab tab1 = Shuffleboard.getTab("testTabObjectsCached");
ShuffleboardTab tab2 = Shuffleboard.getTab("testTabObjectsCached");
assertSame(tab1, tab2, "Tab objects were not cached");
}
}

View File

@@ -1,112 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.wpilibj.shuffleboard;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.networktables.NetworkTableInstance;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class SuppliedValueWidgetTest {
private NetworkTableInstance m_ntInstance;
private ShuffleboardInstance m_instance;
@BeforeEach
void setup() {
m_ntInstance = NetworkTableInstance.create();
m_instance = new ShuffleboardInstance(m_ntInstance);
}
@AfterEach
void tearDown() {
m_ntInstance.close();
}
@Test
void testAddString() {
AtomicInteger count = new AtomicInteger(0);
m_instance.getTab("Tab").addString("Title", () -> Integer.toString(count.incrementAndGet()));
NetworkTableEntry entry = m_ntInstance.getEntry("/Shuffleboard/Tab/Title");
m_instance.update();
assertEquals("1", entry.getString(null));
m_instance.update();
assertEquals("2", entry.getString(null));
}
@Test
void testAddDouble() {
AtomicInteger num = new AtomicInteger(0);
m_instance.getTab("Tab").addNumber("Title", num::incrementAndGet);
NetworkTableEntry entry = m_ntInstance.getEntry("/Shuffleboard/Tab/Title");
m_instance.update();
assertEquals(1, entry.getDouble(0));
m_instance.update();
assertEquals(2, entry.getDouble(0));
}
@Test
void testAddBoolean() {
boolean[] bool = {false};
m_instance.getTab("Tab").addBoolean("Title", () -> bool[0] = !bool[0]);
NetworkTableEntry entry = m_ntInstance.getEntry("/Shuffleboard/Tab/Title");
m_instance.update();
assertTrue(entry.getBoolean(false));
m_instance.update();
assertFalse(entry.getBoolean(true));
}
@Test
void testAddStringArray() {
String[] arr = {"foo", "bar"};
m_instance.getTab("Tab").addStringArray("Title", () -> arr);
NetworkTableEntry entry = m_ntInstance.getEntry("/Shuffleboard/Tab/Title");
m_instance.update();
assertArrayEquals(arr, entry.getStringArray(new String[0]));
}
@Test
void testAddDoubleArray() {
double[] arr = {0, 1};
m_instance.getTab("Tab").addDoubleArray("Title", () -> arr);
NetworkTableEntry entry = m_ntInstance.getEntry("/Shuffleboard/Tab/Title");
m_instance.update();
assertArrayEquals(arr, entry.getDoubleArray(new double[0]));
}
@Test
void testAddBooleanArray() {
boolean[] arr = {true, false};
m_instance.getTab("Tab").addBooleanArray("Title", () -> arr);
NetworkTableEntry entry = m_ntInstance.getEntry("/Shuffleboard/Tab/Title");
m_instance.update();
assertArrayEquals(arr, entry.getBooleanArray(new boolean[0]));
}
@Test
void testAddRawBytes() {
byte[] arr = {0, 1, 2, 3};
m_instance.getTab("Tab").addRaw("Title", () -> arr);
NetworkTableEntry entry = m_ntInstance.getEntry("/Shuffleboard/Tab/Title");
m_instance.update();
assertArrayEquals(arr, entry.getRaw(new byte[0]));
}
}