Skip to content

Commit ebfe199

Browse files
committed
Merge pull request #225 from tseaver/100_pct_branch_coverage
Get to 100% branch coverage
2 parents 00d456d + 03c740d commit ebfe199

File tree

7 files changed

+153
-18
lines changed

7 files changed

+153
-18
lines changed

gcloud/datastore/helpers.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ def get_protobuf_attribute_and_value(val):
6060
name, value = 'integer', long(val) # Always cast to a long.
6161
elif isinstance(val, basestring):
6262
name, value = 'string', val
63+
else:
64+
raise ValueError("Unknown protobuf attr type %s" % type(val))
6365

6466
return name + '_value', value
6567

gcloud/datastore/key.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ def from_protobuf(cls, pb, dataset=None):
6666
if element.HasField('id'):
6767
element_dict['id'] = element.id
6868

69-
elif element.HasField('name'):
69+
# This is safe: we expect proto objects returned will only have
70+
# one of `name` or `id` set.
71+
if element.HasField('name'):
7072
element_dict['name'] = element.name
7173

7274
path.append(element_dict)

gcloud/datastore/test_helpers.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ def test_unicode(self):
8383
self.assertEqual(name, 'string_value')
8484
self.assertEqual(value, u'str')
8585

86+
def test_object(self):
87+
self.assertRaises(ValueError, self._callFUT, object())
88+
8689

8790
class Test_get_value_from_protobuf(unittest2.TestCase):
8891

gcloud/datastore/test_key.py

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ def _makePB(self, dataset_id=None, namespace=None, path=()):
1919
pb.partition_id.namespace = namespace
2020
for elem in path:
2121
added = pb.path_element.add()
22-
if 'kind' in elem:
23-
added.kind = elem['kind']
22+
added.kind = elem['kind']
2423
if 'id' in elem:
2524
added.id = elem['id']
2625
if 'name' in elem:
@@ -101,9 +100,16 @@ def test_from_protobuf_w_path_in_pb(self):
101100
pb = self._makePB(_DATASET, _NAMESPACE)
102101
_PARENT = 'PARENT'
103102
_CHILD = 'CHILD'
103+
_GRANDCHILD = 'GRANDCHILD'
104104
_ID = 1234
105+
_ID2 = 5678
105106
_NAME = 'NAME'
106-
_PATH = [{'kind': _PARENT, 'name': _NAME}, {'kind': _CHILD, 'id': _ID}]
107+
_NAME2 = 'NAME2'
108+
_PATH = [
109+
{'kind': _PARENT, 'name': _NAME},
110+
{'kind': _CHILD, 'id': _ID},
111+
{'kind': _GRANDCHILD, 'id': _ID2, 'name': _NAME2},
112+
]
107113
pb = self._makePB(path=_PATH)
108114
key = self._getTargetClass().from_protobuf(pb)
109115
self.assertEqual(key.path(), _PATH)
@@ -120,6 +126,13 @@ def test_to_protobuf_defaults(self):
120126
self.assertEqual(elem.name, '')
121127
self.assertEqual(elem.id, 0)
122128

129+
def test_to_protobuf_w_explicit_dataset_empty_id(self):
130+
from gcloud.datastore.dataset import Dataset
131+
dataset = Dataset('')
132+
key = self._makeOne(dataset)
133+
pb = key.to_protobuf()
134+
self.assertEqual(pb.partition_id.dataset_id, '')
135+
123136
def test_to_protobuf_w_explicit_dataset_no_prefix(self):
124137
from gcloud.datastore.dataset import Dataset
125138
_DATASET = 'DATASET'
@@ -155,14 +168,22 @@ def test_to_protobuf_w_explicit_path(self):
155168
_CHILD = 'CHILD'
156169
_ID = 1234
157170
_NAME = 'NAME'
158-
_PATH = [{'kind': _PARENT, 'name': _NAME}, {'kind': _CHILD, 'id': _ID}]
171+
_PATH = [
172+
{'kind': _PARENT, 'name': _NAME},
173+
{'kind': _CHILD, 'id': _ID},
174+
{},
175+
]
159176
key = self._makeOne(path=_PATH)
160177
pb = key.to_protobuf()
161178
elems = list(pb.path_element)
179+
self.assertEqual(len(elems), len(_PATH))
162180
self.assertEqual(elems[0].kind, _PARENT)
163181
self.assertEqual(elems[0].name, _NAME)
164182
self.assertEqual(elems[1].kind, _CHILD)
165183
self.assertEqual(elems[1].id, _ID)
184+
self.assertEqual(elems[2].kind, '')
185+
self.assertEqual(elems[2].name, '')
186+
self.assertEqual(elems[2].id, 0)
166187

167188
def test_from_path_empty(self):
168189
key = self._getTargetClass().from_path()
@@ -262,6 +283,15 @@ def test_path_setter(self):
262283
self.assertEqual(after.namespace(), _NAMESPACE)
263284
self.assertEqual(after.path(), _PATH)
264285

