# Copyright 2014 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import unittest2 class Test__new_value_pb(unittest2.TestCase): def _callFUT(self, entity_pb, name): from gcloud.datastore.helpers import _new_value_pb return _new_value_pb(entity_pb, name) def test_it(self): from gcloud.datastore._generated import entity_pb2 entity_pb = entity_pb2.Entity() name = 'foo' result = self._callFUT(entity_pb, name) self.assertTrue(isinstance(result, entity_pb2.Value)) self.assertEqual(len(entity_pb.properties), 1) self.assertEqual(entity_pb.properties[name], result) class Test__property_tuples(unittest2.TestCase): def _callFUT(self, entity_pb): from gcloud.datastore.helpers import _property_tuples return _property_tuples(entity_pb) def test_it(self): import types from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.helpers import _new_value_pb entity_pb = entity_pb2.Entity() name1 = 'foo' name2 = 'bar' val_pb1 = _new_value_pb(entity_pb, name1) val_pb2 = _new_value_pb(entity_pb, name2) result = self._callFUT(entity_pb) self.assertTrue(isinstance(result, types.GeneratorType)) self.assertEqual(sorted(result), sorted([(name1, val_pb1), (name2, val_pb2)])) class Test_entity_from_protobuf(unittest2.TestCase): def _callFUT(self, val): from gcloud.datastore.helpers import entity_from_protobuf return entity_from_protobuf(val) def test_it(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.helpers import _new_value_pb _PROJECT = 'PROJECT' _KIND = 'KIND' _ID = 1234 entity_pb = entity_pb2.Entity() entity_pb.key.partition_id.project_id = _PROJECT entity_pb.key.path.add(kind=_KIND, id=_ID) value_pb = _new_value_pb(entity_pb, 'foo') value_pb.string_value = 'Foo' unindexed_val_pb = _new_value_pb(entity_pb, 'bar') unindexed_val_pb.integer_value = 10 unindexed_val_pb.exclude_from_indexes = True array_val_pb1 = _new_value_pb(entity_pb, 'baz') array_pb1 = array_val_pb1.array_value.values unindexed_array_val_pb = array_pb1.add() unindexed_array_val_pb.integer_value = 11 unindexed_array_val_pb.exclude_from_indexes = True array_val_pb2 = _new_value_pb(entity_pb, 'qux') array_pb2 = array_val_pb2.array_value.values indexed_array_val_pb = array_pb2.add() indexed_array_val_pb.integer_value = 12 entity = self._callFUT(entity_pb) self.assertEqual(entity.kind, _KIND) self.assertEqual(entity.exclude_from_indexes, frozenset(['bar', 'baz'])) entity_props = dict(entity) self.assertEqual(entity_props, {'foo': 'Foo', 'bar': 10, 'baz': [11], 'qux': [12]}) # Also check the key. key = entity.key self.assertEqual(key.project, _PROJECT) self.assertEqual(key.namespace, None) self.assertEqual(key.kind, _KIND) self.assertEqual(key.id, _ID) def test_mismatched_value_indexed(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.helpers import _new_value_pb _PROJECT = 'PROJECT' _KIND = 'KIND' _ID = 1234 entity_pb = entity_pb2.Entity() entity_pb.key.partition_id.project_id = _PROJECT entity_pb.key.path.add(kind=_KIND, id=_ID) array_val_pb = _new_value_pb(entity_pb, 'baz') array_pb = array_val_pb.array_value.values unindexed_value_pb1 = array_pb.add() unindexed_value_pb1.integer_value = 10 unindexed_value_pb1.exclude_from_indexes = True unindexed_value_pb2 = array_pb.add() unindexed_value_pb2.integer_value = 11 with self.assertRaises(ValueError): self._callFUT(entity_pb) def test_entity_no_key(self): from gcloud.datastore._generated import entity_pb2 entity_pb = entity_pb2.Entity() entity = self._callFUT(entity_pb) self.assertEqual(entity.key, None) self.assertEqual(dict(entity), {}) def test_entity_with_meaning(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.helpers import _new_value_pb entity_pb = entity_pb2.Entity() name = 'hello' value_pb = _new_value_pb(entity_pb, name) value_pb.meaning = meaning = 9 value_pb.string_value = val = u'something' entity = self._callFUT(entity_pb) self.assertEqual(entity.key, None) self.assertEqual(dict(entity), {name: val}) self.assertEqual(entity._meanings, {name: (meaning, val)}) def test_nested_entity_no_key(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.helpers import _new_value_pb PROJECT = 'FOO' KIND = 'KIND' INSIDE_NAME = 'IFOO' OUTSIDE_NAME = 'OBAR' INSIDE_VALUE = 1337 entity_inside = entity_pb2.Entity() inside_val_pb = _new_value_pb(entity_inside, INSIDE_NAME) inside_val_pb.integer_value = INSIDE_VALUE entity_pb = entity_pb2.Entity() entity_pb.key.partition_id.project_id = PROJECT element = entity_pb.key.path.add() element.kind = KIND outside_val_pb = _new_value_pb(entity_pb, OUTSIDE_NAME) outside_val_pb.entity_value.CopyFrom(entity_inside) entity = self._callFUT(entity_pb) self.assertEqual(entity.key.project, PROJECT) self.assertEqual(entity.key.flat_path, (KIND,)) self.assertEqual(len(entity), 1) inside_entity = entity[OUTSIDE_NAME] self.assertEqual(inside_entity.key, None) self.assertEqual(len(inside_entity), 1) self.assertEqual(inside_entity[INSIDE_NAME], INSIDE_VALUE) class Test_entity_to_protobuf(unittest2.TestCase): def _callFUT(self, entity): from gcloud.datastore.helpers import entity_to_protobuf return entity_to_protobuf(entity) def _compareEntityProto(self, entity_pb1, entity_pb2): from gcloud.datastore.helpers import _property_tuples self.assertEqual(entity_pb1.key, entity_pb2.key) value_list1 = sorted(_property_tuples(entity_pb1)) value_list2 = sorted(_property_tuples(entity_pb2)) self.assertEqual(len(value_list1), len(value_list2)) for pair1, pair2 in zip(value_list1, value_list2): name1, val1 = pair1 name2, val2 = pair2 self.assertEqual(name1, name2) if val1.HasField('entity_value'): # Message field (Entity) self.assertEqual(val1.meaning, val2.meaning) self._compareEntityProto(val1.entity_value, val2.entity_value) else: self.assertEqual(val1, val2) def test_empty(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.entity import Entity entity = Entity() entity_pb = self._callFUT(entity) self._compareEntityProto(entity_pb, entity_pb2.Entity()) def test_key_only(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.entity import Entity from gcloud.datastore.key import Key kind, name = 'PATH', 'NAME' project = 'PROJECT' key = Key(kind, name, project=project) entity = Entity(key=key) entity_pb = self._callFUT(entity) expected_pb = entity_pb2.Entity() expected_pb.key.partition_id.project_id = project path_elt = expected_pb.key.path.add() path_elt.kind = kind path_elt.name = name self._compareEntityProto(entity_pb, expected_pb) def test_simple_fields(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.entity import Entity from gcloud.datastore.helpers import _new_value_pb entity = Entity() name1 = 'foo' entity[name1] = value1 = 42 name2 = 'bar' entity[name2] = value2 = u'some-string' entity_pb = self._callFUT(entity) expected_pb = entity_pb2.Entity() val_pb1 = _new_value_pb(expected_pb, name1) val_pb1.integer_value = value1 val_pb2 = _new_value_pb(expected_pb, name2) val_pb2.string_value = value2 self._compareEntityProto(entity_pb, expected_pb) def test_with_empty_list(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.entity import Entity entity = Entity() entity['foo'] = [] entity_pb = self._callFUT(entity) self._compareEntityProto(entity_pb, entity_pb2.Entity()) def test_inverts_to_protobuf(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.helpers import _new_value_pb from gcloud.datastore.helpers import entity_from_protobuf original_pb = entity_pb2.Entity() # Add a key. original_pb.key.partition_id.project_id = project = 'PROJECT' elem1 = original_pb.key.path.add() elem1.kind = 'Family' elem1.id = 1234 elem2 = original_pb.key.path.add() elem2.kind = 'King' elem2.name = 'Spades' # Add an integer property. val_pb1 = _new_value_pb(original_pb, 'foo') val_pb1.integer_value = 1337 val_pb1.exclude_from_indexes = True # Add a string property. val_pb2 = _new_value_pb(original_pb, 'bar') val_pb2.string_value = u'hello' # Add a nested (entity) property. val_pb3 = _new_value_pb(original_pb, 'entity-baz') sub_pb = entity_pb2.Entity() sub_val_pb1 = _new_value_pb(sub_pb, 'x') sub_val_pb1.double_value = 3.14 sub_val_pb2 = _new_value_pb(sub_pb, 'y') sub_val_pb2.double_value = 2.718281828 val_pb3.meaning = 9 val_pb3.entity_value.CopyFrom(sub_pb) # Add a list property. val_pb4 = _new_value_pb(original_pb, 'list-quux') array_val1 = val_pb4.array_value.values.add() array_val1.exclude_from_indexes = False array_val1.meaning = meaning = 22 array_val1.blob_value = b'\xe2\x98\x83' array_val2 = val_pb4.array_value.values.add() array_val2.exclude_from_indexes = False array_val2.meaning = meaning array_val2.blob_value = b'\xe2\x98\x85' # Convert to the user-space Entity. entity = entity_from_protobuf(original_pb) # Convert the user-space Entity back to a protobuf. new_pb = self._callFUT(entity) # NOTE: entity_to_protobuf() strips the project so we "cheat". new_pb.key.partition_id.project_id = project self._compareEntityProto(original_pb, new_pb) def test_meaning_with_change(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.entity import Entity from gcloud.datastore.helpers import _new_value_pb entity = Entity() name = 'foo' entity[name] = value = 42 entity._meanings[name] = (9, 1337) entity_pb = self._callFUT(entity) expected_pb = entity_pb2.Entity() value_pb = _new_value_pb(expected_pb, name) value_pb.integer_value = value # NOTE: No meaning is used since the value differs from the # value stored. self._compareEntityProto(entity_pb, expected_pb) def test_variable_meanings(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.entity import Entity from gcloud.datastore.helpers import _new_value_pb entity = Entity() name = 'quux' entity[name] = values = [1, 20, 300] meaning = 9 entity._meanings[name] = ([None, meaning, None], values) entity_pb = self._callFUT(entity) # Construct the expected protobuf. expected_pb = entity_pb2.Entity() value_pb = _new_value_pb(expected_pb, name) value0 = value_pb.array_value.values.add() value0.integer_value = values[0] # The only array entry with a meaning is the middle one. value1 = value_pb.array_value.values.add() value1.integer_value = values[1] value1.meaning = meaning value2 = value_pb.array_value.values.add() value2.integer_value = values[2] self._compareEntityProto(entity_pb, expected_pb) class Test_key_from_protobuf(unittest2.TestCase): def _callFUT(self, val): from gcloud.datastore.helpers import key_from_protobuf return key_from_protobuf(val) def _makePB(self, project=None, namespace=None, path=()): from gcloud.datastore._generated import entity_pb2 pb = entity_pb2.Key() if project is not None: pb.partition_id.project_id = project if namespace is not None: pb.partition_id.namespace_id = namespace for elem in path: added = pb.path.add() added.kind = elem['kind'] if 'id' in elem: added.id = elem['id'] if 'name' in elem: added.name = elem['name'] return pb def test_wo_namespace_in_pb(self): _PROJECT = 'PROJECT' pb = self._makePB(path=[{'kind': 'KIND'}], project=_PROJECT) key = self._callFUT(pb) self.assertEqual(key.project, _PROJECT) self.assertEqual(key.namespace, None) def test_w_namespace_in_pb(self): _PROJECT = 'PROJECT' _NAMESPACE = 'NAMESPACE' pb = self._makePB(path=[{'kind': 'KIND'}], namespace=_NAMESPACE, project=_PROJECT) key = self._callFUT(pb) self.assertEqual(key.project, _PROJECT) self.assertEqual(key.namespace, _NAMESPACE) def test_w_nested_path_in_pb(self): _PATH = [ {'kind': 'PARENT', 'name': 'NAME'}, {'kind': 'CHILD', 'id': 1234}, {'kind': 'GRANDCHILD', 'id': 5678}, ] pb = self._makePB(path=_PATH, project='PROJECT') key = self._callFUT(pb) self.assertEqual(key.path, _PATH) def test_w_nothing_in_pb(self): pb = self._makePB() self.assertRaises(ValueError, self._callFUT, pb) class Test__pb_attr_value(unittest2.TestCase): def _callFUT(self, val): from gcloud.datastore.helpers import _pb_attr_value return _pb_attr_value(val) def test_datetime_naive(self): import calendar import datetime from gcloud._helpers import UTC micros = 4375 naive = datetime.datetime(2014, 9, 16, 10, 19, 32, micros) # No zone. utc = datetime.datetime(2014, 9, 16, 10, 19, 32, micros, UTC) name, value = self._callFUT(naive) self.assertEqual(name, 'timestamp_value') self.assertEqual(value.seconds, calendar.timegm(utc.timetuple())) self.assertEqual(value.nanos, 1000 * micros) def test_datetime_w_zone(self): import calendar import datetime from gcloud._helpers import UTC micros = 4375 utc = datetime.datetime(2014, 9, 16, 10, 19, 32, micros, UTC) name, value = self._callFUT(utc) self.assertEqual(name, 'timestamp_value') self.assertEqual(value.seconds, calendar.timegm(utc.timetuple())) self.assertEqual(value.nanos, 1000 * micros) def test_key(self): from gcloud.datastore.key import Key key = Key('PATH', 1234, project='PROJECT') name, value = self._callFUT(key) self.assertEqual(name, 'key_value') self.assertEqual(value, key.to_protobuf()) def test_bool(self): name, value = self._callFUT(False) self.assertEqual(name, 'boolean_value') self.assertEqual(value, False) def test_float(self): name, value = self._callFUT(3.1415926) self.assertEqual(name, 'double_value') self.assertEqual(value, 3.1415926) def test_int(self): name, value = self._callFUT(42) self.assertEqual(name, 'integer_value') self.assertEqual(value, 42) def test_long(self): must_be_long = (1 << 63) - 1 name, value = self._callFUT(must_be_long) self.assertEqual(name, 'integer_value') self.assertEqual(value, must_be_long) def test_native_str(self): import six name, value = self._callFUT('str') if six.PY2: self.assertEqual(name, 'blob_value') else: # pragma: NO COVER Python 3 self.assertEqual(name, 'string_value') self.assertEqual(value, 'str') def test_bytes(self): name, value = self._callFUT(b'bytes') self.assertEqual(name, 'blob_value') self.assertEqual(value, b'bytes') def test_unicode(self): name, value = self._callFUT(u'str') self.assertEqual(name, 'string_value') self.assertEqual(value, u'str') def test_entity(self): from gcloud.datastore.entity import Entity entity = Entity() name, value = self._callFUT(entity) self.assertEqual(name, 'entity_value') self.assertTrue(value is entity) def test_array(self): values = ['a', 0, 3.14] name, value = self._callFUT(values) self.assertEqual(name, 'array_value') self.assertTrue(value is values) def test_geo_point(self): from google.type import latlng_pb2 from gcloud.datastore.helpers import GeoPoint lat = 42.42 lng = 99.0007 geo_pt = GeoPoint(latitude=lat, longitude=lng) geo_pt_pb = latlng_pb2.LatLng(latitude=lat, longitude=lng) name, value = self._callFUT(geo_pt) self.assertEqual(name, 'geo_point_value') self.assertEqual(value, geo_pt_pb) def test_null(self): from google.protobuf import struct_pb2 name, value = self._callFUT(None) self.assertEqual(name, 'null_value') self.assertEqual(value, struct_pb2.NULL_VALUE) def test_object(self): self.assertRaises(ValueError, self._callFUT, object()) class Test__get_value_from_value_pb(unittest2.TestCase): def _callFUT(self, pb): from gcloud.datastore.helpers import _get_value_from_value_pb return _get_value_from_value_pb(pb) def _makePB(self, attr_name, value): from gcloud.datastore._generated import entity_pb2 pb = entity_pb2.Value() setattr(pb, attr_name, value) return pb def test_datetime(self): import calendar import datetime from gcloud._helpers import UTC from gcloud.datastore._generated import entity_pb2 micros = 4375 utc = datetime.datetime(2014, 9, 16, 10, 19, 32, micros, UTC) pb = entity_pb2.Value() pb.timestamp_value.seconds = calendar.timegm(utc.timetuple()) pb.timestamp_value.nanos = 1000 * micros self.assertEqual(self._callFUT(pb), utc) def test_key(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.key import Key pb = entity_pb2.Value() expected = Key('KIND', 1234, project='PROJECT').to_protobuf() pb.key_value.CopyFrom(expected) found = self._callFUT(pb) self.assertEqual(found.to_protobuf(), expected) def test_bool(self): pb = self._makePB('boolean_value', False) self.assertEqual(self._callFUT(pb), False) def test_float(self): pb = self._makePB('double_value', 3.1415926) self.assertEqual(self._callFUT(pb), 3.1415926) def test_int(self): pb = self._makePB('integer_value', 42) self.assertEqual(self._callFUT(pb), 42) def test_bytes(self): pb = self._makePB('blob_value', b'str') self.assertEqual(self._callFUT(pb), b'str') def test_unicode(self): pb = self._makePB('string_value', u'str') self.assertEqual(self._callFUT(pb), u'str') def test_entity(self): from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.entity import Entity from gcloud.datastore.helpers import _new_value_pb pb = entity_pb2.Value() entity_pb = pb.entity_value entity_pb.key.path.add(kind='KIND') entity_pb.key.partition_id.project_id = 'PROJECT' value_pb = _new_value_pb(entity_pb, 'foo') value_pb.string_value = 'Foo' entity = self._callFUT(pb) self.assertTrue(isinstance(entity, Entity)) self.assertEqual(entity['foo'], 'Foo') def test_array(self): from gcloud.datastore._generated import entity_pb2 pb = entity_pb2.Value() array_pb = pb.array_value.values item_pb = array_pb.add() item_pb.string_value = 'Foo' item_pb = array_pb.add() item_pb.string_value = 'Bar' items = self._callFUT(pb) self.assertEqual(items, ['Foo', 'Bar']) def test_geo_point(self): from google.type import latlng_pb2 from gcloud.datastore._generated import entity_pb2 from gcloud.datastore.helpers import GeoPoint lat = -3.14 lng = 13.37 geo_pt_pb = latlng_pb2.LatLng(latitude=lat, longitude=lng) pb = entity_pb2.Value(geo_point_value=geo_pt_pb) result = self._callFUT(pb) self.assertIsInstance(result, GeoPoint) self.assertEqual(result.latitude, lat) self.assertEqual(result.longitude, lng) def test_null(self): from google.protobuf import struct_pb2 from gcloud.datastore._generated import entity_pb2 pb = entity_pb2.Value(null_value=struct_pb2.NULL_VALUE) result = self._callFUT(pb) self.assertIsNone(result) def test_unknown(self): from gcloud.datastore._generated import entity_pb2 pb = entity_pb2.Value() with self.assertRaises(ValueError): self._callFUT(pb) class Test_set_protobuf_value(unittest2.TestCase): def _callFUT(self, value_pb, val): from gcloud.datastore.helpers import _set_protobuf_value return _set_protobuf_value(value_pb, val) def _makePB(self): from gcloud.datastore._generated import entity_pb2 return entity_pb2.Value() def test_datetime(self): import calendar import datetime from gcloud._helpers import UTC pb = self._makePB() micros = 4375 utc = datetime.datetime(2014, 9, 16, 10, 19, 32, micros, UTC) self._callFUT(pb, utc) value = pb.timestamp_value self.assertEqual(value.seconds, calendar.timegm(utc.timetuple())) self.assertEqual(value.nanos, 1000 * micros) def test_key(self): from gcloud.datastore.key import Key pb = self._makePB() key = Key('KIND', 1234, project='PROJECT') self._callFUT(pb, key) value = pb.key_value self.assertEqual(value, key.to_protobuf()) def test_none(self): pb = self._makePB() self._callFUT(pb, None) self.assertEqual(pb.WhichOneof('value_type'), 'null_value') def test_bool(self): pb = self._makePB() self._callFUT(pb, False) value = pb.boolean_value self.assertEqual(value, False) def test_float(self): pb = self._makePB() self._callFUT(pb, 3.1415926) value = pb.double_value self.assertEqual(value, 3.1415926) def test_int(self): pb = self._makePB() self._callFUT(pb, 42) value = pb.integer_value self.assertEqual(value, 42) def test_long(self): pb = self._makePB() must_be_long = (1 << 63) - 1 self._callFUT(pb, must_be_long) value = pb.integer_value self.assertEqual(value, must_be_long) def test_native_str(self): import six pb = self._makePB() self._callFUT(pb, 'str') if six.PY2: value = pb.blob_value else: # pragma: NO COVER Python 3 value = pb.string_value self.assertEqual(value, 'str') def test_bytes(self): pb = self._makePB() self._callFUT(pb, b'str') value = pb.blob_value self.assertEqual(value, b'str') def test_unicode(self): pb = self._makePB() self._callFUT(pb, u'str') value = pb.string_value self.assertEqual(value, u'str') def test_entity_empty_wo_key(self): from gcloud.datastore.entity import Entity from gcloud.datastore.helpers import _property_tuples pb = self._makePB() entity = Entity() self._callFUT(pb, entity) value = pb.entity_value self.assertEqual(value.key.SerializeToString(), b'') self.assertEqual(len(list(_property_tuples(value))), 0) def test_entity_w_key(self): from gcloud.datastore.entity import Entity from gcloud.datastore.helpers import _property_tuples from gcloud.datastore.key import Key name = 'foo' value = u'Foo' pb = self._makePB() key = Key('KIND', 123, project='PROJECT') entity = Entity(key=key) entity[name] = value self._callFUT(pb, entity) entity_pb = pb.entity_value self.assertEqual(entity_pb.key, key.to_protobuf()) prop_dict = dict(_property_tuples(entity_pb)) self.assertEqual(len(prop_dict), 1) self.assertEqual(list(prop_dict.keys()), [name]) self.assertEqual(prop_dict[name].string_value, value) def test_array(self): pb = self._makePB() values = [u'a', 0, 3.14] self._callFUT(pb, values) marshalled = pb.array_value.values self.assertEqual(len(marshalled), len(values)) self.assertEqual(marshalled[0].string_value, values[0]) self.assertEqual(marshalled[1].integer_value, values[1]) self.assertEqual(marshalled[2].double_value, values[2]) def test_geo_point(self): from google.type import latlng_pb2 from gcloud.datastore.helpers import GeoPoint pb = self._makePB() lat = 9.11 lng = 3.337 geo_pt = GeoPoint(latitude=lat, longitude=lng) geo_pt_pb = latlng_pb2.LatLng(latitude=lat, longitude=lng) self._callFUT(pb, geo_pt) self.assertEqual(pb.geo_point_value, geo_pt_pb) class Test__get_meaning(unittest2.TestCase): def _callFUT(self, *args, **kwargs): from gcloud.datastore.helpers import _get_meaning return _get_meaning(*args, **kwargs) def test_no_meaning(self): from gcloud.datastore._generated import entity_pb2 value_pb = entity_pb2.Value() result = self._callFUT(value_pb) self.assertEqual(result, None) def test_single(self): from gcloud.datastore._generated import entity_pb2 value_pb = entity_pb2.Value() value_pb.meaning = meaning = 22 value_pb.string_value = u'hi' result = self._callFUT(value_pb) self.assertEqual(meaning, result) def test_empty_array_value(self): from gcloud.datastore._generated import entity_pb2 value_pb = entity_pb2.Value() value_pb.array_value.values.add() value_pb.array_value.values.pop() result = self._callFUT(value_pb, is_list=True) self.assertEqual(None, result) def test_array_value(self): from gcloud.datastore._generated import entity_pb2 value_pb = entity_pb2.Value() meaning = 9 sub_value_pb1 = value_pb.array_value.values.add() sub_value_pb2 = value_pb.array_value.values.add() sub_value_pb1.meaning = sub_value_pb2.meaning = meaning sub_value_pb1.string_value = u'hi' sub_value_pb2.string_value = u'bye' result = self._callFUT(value_pb, is_list=True) self.assertEqual(meaning, result) def test_array_value_multiple_meanings(self): from gcloud.datastore._generated import entity_pb2 value_pb = entity_pb2.Value() meaning1 = 9 meaning2 = 10 sub_value_pb1 = value_pb.array_value.values.add() sub_value_pb2 = value_pb.array_value.values.add() sub_value_pb1.meaning = meaning1 sub_value_pb2.meaning = meaning2 sub_value_pb1.string_value = u'hi' sub_value_pb2.string_value = u'bye' result = self._callFUT(value_pb, is_list=True) self.assertEqual(result, [meaning1, meaning2]) def test_array_value_meaning_partially_unset(self): from gcloud.datastore._generated import entity_pb2 value_pb = entity_pb2.Value() meaning1 = 9 sub_value_pb1 = value_pb.array_value.values.add() sub_value_pb2 = value_pb.array_value.values.add() sub_value_pb1.meaning = meaning1 sub_value_pb1.string_value = u'hi' sub_value_pb2.string_value = u'bye' result = self._callFUT(value_pb, is_list=True) self.assertEqual(result, [meaning1, None]) class TestGeoPoint(unittest2.TestCase): def _getTargetClass(self): from gcloud.datastore.helpers import GeoPoint return GeoPoint def _makeOne(self, *args, **kwargs): return self._getTargetClass()(*args, **kwargs) def test_constructor(self): lat = 81.2 lng = 359.9999 geo_pt = self._makeOne(lat, lng) self.assertEqual(geo_pt.latitude, lat) self.assertEqual(geo_pt.longitude, lng) def test_to_protobuf(self): from google.type import latlng_pb2 lat = 0.0001 lng = 20.03 geo_pt = self._makeOne(lat, lng) result = geo_pt.to_protobuf() geo_pt_pb = latlng_pb2.LatLng(latitude=lat, longitude=lng) self.assertEqual(result, geo_pt_pb) def test___eq__(self): lat = 0.0001 lng = 20.03 geo_pt1 = self._makeOne(lat, lng) geo_pt2 = self._makeOne(lat, lng) self.assertEqual(geo_pt1, geo_pt2) def test___eq__type_differ(self): lat = 0.0001 lng = 20.03 geo_pt1 = self._makeOne(lat, lng) geo_pt2 = object() self.assertNotEqual(geo_pt1, geo_pt2) def test___ne__same_value(self): lat = 0.0001 lng = 20.03 geo_pt1 = self._makeOne(lat, lng) geo_pt2 = self._makeOne(lat, lng) comparison_val = (geo_pt1 != geo_pt2) self.assertFalse(comparison_val) def test___ne__(self): geo_pt1 = self._makeOne(0.0, 1.0) geo_pt2 = self._makeOne(2.0, 3.0) self.assertNotEqual(geo_pt1, geo_pt2)