Skip to content

Commit b8b05f9

Browse files
committed
Additional tests of fundamental Queryable behaviour.
1 parent ff5e480 commit b8b05f9

File tree

2 files changed

+47
-6
lines changed

2 files changed

+47
-6
lines changed

marrow/mongo/core/trait/queryable.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,6 @@ def _prepare_aggregate(cls, *args, **kw):
184184
if 'projection' in options:
185185
stages.append({'$project': options.pop('projection')})
186186

187-
if 'skip' in options:
188-
stages.append({'$skip': options.pop('skip')})
189-
190187
return cls, collection, stages, options
191188

192189
@classmethod
@@ -250,8 +247,10 @@ def find_in_sequence(cls, field, order, *args, **kw):
250247
**kw
251248
)
252249

253-
if tuple(collection.database.client.server_info()['versionArray'][:2]) < (3, 4): # noqa
254-
raise RuntimeError("Queryable.find_in_sequence only works against MongoDB server versions 3.4 or newer.")
250+
if __debug__: # noqa
251+
# This "foot shot avoidance" check requires a server round-trip, potentially, so we only do this in dev.
252+
if tuple(collection.database.client.server_info()['versionArray'][:2]) < (3, 4): # pragma: no cover
253+
raise RuntimeError("Queryable.find_in_sequence only works against MongoDB server versions 3.4 or newer.")
255254

256255
return collection.aggregate(stages, **options)
257256

test/trait/test_queryable.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44

55
import pytest
66
from bson import ObjectId
7+
from pymongo.cursor import CursorType
78
from pymongo.errors import WriteError
89

9-
from marrow.mongo import Field, Index, U
10+
from marrow.mongo import Index, U
1011
from marrow.mongo.field import Integer, String
1112
from marrow.mongo.trait import Queryable
1213

@@ -39,6 +40,47 @@ class Sample(Queryable):
3940
return Sample
4041

4142

43+
44+
class TestQueryableCore(object):
45+
def test_prepare_find_cursor_type_explicit(self, Sample):
46+
cls, collection, query, options = Sample._prepare_find(cursor_type=CursorType.TAILABLE)
47+
assert options['cursor_type'] == CursorType.TAILABLE
48+
49+
def test_prepare_find_cursor_conflict(self, Sample):
50+
with pytest.raises(TypeError):
51+
Sample._prepare_find(cursor_type=CursorType.TAILABLE, tail=True)
52+
53+
with pytest.raises(TypeError):
54+
Sample._prepare_find(cursor_type=CursorType.TAILABLE, await=True)
55+
56+
with pytest.raises(TypeError):
57+
Sample._prepare_find(cursor_type=CursorType.TAILABLE, tail=True, await=True)
58+
59+
def test_prepare_find_cursor_type_tail(self, Sample):
60+
cls, collection, query, options = Sample._prepare_find(tail=True)
61+
assert options['cursor_type'] == CursorType.TAILABLE_AWAIT
62+
63+
def test_prepare_find_cursor_type_tail_not_await(self, Sample):
64+
cls, collection, query, options = Sample._prepare_find(tail=True, await=False)
65+
assert options['cursor_type'] == CursorType.TAILABLE
66+
67+
def test_prepare_find_cursor_type_await_conflict(self, Sample):
68+
with pytest.raises(TypeError):
69+
Sample._prepare_find(await=False)
70+
71+
def test_prepare_find_max_time_modifier(self, Sample):
72+
cls, collection, query, options = Sample._prepare_find(max_time_ms=1000)
73+
assert options['modifiers'] == {'$maxTimeMS': 1000}
74+
75+
def test_prepare_aggregate_skip_limit(self, Sample):
76+
cls, collection, stages, options = Sample._prepare_aggregate(skip=10, limit=10)
77+
78+
assert stages == [
79+
{'$skip': 10},
80+
{'$limit': 10},
81+
]
82+
83+
4284
class TestQueryableTrait(object):
4385
def test_find(self, Sample):
4486
rs = Sample.find()

0 commit comments

Comments
 (0)