286+
def test_kind_getter_empty_path(self):
287+
from gcloud.datastore.dataset import Dataset
288+
_DATASET = 'DATASET'
289+
_NAMESPACE = 'NAMESPACE'
290+
dataset = Dataset(_DATASET)
291+
key = self._makeOne(dataset, _NAMESPACE)
292+
key._path = () # edge case
293+
self.assertEqual(key.kind(), None)
294+
265295
def test_kind_setter(self):
266296
from gcloud.datastore.dataset import Dataset
267297
_DATASET = 'DATASET'
@@ -279,22 +309,14 @@ def test_kind_setter(self):
279309
self.assertEqual(after.namespace(), _NAMESPACE)
280310
self.assertEqual(after.path(), [{'kind': _KIND_AFTER, 'name': _NAME}])
281311

282-
def test_name_setter(self):
312+
def test_id_getter_empty_path(self):
283313
from gcloud.datastore.dataset import Dataset
284314
_DATASET = 'DATASET'
285315
_NAMESPACE = 'NAMESPACE'
286-
_KIND = 'KIND'
287-
_NAME_BEFORE = 'NAME_BEFORE'
288-
_NAME_AFTER = 'NAME_AFTER'
289-
_PATH = [{'kind': _KIND, 'name': _NAME_BEFORE}]
290316
dataset = Dataset(_DATASET)
291-
key = self._makeOne(dataset, _NAMESPACE, _PATH)
292-
after = key.name(_NAME_AFTER)
293-
self.assertFalse(after is key)
294-
self.assertTrue(isinstance(after, self._getTargetClass()))
295-
self.assertTrue(after.dataset() is dataset)
296-
self.assertEqual(after.namespace(), _NAMESPACE)
297-
self.assertEqual(after.path(), [{'kind': _KIND, 'name': _NAME_AFTER}])
317+
key = self._makeOne(dataset, _NAMESPACE)
318+
key._path = () # edge case
319+
self.assertEqual(key.id(), None)
298320

299321
def test_id_setter(self):
300322
from gcloud.datastore.dataset import Dataset
@@ -313,6 +335,32 @@ def test_id_setter(self):
313335
self.assertEqual(after.namespace(), _NAMESPACE)
314336
self.assertEqual(after.path(), [{'kind': _KIND, 'id': _ID_AFTER}])
315337

338+
def test_name_getter_empty_path(self):
339+
from gcloud.datastore.dataset import Dataset
340+
_DATASET = 'DATASET'
341+
_NAMESPACE = 'NAMESPACE'
342+
dataset = Dataset(_DATASET)
343+
key = self._makeOne(dataset, _NAMESPACE)
344+
key._path = () # edge case
345+
self.assertEqual(key.name(), None)
346+
347+
def test_name_setter(self):
348+
from gcloud.datastore.dataset import Dataset
349+
_DATASET = 'DATASET'
350+
_NAMESPACE = 'NAMESPACE'
351+
_KIND = 'KIND'
352+
_NAME_BEFORE = 'NAME_BEFORE'
353+
_NAME_AFTER = 'NAME_AFTER'
354+
_PATH = [{'kind': _KIND, 'name': _NAME_BEFORE}]
355+
dataset = Dataset(_DATASET)
356+
key = self._makeOne(dataset, _NAMESPACE, _PATH)
357+
after = key.name(_NAME_AFTER)
358+
self.assertFalse(after is key)
359+
self.assertTrue(isinstance(after, self._getTargetClass()))
360+
self.assertTrue(after.dataset() is dataset)
361+
self.assertEqual(after.namespace(), _NAMESPACE)
362+
self.assertEqual(after.path(), [{'kind': _KIND, 'name': _NAME_AFTER}])
363+
316364
def test_id_or_name_no_name_or_id(self):
317365
key = self._makeOne()
318366
self.assertEqual(key.id_or_name(), None)

gcloud/datastore/test_query.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,26 @@ def test_ancestor_w_non_key_non_list(self):
7676
# XXX s.b. ValueError
7777
self.assertRaises(TypeError, query.ancestor, object())
7878

