@@ -1017,6 +1017,202 @@ def test_thread_join_raises_exception(self) -> None:
10171017 thread .join ()
10181018
10191019
1020+ class TestClientQueryHelpers :
1021+ """Test Client query_arrow / query_pandas / query_polars / query_pylist."""
1022+
1023+ @staticmethod
1024+ def _sample_table () -> pa .Table :
1025+ return pa .table ({"id" : [1 , 2 , 3 ], "name" : ["a" , "b" , "c" ]})
1026+
1027+ @patch ("spicepy._client._SpiceFlight" )
1028+ @patch ("spicepy._client._Cert" )
1029+ def test_query_arrow_returns_table (
1030+ self ,
1031+ mock_cert_class : MagicMock ,
1032+ mock_flight_class : MagicMock ,
1033+ ) -> None :
1034+ mock_cert = MagicMock ()
1035+ mock_cert .tls_root_certs = b"cert"
1036+ mock_cert_class .return_value = mock_cert
1037+
1038+ table = self ._sample_table ()
1039+ mock_reader = MagicMock ()
1040+ mock_reader .read_all .return_value = table
1041+ mock_flight = MagicMock ()
1042+ mock_flight .query .return_value = mock_reader
1043+ mock_flight_class .return_value = mock_flight
1044+
1045+ client = Client ()
1046+ result = client .query_arrow ("SELECT * FROM t" )
1047+
1048+ assert result is table
1049+ mock_flight .query .assert_called_once_with ("SELECT * FROM t" )
1050+
1051+ @patch ("spicepy._client._SpiceFlight" )
1052+ @patch ("spicepy._client._Cert" )
1053+ def test_query_arrow_passes_timeout (
1054+ self ,
1055+ mock_cert_class : MagicMock ,
1056+ mock_flight_class : MagicMock ,
1057+ ) -> None :
1058+ mock_cert = MagicMock ()
1059+ mock_cert .tls_root_certs = b"cert"
1060+ mock_cert_class .return_value = mock_cert
1061+
1062+ mock_reader = MagicMock ()
1063+ mock_reader .read_all .return_value = self ._sample_table ()
1064+ mock_flight = MagicMock ()
1065+ mock_flight .query .return_value = mock_reader
1066+ mock_flight_class .return_value = mock_flight
1067+
1068+ client = Client ()
1069+ client .query_arrow ("SELECT 1" , timeout = 30 )
1070+
1071+ mock_flight .query .assert_called_once_with ("SELECT 1" , timeout = 30 )
1072+
1073+ @patch ("spicepy._client._SpiceFlight" )
1074+ @patch ("spicepy._client._Cert" )
1075+ @patch ("spicepy._client._ADBCClient" )
1076+ def test_query_arrow_routes_params_to_adbc (
1077+ self ,
1078+ mock_adbc_class : MagicMock ,
1079+ mock_cert_class : MagicMock ,
1080+ mock_flight_class : MagicMock ,
1081+ ) -> None :
1082+ mock_cert = MagicMock ()
1083+ mock_cert .tls_root_certs = b"cert"
1084+ mock_cert_class .return_value = mock_cert
1085+
1086+ table = self ._sample_table ()
1087+ adbc_reader = MagicMock ()
1088+ adbc_reader .read_all .return_value = table
1089+ mock_adbc = MagicMock ()
1090+ mock_adbc .query_with_params .return_value = adbc_reader
1091+ mock_adbc_class .return_value = mock_adbc
1092+
1093+ flight_instance = MagicMock ()
1094+ mock_flight_class .return_value = flight_instance
1095+
1096+ client = Client ()
1097+ result = client .query_arrow ("SELECT * FROM t WHERE id = $1" , params = [1 ])
1098+
1099+ assert result is table
1100+ mock_adbc .query_with_params .assert_called_once_with (
1101+ "SELECT * FROM t WHERE id = $1" , [1 ]
1102+ )
1103+ flight_instance .query .assert_not_called ()
1104+
1105+ @patch ("spicepy._client._SpiceFlight" )
1106+ @patch ("spicepy._client._Cert" )
1107+ def test_query_pandas_returns_dataframe (
1108+ self ,
1109+ mock_cert_class : MagicMock ,
1110+ mock_flight_class : MagicMock ,
1111+ ) -> None :
1112+ import pandas as pd
1113+
1114+ mock_cert = MagicMock ()
1115+ mock_cert .tls_root_certs = b"cert"
1116+ mock_cert_class .return_value = mock_cert
1117+
1118+ mock_reader = MagicMock ()
1119+ mock_reader .read_all .return_value = self ._sample_table ()
1120+ mock_flight = MagicMock ()
1121+ mock_flight .query .return_value = mock_reader
1122+ mock_flight_class .return_value = mock_flight
1123+
1124+ client = Client ()
1125+ df = client .query_pandas ("SELECT * FROM t" )
1126+
1127+ assert isinstance (df , pd .DataFrame )
1128+ assert list (df .columns ) == ["id" , "name" ]
1129+ assert len (df ) == 3
1130+
1131+ @patch ("spicepy._client._SpiceFlight" )
1132+ @patch ("spicepy._client._Cert" )
1133+ def test_query_pylist_returns_row_dicts (
1134+ self ,
1135+ mock_cert_class : MagicMock ,
1136+ mock_flight_class : MagicMock ,
1137+ ) -> None :
1138+ mock_cert = MagicMock ()
1139+ mock_cert .tls_root_certs = b"cert"
1140+ mock_cert_class .return_value = mock_cert
1141+
1142+ mock_reader = MagicMock ()
1143+ mock_reader .read_all .return_value = self ._sample_table ()
1144+ mock_flight = MagicMock ()
1145+ mock_flight .query .return_value = mock_reader
1146+ mock_flight_class .return_value = mock_flight
1147+
1148+ client = Client ()
1149+ rows = client .query_pylist ("SELECT * FROM t" )
1150+
1151+ assert rows == [
1152+ {"id" : 1 , "name" : "a" },
1153+ {"id" : 2 , "name" : "b" },
1154+ {"id" : 3 , "name" : "c" },
1155+ ]
1156+
1157+ @patch ("spicepy._client._SpiceFlight" )
1158+ @patch ("spicepy._client._Cert" )
1159+ def test_query_polars_returns_dataframe (
1160+ self ,
1161+ mock_cert_class : MagicMock ,
1162+ mock_flight_class : MagicMock ,
1163+ ) -> None :
1164+ pl = pytest .importorskip ("polars" )
1165+
1166+ mock_cert = MagicMock ()
1167+ mock_cert .tls_root_certs = b"cert"
1168+ mock_cert_class .return_value = mock_cert
1169+
1170+ mock_reader = MagicMock ()
1171+ mock_reader .read_all .return_value = self ._sample_table ()
1172+ mock_flight = MagicMock ()
1173+ mock_flight .query .return_value = mock_reader
1174+ mock_flight_class .return_value = mock_flight
1175+
1176+ client = Client ()
1177+ df = client .query_polars ("SELECT * FROM t" )
1178+
1179+ assert isinstance (df , pl .DataFrame )
1180+ assert df .columns == ["id" , "name" ]
1181+ assert df .height == 3
1182+
1183+ @patch ("spicepy._client._SpiceFlight" )
1184+ @patch ("spicepy._client._Cert" )
1185+ def test_query_polars_missing_raises_importerror (
1186+ self ,
1187+ mock_cert_class : MagicMock ,
1188+ mock_flight_class : MagicMock ,
1189+ ) -> None :
1190+ mock_cert = MagicMock ()
1191+ mock_cert .tls_root_certs = b"cert"
1192+ mock_cert_class .return_value = mock_cert
1193+
1194+ mock_reader = MagicMock ()
1195+ mock_reader .read_all .return_value = self ._sample_table ()
1196+ mock_flight = MagicMock ()
1197+ mock_flight .query .return_value = mock_reader
1198+ mock_flight_class .return_value = mock_flight
1199+
1200+ client = Client ()
1201+
1202+ import builtins
1203+
1204+ real_import = builtins .__import__
1205+
1206+ def fake_import (name , * args , ** kwargs ):
1207+ if name == "polars" :
1208+ raise ImportError ("No module named 'polars'" )
1209+ return real_import (name , * args , ** kwargs )
1210+
1211+ with patch ("builtins.__import__" , side_effect = fake_import ):
1212+ with pytest .raises (ImportError , match = "polars is not installed" ):
1213+ client .query_polars ("SELECT 1" )
1214+
1215+
10201216class TestIsMacosArm64 :
10211217 """Test is_macos_arm64 function."""
10221218
0 commit comments