[robotpy] Mirror most other subprojects (#8208)

GitOrigin-RevId: ac60fd3cf4a24023184376687da28373d14b781a

This mirrors the robotpy files for the following projects:
- apriltag
- datalog
- hal
- ntcore
- romiVendordep
- wpilibc
- wpimath
- xrpVendordep

This excludes cscore and the halsim wrappers for at this time.

NOTE: This does not hook these projects up to the build system, just simply mirrors the files. The building will take place in a follow up PR to make it easier to review the changes necessary to build.
This commit is contained in:
PJ Reiniger
2025-10-24 01:28:04 -04:00
committed by GitHub
parent 8992dcdc99
commit 44b9cc1398
545 changed files with 27293 additions and 38 deletions

View File

@@ -0,0 +1,165 @@
#
# Useful fixtures
#
from contextlib import contextmanager
from threading import Condition
import logging
logger = logging.getLogger("conftest")
import pytest
from ntcore import NetworkTableInstance, MultiSubscriber, Event, EventFlags
#
# Fixtures for a usable in-memory version of networktables
#
@pytest.fixture
def cfg_logging(caplog):
caplog.set_level(logging.INFO)
@pytest.fixture(scope="function")
def nt(cfg_logging):
instance = NetworkTableInstance.create()
instance.startLocal()
try:
yield instance
finally:
NetworkTableInstance.destroy(instance)
#
# Live NT instance fixtures
#
class NtTestBase:
"""
Object for managing a live pair of NT server/client
"""
_wait_lock = None
def __init__(self):
self.reset()
def reset(self):
self._impl = NetworkTableInstance.create()
self.getTable = self._impl.getTable
self.isConnected = self._impl.isConnected
def shutdown(self):
logger.info("shutting down %s", self.__class__.__name__)
if self._impl:
NetworkTableInstance.destroy(self._impl)
self._impl = None
# def disconnect(self):
# self._api.dispatcher.stop()
def _init_common(self):
# This resets the instance to be independent
self.shutdown()
self.reset()
# self._wait_init()
def _init_server(self, port=23232):
self._init_common()
self.port = port
def _init_client(self):
self._init_common()
def _wait_init(self):
logger.info("wait-init %s", self.__class__.__name__)
self._wait_lock = Condition()
self._wait = 0
self.msub = MultiSubscriber(self._impl, [""])
self.vl = self._impl.addListener(
self.msub, EventFlags.kValueRemote, self._wait_cb
)
def _wait_cb(self, evt: Event):
logger.info("wait-callback %s: %s", self.__class__.__name__, evt)
with self._wait_lock:
self._wait += 1
self._wait_lock.notify()
@contextmanager
def expect_changes(self, count):
"""Use this on the *other* instance that you're making
changes on, to wait for the changes to propagate to the
other instance"""
if self._wait_lock is None:
self._wait_init()
with self._wait_lock:
self._wait = 0
logger.info("Begin actions")
yield
logger.info("Waiting for %s changes", count)
with self._wait_lock:
self._wait_lock.wait_for(lambda: self._wait >= count, 4)
logger.info("expect_changes: %s == %s", self._wait, count)
msg = "Failed waiting for exactly %s changes (got %s)" % (count, self._wait)
assert self._wait == count, msg
@pytest.fixture()
def nt_server(request, cfg_logging):
class NtServer(NtTestBase):
_test_saved_port = None
def start_test(self):
logger.info("NtServer::start_test")
# Restore server port on restart
if self._test_saved_port is not None:
self.port = self._test_saved_port
self._impl.startServer(listen_address="127.0.0.1", port=self.port)
self._test_saved_port = self.port
server = NtServer()
server._init_server()
try:
yield server
finally:
server.shutdown()
@pytest.fixture()
def nt_client(request, nt_server):
class NtClient(NtTestBase):
def start_test(self):
self._impl.startClient("C4")
self._impl.setServer("127.0.0.1", nt_server.port)
client = NtClient()
client._init_client()
yield client
client.shutdown()
@pytest.fixture
def nt_live(nt_server, nt_client):
"""This fixture automatically starts the client and server"""
nt_server.start_test()
nt_client.start_test()
return nt_server, nt_client

View File

@@ -0,0 +1,155 @@
#
# These tests stand up a separate client and server instance of
# networktables and tests the 'real' user API to ensure that it
# works correctly
#
from __future__ import print_function
import pytest
import logging
logger = logging.getLogger("test")
# test defaults
def doc(nt):
t = nt.getTable("nope")
assert t.getBoolean("b", None) is None
assert t.getNumber("n", None) is None
assert t.getString("s", None) is None
assert t.getBooleanArray("ba", None) is None
assert t.getNumberArray("na", None) is None
assert t.getStringArray("sa", None) is None
assert t.getValue("v", None) is None
assert t.getBoolean("b", True) is True
assert t.getNumber("n", 1) == 1
assert t.getString("s", "sss") == "sss"
assert t.getBooleanArray("ba", (True,)) == (True,)
assert t.getNumberArray("na", (1,)) == (1,)
assert t.getStringArray("sa", ("ss",)) == ("ss",)
assert t.getValue("v", "vvv") == "vvv"
def do(nt1, nt2, t):
t1 = nt1.getTable(t)
with nt2.expect_changes(8):
t1.putBoolean("bool", True)
t1.putNumber("number1", 1)
t1.putNumber("number2", 1.5)
t1.putString("string", "string")
t1.putString("unicode", "\xa9") # copyright symbol
t1.putBooleanArray("ba", (True, False))
t1.putNumberArray("na", (1, 2))
t1.putStringArray("sa", ("s", "t"))
logger.info("put is done")
t2 = nt2.getTable(t)
assert t2.getBoolean("bool", None) is True
assert t2.getNumber("number1", None) == 1
assert t2.getNumber("number2", None) == 1.5
assert t2.getString("string", None) == "string"
assert t2.getString("unicode", None) == "\xa9" # copyright symbol
assert t2.getBooleanArray("ba", None) == [True, False]
assert t2.getNumberArray("na", None) == [1, 2]
assert t2.getStringArray("sa", None) == ["s", "t"]
# Value testing
with nt2.expect_changes(6):
t1.putValue("v_b", False)
t1.putValue("v_n1", 2)
t1.putValue("v_n2", 2.5)
t1.putValue("v_s", "ssss")
t1.putValue("v_s2", "\xa9")
t1.putValue("v_v", 0)
print(t2.getKeys())
assert t2.getBoolean("v_b", None) is False
assert t2.getNumber("v_n1", None) == 2
assert t2.getNumber("v_n2", None) == 2.5
assert t2.getString("v_s", None) == "ssss"
assert t2.getString("v_s2", None) == "\xa9"
assert t2.getValue("v_v", None) == 0
# Ensure that updating values work!
with nt2.expect_changes(8):
t1.putBoolean("bool", False)
t1.putNumber("number1", 2)
t1.putNumber("number2", 2.5)
t1.putString("string", "sss")
t1.putString("unicode", "\u2122") # (tm)
t1.putBooleanArray("ba", (False, True, False))
t1.putNumberArray("na", (2, 1))
t1.putStringArray("sa", ("t", "s"))
t2 = nt2.getTable(t)
assert t2.getBoolean("bool", None) is False
assert t2.getNumber("number1", None) == 2
assert t2.getNumber("number2", None) == 2.5
assert t2.getString("string", None) == "sss"
assert t2.getString("unicode", None) == "\u2122"
assert t2.getBooleanArray("ba", None) == [False, True, False]
assert t2.getNumberArray("na", None) == [2, 1]
assert t2.getStringArray("sa", None) == ["t", "s"]
@pytest.mark.xfail(reason="ntcore is broken")
def test_basic(nt_live):
nt_server, nt_client = nt_live
# assert nt_server.isServer()
# assert not nt_client.isServer()
doc(nt_client)
doc(nt_server)
# server -> client
do(nt_server, nt_client, "server2client")
# client -> server
do(nt_client, nt_server, "client2server")
assert nt_client.isConnected()
assert nt_server.isConnected()
# def test_reconnect(nt_live):
# nt_server, nt_client = nt_live
# with nt_server.expect_changes(1):
# ct = nt_client.getTable("t")
# ct.putBoolean("foo", True)
# st = nt_server.getTable("t")
# assert st.getBoolean("foo", None) == True
# # Client disconnect testing
# nt_client.shutdown()
# logger.info("Shutdown the client")
# with nt_client.expect_changes(1):
# nt_client.start_test()
# ct = nt_client.getTable("t")
# assert ct.getBoolean("foo", None) == True
# # Server disconnect testing
# nt_server.shutdown()
# logger.info("Shutdown the server")
# # synchronization change: if the client doesn't touch the entry locally,
# # then it won't get transferred back to the server on reconnect. Touch
# # it here to ensure that it comes back
# ct.putBoolean("foo", True)
# with nt_server.expect_changes(1):
# nt_server.start_test()
# st = nt_server.getTable("t")
# assert st.getBoolean("foo", None) == True

View File

@@ -0,0 +1,71 @@
#
# Ensure that the NetworkTableEntry objects work
#
def test_entry_repr(nt):
e = nt.getEntry("/k1")
assert repr(e) == "<NetworkTableEntry '/k1'>"
def test_topic_repr(nt):
topic = nt.getIntegerTopic("/int")
assert repr(topic) == "<IntegerTopic '/int'>"
pub = topic.publish()
assert repr(pub) == "<IntegerPublisher '/int'>"
entry = topic.getEntry(0)
assert repr(entry) == "<IntegerEntry '/int'>"
generic_entry = topic.getGenericEntry()
assert repr(generic_entry) == "<GenericEntry '/int'>"
def test_entry_string(nt):
e = nt.getEntry("/k1")
assert e.getString(None) is None
e.setString("value")
assert e.getString(None) == "value"
assert e.getValue().value() == "value"
assert e.value == "value"
e.unpublish()
assert e.getString(None) is None
e.setString("value")
assert e.getString(None) == "value"
def test_entry_string_array(nt):
e = nt.getEntry("/k1")
assert e.getStringArray(None) is None
e.setStringArray(["value"])
assert e.getStringArray(None) == ["value"]
assert e.getValue().value() == ["value"]
assert e.value == ["value"]
e.unpublish()
assert e.getStringArray(None) is None
e.setStringArray(["value"])
assert e.getStringArray(None) == ["value"]
def test_entry_persistence(nt):
e = nt.getEntry("/k2")
for _ in range(2):
assert not e.isPersistent()
# persistent flag cannot be set unless the entry has a value
e.setString("value")
assert not e.isPersistent()
e.setPersistent()
assert e.isPersistent()
e.clearPersistent()
assert not e.isPersistent()
e.unpublish()
def test_entry_publish_empty_double_array(nt):
topic = nt.getDoubleArrayTopic("/Topic")
pub = topic.publish()
pub.set([])

View File

@@ -0,0 +1,176 @@
#
# These tests are leftover from the original pynetworktables tests
#
import pytest
@pytest.fixture(scope="function")
def table1(nt):
return nt.getTable("/test1")
@pytest.fixture(scope="function")
def table2(nt):
return nt.getTable("/test2")
def test_put_double(table1):
table1.putNumber("double", 42.42)
assert table1.getNumber("double", None) == 42.42
assert table1.getNumber("Non-Existant", 44.44) == 44.44
def test_put_boolean(table1):
table1.putBoolean("boolean", True)
assert table1.getBoolean("boolean", None) == True
assert table1.getBoolean("Non-Existant", False) == False
def test_put_string(table1):
table1.putString("String", "Test 1")
assert table1.getString("String", None) == "Test 1"
assert table1.getString("Non-Existant", "Test 3") == "Test 3"
def test_getvalue_overloads(table1):
table1.putValue("float", 35.5)
assert table1.getValue("float", None) == pytest.approx(35.5)
table1.putValue("integer", 950)
assert table1.getValue("integer", None) == pytest.approx(950)
table1.putValue("boolean", True)
assert table1.getValue("boolean", None) is True
def test_multi_data_type(table1):
table1.putNumber("double1", 1)
table1.putNumber("double2", 2)
table1.putNumber("double3", 3)
table1.putBoolean("bool1", False)
table1.putBoolean("bool2", True)
table1.putString("string1", "String 1")
table1.putString("string2", "String 2")
table1.putString("string3", "String 3")
assert table1.getNumber("double1", None) == 1
assert table1.getNumber("double2", None) == 2
assert table1.getNumber("double3", None) == 3
assert table1.getBoolean("bool1", None) == False
assert table1.getBoolean("bool2", None) == True
assert table1.getString("string1", None) == "String 1"
assert table1.getString("string2", None) == "String 2"
assert table1.getString("string3", None) == "String 3"
table1.putNumber("double1", 4)
table1.putNumber("double2", 5)
table1.putNumber("double3", 6)
table1.putBoolean("bool1", True)
table1.putBoolean("bool2", False)
table1.putString("string1", "String 4")
table1.putString("string2", "String 5")
table1.putString("string3", "String 6")
assert table1.getNumber("double1", None) == 4
assert table1.getNumber("double2", None) == 5
assert table1.getNumber("double3", None) == 6
assert table1.getBoolean("bool1", None) == True
assert table1.getBoolean("bool2", None) == False
assert table1.getString("string1", None) == "String 4"
assert table1.getString("string2", None) == "String 5"
assert table1.getString("string3", None) == "String 6"
def test_multi_table(table1, table2):
table1.putNumber("table1double", 1)
table1.putBoolean("table1boolean", True)
table1.putString("table1string", "Table 1")
assert table2.getNumber("table1double", None) == None
assert table2.getBoolean("table1boolean", None) == None
assert table2.getString("table1string", None) == None
table2.putNumber("table2double", 2)
table2.putBoolean("table2boolean", False)
table2.putString("table2string", "Table 2")
assert table1.getNumber("table2double", None) == None
assert table1.getBoolean("table2boolean", None) == None
assert table1.getString("table2string", None) == None
# def test_get_table(nt, table1, table2):
# assert nt.getTable("test1") is table1
# assert nt.getTable("test2") is table2
# assert nt.getTable("/test1") is table1
# assert nt.getTable("/test2") is table2
# assert nt.getTable("/test1/") is table1
# assert nt.getTable("/test1/").path == "/test1"
# assert table1 is not table2
# table3 = nt.getTable("/test3")
# assert table1 is not table3
# assert table2 is not table3
# def test_get_subtable(nt, table1):
# assert not table1.containsSubTable("test1")
# st1 = table1.getSubTable("test1")
# assert nt.getTable("/test1/test1") is st1
# assert table1.getSubTable("test1") is st1
# # weird, but true -- subtable only exists when key exists
# assert not table1.containsSubTable("test1")
# st1.putBoolean("hi", True)
# assert table1.containsSubTable("test1")
# assert table1.getSubTables() == ["test1"]
# assert st1.getSubTables() == []
def test_getkeys(table1):
assert table1.getKeys() == []
assert not table1.containsKey("hi")
assert "hi" not in table1
table1.putBoolean("hi", True)
assert table1.getKeys() == ["hi"]
assert table1.containsKey("hi")
assert "hi" in table1
def test_flags(table1):
table1.putBoolean("foo", True)
assert not table1.isPersistent("foo")
table1.setPersistent("foo")
assert table1.isPersistent("foo")
table1.clearPersistent("foo")
assert not table1.isPersistent("foo")
# def test_delete(table1):
# table1.putBoolean("foo", True)
# assert table1.getBoolean("foo", None) == True
# table1.delete("foo")
# assert table1.getBoolean("foo", None) == None
def test_different_type(table1):
assert table1.putBoolean("foo", True)
assert table1.getBoolean("foo", None) == True
assert not table1.putNumber("foo", 1)
assert table1.getBoolean("foo", None) == True

View File

@@ -0,0 +1,55 @@
import dataclasses
import ntcore
from wpiutil import wpistruct
@wpistruct.make_wpistruct
@dataclasses.dataclass
class MyStruct:
x: int
y: bool
z: wpistruct.double
def test_mystruct(nt: ntcore.NetworkTableInstance):
topic = nt.getStructTopic("mystruct", MyStruct)
pub = topic.publish()
sub = topic.subscribe(MyStruct(1, True, 2.0))
assert topic.getTypeString() == "struct:MyStruct"
default = MyStruct(6, False, 7.0)
pub.setDefault(default)
val = sub.get()
assert val == default
# val2 = MyStruct(0, False, 0)
# sub.getInto(val2)
# assert val2 == default
vals = sub.readQueue()
assert len(vals) == 1
assert vals[0].value == default
def test_mystruct_array(nt: ntcore.NetworkTableInstance):
topic = nt.getStructArrayTopic("mystruct", MyStruct)
pub = topic.publish()
sub = topic.subscribe([])
assert topic.getTypeString() == "struct:MyStruct[]"
default = MyStruct(8, True, 9.0)
pub.setDefault([default])
val = sub.get()
assert val == [default]
val2 = MyStruct(0, False, 0)
pub.set([val2])
atomicVal = sub.getAtomic()
assert atomicVal.value == [val2]
vals = sub.readQueue()
assert len(vals) == 1
assert vals[0].value == [val2]

View File

@@ -0,0 +1,153 @@
import pytest
from ntcore import NetworkTableInstance, NetworkTableType
from ntcore.util import ntproperty, ChooserControl
# def test_autoupdatevalue(nt):
# # tricksy: make sure that this works *before* initialization
# # of network tables happens!
# nt.shutdown()
# foo = nt.getGlobalAutoUpdateValue("/SmartDashboard/foo", True, True)
# assert foo.value == True
# assert foo.get() == True
# nt.startTestMode()
# assert foo.value == True
# assert foo.get() == True
# t = nt.getTable("/SmartDashboard")
# assert t.getBoolean("foo", None) == True
# t.putBoolean("foo", False)
# assert foo.value == False
def test_ntproperty(nt: NetworkTableInstance):
class Foo(object):
robotTime = ntproperty(
"/SmartDashboard/robotTime", 0.0, writeDefault=False, inst=nt
)
dsTime = ntproperty("/SmartDashboard/dsTime", 0.0, writeDefault=True, inst=nt)
testIntArray = ntproperty(
"/SmartDashboard/testIntArray", [1, 2, 3], writeDefault=True, inst=nt
)
testBoolArray = ntproperty(
"/SmartDashboard/testBoolArray", [True, False], writeDefault=True, inst=nt
)
testFloatArray = ntproperty(
"/SmartDashboard/testFloatArray",
[1.1, 1.2, 1.3],
writeDefault=True,
type=NetworkTableType.kFloatArray,
inst=nt,
)
f = Foo()
t = nt.getTable("/SmartDashboard")
assert f.robotTime == 0
assert t.getNumber("robotTime", None) == 0
f.robotTime = 2
assert t.getNumber("robotTime", None) == 2
t.putNumber("robotTime", 4)
assert f.robotTime == 4
assert f.testIntArray == [1, 2, 3]
f.testIntArray = [4, 5, 6]
assert f.testIntArray == [4, 5, 6]
assert f.testBoolArray == [True, False]
f.testBoolArray = [False, True]
assert f.testBoolArray == [False, True]
assert f.testFloatArray == [
pytest.approx(1.1),
pytest.approx(1.2),
pytest.approx(1.3),
]
f.testFloatArray = [4.1, 5.1, 6.1]
assert f.testFloatArray == [
pytest.approx(4.1),
pytest.approx(5.1),
pytest.approx(6.1),
]
def test_ntproperty_emptyarray(nt: NetworkTableInstance):
with pytest.raises(TypeError):
class Foo1(object):
testArray = ntproperty(
"/SmartDashboard/testArray", [], writeDefault=True, inst=nt
)
with pytest.raises(TypeError):
class Foo2(object):
testArray = ntproperty(
"/SmartDashboard/testArray", [], writeDefault=False, inst=nt
)
def test_ntproperty_multitest(nt: NetworkTableInstance):
"""
Checks to see that ntproperties still work between NT restarts
This is needed to ensure that ntproperty gets reset between
pyfrc tests
"""
class Foo(object):
robotTime = ntproperty(
"/SmartDashboard/robotTime", 0.0, writeDefault=False, inst=nt
)
dsTime = ntproperty("/SmartDashboard/dsTime", 0.0, writeDefault=True, inst=nt)
for i in range(3):
print("Iteration", i)
f = Foo()
t = nt.getTable("/SmartDashboard")
assert f.robotTime == 0
assert f.dsTime == 0
assert t.getNumber("robotTime", None) == 0
assert t.getNumber("dsTime", None) == 0
f.robotTime = 2
assert t.getNumber("robotTime", None) == 2
assert t.getNumber("dsTime", None) == 0
t.putNumber("robotTime", 4)
assert f.robotTime == 4
assert f.dsTime == 0
nt.stopLocal()
nt._reset()
nt.startLocal()
def test_chooser_control(nt: NetworkTableInstance):
c = ChooserControl("Autonomous Mode", inst=nt)
assert c.getChoices() == []
assert c.getSelected() is None
c.setSelected("foo")
assert c.getSelected() == "foo"
t = nt.getTable("/SmartDashboard/Autonomous Mode")
assert t.getString("selected", None) == "foo"
t.putStringArray("options", ("option1", "option2"))
assert c.getChoices() == ["option1", "option2"]

View File

@@ -0,0 +1,196 @@
import ntcore
import pytest
def test_value_bool():
v = ntcore.Value.makeBoolean(True)
assert v.getBoolean() == True
assert v.value() == True
def test_mkvalue_bool():
v = ntcore.Value.makeValue(True)
assert v.getBoolean() == True
assert v.value() == True
def test_bool_factory():
f = ntcore.Value.getFactoryByType(ntcore.NetworkTableType.kBoolean)
v = f(True)
assert v.getBoolean() == True
def test_value_int():
v = ntcore.Value.makeInteger(2)
assert v.getInteger() == 2
assert v.value() == 2
def test_mkvalue_int():
v = ntcore.Value.makeValue(2)
assert v.getInteger() == 2
assert v.value() == 2
def test_int_factory():
f = ntcore.Value.getFactoryByType(ntcore.NetworkTableType.kInteger)
v = f(2)
assert v.getInteger() == 2
def test_value_double():
v = ntcore.Value.makeDouble(2.5)
assert v.getDouble() == pytest.approx(2.5)
assert v.value() == pytest.approx(2.5)
def test_mkvalue_double():
v = ntcore.Value.makeValue(2.5)
assert v.getDouble() == pytest.approx(2.5)
assert v.value() == pytest.approx(2.5)
def test_double_factory():
f = ntcore.Value.getFactoryByType(ntcore.NetworkTableType.kDouble)
v = f(2.2)
assert v.getDouble() == pytest.approx(2.2)
def test_value_float():
v = ntcore.Value.makeFloat(2.5)
assert v.getFloat() == pytest.approx(2.5)
assert v.value() == pytest.approx(2.5)
def test_mkvalue_float():
pass # makeValue cannot create a float value
def test_float_factory():
f = ntcore.Value.getFactoryByType(ntcore.NetworkTableType.kFloat)
v = f(2.2)
assert v.getFloat() == pytest.approx(2.2)
def test_value_str():
v = ntcore.Value.makeString("s")
assert v.getString() == "s"
assert v.value() == "s"
def test_mkvalue_str():
v = ntcore.Value.makeValue("s")
assert v.getString() == "s"
assert v.value() == "s"
def test_str_factory():
f = ntcore.Value.getFactoryByType(ntcore.NetworkTableType.kString)
v = f("abc")
assert v.getString() == "abc"
def test_value_raw():
v = ntcore.Value.makeRaw(b"raw")
assert v.getRaw() == b"raw"
assert v.value() == b"raw"
def test_mkvalue_raw():
v = ntcore.Value.makeValue(b"raw")
assert v.getRaw() == b"raw"
assert v.value() == b"raw"
def test_raw_factory():
f = ntcore.Value.getFactoryByType(ntcore.NetworkTableType.kRaw)
v = f(b"raw")
assert v.getRaw() == b"raw"
def test_value_bool_list():
v = ntcore.Value.makeBooleanArray([True, False])
assert v.getBooleanArray() == [True, False]
assert v.value() == [True, False]
def test_mkvalue_bool_list():
v = ntcore.Value.makeValue([True, False])
assert v.getBooleanArray() == [True, False]
assert v.value() == [True, False]
def test_bool_list_factory():
f = ntcore.Value.getFactoryByType(ntcore.NetworkTableType.kBooleanArray)
v = f([True, False])
assert v.getBooleanArray() == [True, False]
def test_value_int_list():
v = ntcore.Value.makeIntegerArray([1, 2])
assert v.getIntegerArray() == [1, 2]
assert v.value() == [1, 2]
def test_mkvalue_int_list():
v = ntcore.Value.makeValue([1, 2])
assert v.getIntegerArray() == [1, 2]
assert v.value() == [1, 2]
def test_int_list_factory():
f = ntcore.Value.getFactoryByType(ntcore.NetworkTableType.kIntegerArray)
v = f([1, 2])
assert v.getIntegerArray() == [1, 2]
def test_value_double_list():
v = ntcore.Value.makeDoubleArray([1.1, 2.2])
assert v.getDoubleArray() == [pytest.approx(1.1), pytest.approx(2.2)]
assert v.value() == [pytest.approx(1.1), pytest.approx(2.2)]
def test_mkvalue_double_list():
v = ntcore.Value.makeValue([1.1, 2.2])
assert v.getDoubleArray() == [pytest.approx(1.1), pytest.approx(2.2)]
assert v.value() == [pytest.approx(1.1), pytest.approx(2.2)]
def test_double_list_factory():
f = ntcore.Value.getFactoryByType(ntcore.NetworkTableType.kDoubleArray)
v = f([1.1, 2.2])
assert v.getDoubleArray() == [pytest.approx(1.1), pytest.approx(2.2)]
def test_value_float_list():
v = ntcore.Value.makeFloatArray([1.1, 2.2])
assert v.getFloatArray() == [pytest.approx(1.1), pytest.approx(2.2)]
assert v.value() == [pytest.approx(1.1), pytest.approx(2.2)]
def test_mkvalue_float_list():
pass # not possible to use makeValue to make a float list
def test_float_list_factory():
f = ntcore.Value.getFactoryByType(ntcore.NetworkTableType.kFloatArray)
v = f([1.1, 2.2])
assert v.getFloatArray() == [pytest.approx(1.1), pytest.approx(2.2)]
def test_value_str_list():
v = ntcore.Value.makeStringArray(["a", "b"])
assert v.getStringArray() == ["a", "b"]
assert v.value() == ["a", "b"]
def test_mkvalue_str_list():
v = ntcore.Value.makeValue(["a", "b"])
assert v.getStringArray() == ["a", "b"]
assert v.value() == ["a", "b"]
def test_str_list_factory():
f = ntcore.Value.getFactoryByType(ntcore.NetworkTableType.kStringArray)
v = f(["a", "b"])
assert v.getStringArray() == ["a", "b"]