79+
def test_ancester_wo_existing_ancestor_query_w_key_and_propfilter(self):
80+
from gcloud.datastore.key import Key
81+
_KIND = 'KIND'
82+
_ID = 123
83+
_NAME = 'NAME'
84+
key = Key(path=[{'kind': _KIND, 'id': _ID}])
85+
query = self._makeOne().filter('name =', _NAME)
86+
after = query.ancestor(key)
87+
self.assertFalse(after is query)
88+
self.assertTrue(isinstance(after, self._getTargetClass()))
89+
q_pb = after.to_protobuf()
90+
self.assertEqual(q_pb.filter.composite_filter.operator, 1) # AND
91+
n_pb, f_pb, = list(q_pb.filter.composite_filter.filter)
92+
p_pb = n_pb.property_filter
93+
self.assertEqual(p_pb.property.name, 'name')
94+
self.assertEqual(p_pb.value.string_value, _NAME)
95+
p_pb = f_pb.property_filter
96+
self.assertEqual(p_pb.property.name, '__key__')
97+
self.assertEqual(p_pb.value.key_value, key.to_protobuf())
98+
7999
def test_ancester_wo_existing_ancestor_query_w_key(self):
80100
from gcloud.datastore.key import Key
81101
_KIND = 'KIND'
@@ -108,7 +128,7 @@ def test_ancester_wo_existing_ancestor_query_w_list(self):
108128
self.assertEqual(p_pb.property.name, '__key__')
109129
self.assertEqual(p_pb.value.key_value, key.to_protobuf())
110130

111-
def test_ancester_clears_existing_ancestor_query(self):
131+
def test_ancester_clears_existing_ancestor_query_w_only(self):
112132
_KIND = 'KIND'
113133
_ID = 123
114134
query = self._makeOne()
@@ -119,6 +139,21 @@ def test_ancester_clears_existing_ancestor_query(self):
119139
q_pb = after.to_protobuf()
120140
self.assertEqual(list(q_pb.filter.composite_filter.filter), [])
121141

142+
def test_ancester_clears_existing_ancestor_query_w_others(self):
143+
_KIND = 'KIND'
144+
_ID = 123
145+
_NAME = 'NAME'
146+
query = self._makeOne().filter('name =', _NAME)
147+
between = query.ancestor([_KIND, _ID])
148+
after = between.ancestor(None)
149+
self.assertFalse(after is query)
150+
self.assertTrue(isinstance(after, self._getTargetClass()))
151+
q_pb = after.to_protobuf()
152+
n_pb, = list(q_pb.filter.composite_filter.filter)
153+
p_pb = n_pb.property_filter
154+
self.assertEqual(p_pb.property.name, 'name')
155+
self.assertEqual(p_pb.value.string_value, _NAME)
156+
122157
def test_kind_setter_wo_existing(self):
123158
from gcloud.datastore.dataset import Dataset
124159
_DATASET = 'DATASET'

gcloud/storage/test_acl.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,14 @@ def test___iter___non_empty_w_roles(self):
153153
self.assertEqual(list(acl),
154154
[{'entity': '%s-%s' % (TYPE, ID), 'role': ROLE}])
155155

156+
def test___iter___non_empty_w_empty_role(self):
157+
TYPE = 'type'
158+
ID = 'id'
159+
acl = self._makeOne()
160+
entity = acl.entity(TYPE, ID)
161+
entity.grant('')
162+
self.assertEqual(list(acl), [])
163+
156164
def test_entity_from_dict_allUsers(self):
157165
ROLE = 'role'
158166
acl = self._makeOne()

gcloud/storage/test_connection.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,41 @@ def test_create_bucket_ok(self):
459459
def test_delete_bucket_defaults_miss(self):
460460
_deleted_keys = []
461461

462+
class _Key(object):
463+
pass
464+
465+
class _Bucket(object):
466+
467+
def __init__(self, name):
468+
self._name = name
469+
self.path = '/b/' + name
470+
471+
PROJECT = 'project'
472+
KEY = 'key'
473+
conn = self._makeOne(PROJECT)
474+
URI = '/'.join([conn.API_BASE_URL,
475+
'storage',
476+
conn.API_VERSION,
477+
'b',
478+
'key?project=%s' % PROJECT,
479+
])
480+
http = conn._http = Http({'status': '200',
481+
'content-type': 'application/json',
482+
},
483+
'{}')
484+
485+
def _new_bucket(name):
486+
return _Bucket(name)
487+
488+
conn.new_bucket = _new_bucket
489+
self.assertEqual(conn.delete_bucket(KEY), True)
490+
self.assertEqual(_deleted_keys, [])
491+
self.assertEqual(http._called_with['method'], 'DELETE')
492+
self.assertEqual(http._called_with['uri'], URI)
493+
494+
def test_delete_bucket_force_True(self):
495+
_deleted_keys = []
496+
462497
class _Key(object):
463498

464499
def __init__(self, name):
@@ -475,6 +510,7 @@ def __init__(self, name):
475510

476511
def __iter__(self):
477512
return iter([_Key(x) for x in ('foo', 'bar')])
513+
478514
PROJECT = 'project'
479515
KEY = 'key'
480516
conn = self._makeOne(PROJECT)
@@ -491,6 +527,7 @@ def __iter__(self):
491527

492528
def _new_bucket(name):
493529
return _Bucket(name)
530+
494531
conn.new_bucket = _new_bucket
495532
self.assertEqual(conn.delete_bucket(KEY, True), True)
496533
self.assertEqual(_deleted_keys, ['foo', 'bar'])

0 commit comments

Comments
 (0)