@@ -361,19 +361,21 @@ def test_entity_to_protobuf_w_variable_meanings():
361361 entity = Entity ()
362362 name = "quux"
363363 entity [name ] = values = [1 , 20 , 300 ]
364- meaning = 9
365- entity ._meanings [name ] = ([None , meaning , None ], values )
364+ root_meaning = 31
365+ sub_meaning = 9
366+ entity ._meanings [name ] = ((root_meaning , [None , sub_meaning , None ]), values )
366367 entity_pb = entity_to_protobuf (entity )
367368
368369 # Construct the expected protobuf.
369370 expected_pb = entity_pb2 .Entity ()
370371 value_pb = _new_value_pb (expected_pb , name )
372+ value_pb .meaning = root_meaning
371373 value0 = value_pb .array_value .values .add ()
372374 value0 .integer_value = values [0 ]
373375 # The only array entry with a meaning is the middle one.
374376 value1 = value_pb .array_value .values .add ()
375377 value1 .integer_value = values [1 ]
376- value1 .meaning = meaning
378+ value1 .meaning = sub_meaning
377379 value2 = value_pb .array_value .values .add ()
378380 value2 .integer_value = values [2 ]
379381
@@ -1179,7 +1181,46 @@ def test__get_meaning_w_array_value():
11791181 sub_value_pb2 .string_value = "bye"
11801182
11811183 result = _get_meaning (value_pb , is_list = True )
1182- assert meaning == result
1184+ # should preserve sub-value meanings as list
1185+ assert (None , [meaning , meaning ]) == result
1186+
1187+
1188+ def test__get_meaning_w_array_value_root_meaning ():
1189+ from google .cloud .datastore_v1 .types import entity as entity_pb2
1190+ from google .cloud .datastore .helpers import _get_meaning
1191+
1192+ value_pb = entity_pb2 .Value ()
1193+ meaning = 9
1194+ value_pb .meaning = meaning
1195+ sub_value_pb1 = value_pb ._pb .array_value .values .add ()
1196+ sub_value_pb2 = value_pb ._pb .array_value .values .add ()
1197+
1198+ sub_value_pb1 .string_value = "hi"
1199+ sub_value_pb2 .string_value = "bye"
1200+
1201+ result = _get_meaning (value_pb , is_list = True )
1202+ # should preserve sub-value meanings as list
1203+ assert (meaning , None ) == result
1204+
1205+
1206+ def test__get_meaning_w_array_value_root_and_sub_meanings ():
1207+ from google .cloud .datastore_v1 .types import entity as entity_pb2
1208+ from google .cloud .datastore .helpers import _get_meaning
1209+
1210+ value_pb = entity_pb2 .Value ()
1211+ root_meaning = 9
1212+ sub_meaning = 3
1213+ value_pb .meaning = root_meaning
1214+ sub_value_pb1 = value_pb ._pb .array_value .values .add ()
1215+ sub_value_pb2 = value_pb ._pb .array_value .values .add ()
1216+
1217+ sub_value_pb1 .meaning = sub_value_pb2 .meaning = sub_meaning
1218+ sub_value_pb1 .string_value = "hi"
1219+ sub_value_pb2 .string_value = "bye"
1220+
1221+ result = _get_meaning (value_pb , is_list = True )
1222+ # should preserve sub-value meanings as list
1223+ assert (root_meaning , [sub_meaning , sub_meaning ]) == result
11831224
11841225
11851226def test__get_meaning_w_array_value_multiple_meanings ():
@@ -1198,7 +1239,7 @@ def test__get_meaning_w_array_value_multiple_meanings():
11981239 sub_value_pb2 .string_value = "bye"
11991240
12001241 result = _get_meaning (value_pb , is_list = True )
1201- assert result == [meaning1 , meaning2 ]
1242+ assert result == ( None , [meaning1 , meaning2 ])
12021243
12031244
12041245def test__get_meaning_w_array_value_meaning_partially_unset ():
@@ -1215,7 +1256,102 @@ def test__get_meaning_w_array_value_meaning_partially_unset():
12151256 sub_value_pb2 .string_value = "bye"
12161257
12171258 result = _get_meaning (value_pb , is_list = True )
1218- assert result == [meaning1 , None ]
1259+ assert result == (None , [meaning1 , None ])
1260+
1261+
1262+ def test__get_meaning_w_array_value_meaning_fully_unset ():
1263+ from google .cloud .datastore_v1 .types import entity as entity_pb2
1264+ from google .cloud .datastore .helpers import _get_meaning
1265+
1266+ value_pb = entity_pb2 .Value ()
1267+ sub_value_pb1 = value_pb ._pb .array_value .values .add ()
1268+ sub_value_pb2 = value_pb ._pb .array_value .values .add ()
1269+
1270+ sub_value_pb1 .string_value = "hi"
1271+ sub_value_pb2 .string_value = "bye"
1272+
1273+ result = _get_meaning (value_pb , is_list = True )
1274+ assert result is None
1275+
1276+
1277+ @pytest .mark .parametrize ("orig_root_meaning" , [0 , 1 ])
1278+ @pytest .mark .parametrize ("orig_sub_meaning" , [0 , 1 ])
1279+ def test__set_pb_meaning_w_array_value_fully_unset (orig_root_meaning , orig_sub_meaning ):
1280+ """
1281+ call _set_pb_meaning_from_entity with meaning=None data.
1282+ Should not touch proto's meaning field
1283+ """
1284+ from google .cloud .datastore_v1 .types import entity as entity_pb2
1285+ from google .cloud .datastore .helpers import _set_pb_meaning_from_entity
1286+ from google .cloud .datastore .entity import Entity
1287+
1288+ orig_pb = entity_pb2 .Entity ()
1289+ value_pb = orig_pb ._pb .properties .get_or_create ("value" )
1290+ value_pb .meaning = orig_root_meaning
1291+ sub_value_pb1 = value_pb .array_value .values .add ()
1292+ sub_value_pb1 .meaning = orig_sub_meaning
1293+
1294+ entity = Entity (key = "key" )
1295+ entity ._meanings = {"value" : ((None , None ), None )}
1296+ _set_pb_meaning_from_entity (entity , "value" , None , value_pb , is_list = True )
1297+ assert value_pb .meaning == orig_root_meaning
1298+ assert value_pb .array_value .values [0 ].meaning == orig_sub_meaning
1299+
1300+
1301+ @pytest .mark .parametrize ("orig_meaning" , [0 , 1 ])
1302+ def test__set_pb_meaning_w_value_unset (orig_meaning ):
1303+ """
1304+ call _set_pb_meaning_from_entity with meaning=None data.
1305+ Should not touch proto's meaning field
1306+ """
1307+ from google .cloud .datastore_v1 .types import entity as entity_pb2
1308+ from google .cloud .datastore .helpers import _set_pb_meaning_from_entity
1309+ from google .cloud .datastore .entity import Entity
1310+
1311+ orig_pb = entity_pb2 .Entity ()
1312+ value_pb = orig_pb ._pb .properties .get_or_create ("value" )
1313+ value_pb .meaning = orig_meaning
1314+
1315+ entity = Entity (key = "key" )
1316+ entity ._meanings = {"value" : (None , None )}
1317+ _set_pb_meaning_from_entity (entity , "value" , None , value_pb , is_list = False )
1318+ assert value_pb .meaning == orig_meaning
1319+
1320+
1321+ def test__array_w_meaning_end_to_end ():
1322+ """
1323+ Test proto->entity->proto with an array with a meaning field
1324+ """
1325+ from google .cloud .datastore_v1 .types import entity as entity_pb2
1326+ from google .cloud .datastore .helpers import entity_from_protobuf
1327+ from google .cloud .datastore .helpers import entity_to_protobuf
1328+
1329+ orig_pb = entity_pb2 .Entity ()
1330+ value_pb = orig_pb ._pb .properties .get_or_create ("value" )
1331+ value_pb .meaning = 31
1332+ sub_value_pb1 = value_pb .array_value .values .add ()
1333+ sub_value_pb1 .double_value = 1
1334+ sub_value_pb1 .meaning = 1
1335+ sub_value_pb2 = value_pb .array_value .values .add ()
1336+ sub_value_pb2 .double_value = 2
1337+ sub_value_pb3 = value_pb .array_value .values .add ()
1338+ sub_value_pb3 .double_value = 3
1339+ sub_value_pb3 .meaning = 3
1340+ # convert to entity
1341+ entity = entity_from_protobuf (orig_pb ._pb )
1342+ assert entity ._meanings ["value" ][0 ] == (31 , [1 , None , 3 ])
1343+ assert entity ._meanings ["value" ][1 ] == [1 , 2 , 3 ]
1344+ # convert back to pb
1345+ output_entity_pb = entity_to_protobuf (entity )
1346+ final_pb = output_entity_pb ._pb .properties ["value" ]
1347+ assert final_pb .meaning == 31
1348+ assert len (final_pb .array_value .values ) == 3
1349+ assert final_pb .array_value .values [0 ].meaning == 1
1350+ assert final_pb .array_value .values [0 ].double_value == 1
1351+ assert final_pb .array_value .values [1 ].meaning == 0
1352+ assert final_pb .array_value .values [1 ].double_value == 2
1353+ assert final_pb .array_value .values [2 ].meaning == 3
1354+ assert final_pb .array_value .values [2 ].double_value == 3
12191355
12201356
12211357def _make_geopoint (* args , ** kwargs ):
0 commit comments