@@ -361,19 +361,21 @@ def test_entity_to_protobuf_w_variable_meanings():
361
361
entity = Entity ()
362
362
name = "quux"
363
363
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 )
366
367
entity_pb = entity_to_protobuf (entity )
367
368
368
369
# Construct the expected protobuf.
369
370
expected_pb = entity_pb2 .Entity ()
370
371
value_pb = _new_value_pb (expected_pb , name )
372
+ value_pb .meaning = root_meaning
371
373
value0 = value_pb .array_value .values .add ()
372
374
value0 .integer_value = values [0 ]
373
375
# The only array entry with a meaning is the middle one.
374
376
value1 = value_pb .array_value .values .add ()
375
377
value1 .integer_value = values [1 ]
376
- value1 .meaning = meaning
378
+ value1 .meaning = sub_meaning
377
379
value2 = value_pb .array_value .values .add ()
378
380
value2 .integer_value = values [2 ]
379
381
@@ -1179,7 +1181,46 @@ def test__get_meaning_w_array_value():
1179
1181
sub_value_pb2 .string_value = "bye"
1180
1182
1181
1183
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
1183
1224
1184
1225
1185
1226
def test__get_meaning_w_array_value_multiple_meanings ():
@@ -1198,7 +1239,7 @@ def test__get_meaning_w_array_value_multiple_meanings():
1198
1239
sub_value_pb2 .string_value = "bye"
1199
1240
1200
1241
result = _get_meaning (value_pb , is_list = True )
1201
- assert result == [meaning1 , meaning2 ]
1242
+ assert result == ( None , [meaning1 , meaning2 ])
1202
1243
1203
1244
1204
1245
def test__get_meaning_w_array_value_meaning_partially_unset ():
@@ -1215,7 +1256,102 @@ def test__get_meaning_w_array_value_meaning_partially_unset():
1215
1256
sub_value_pb2 .string_value = "bye"
1216
1257
1217
1258
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
1219
1355
1220
1356
1221
1357
def _make_geopoint (* args , ** kwargs ):
0 commit comments