13
13
# limitations under the License.
15
15
"""Test the cursor module."""
21
22
sys.path[0:0] = [""]
23
24
from nose.plugins.skip import SkipTest
25
26
from bson.code import Code
27
from bson.son import SON
26
28
from pymongo import (ASCENDING,
28
from pymongo.cursor import Cursor
29
30
from pymongo.database import Database
30
31
from pymongo.errors import (InvalidOperation,
33
from test import version
32
34
from test.test_connection import get_connection
33
from test import version
36
37
class TestCursor(unittest.TestCase):
271
272
self.assertRaises(TypeError, db.test.find().sort, [], ASCENDING)
272
273
self.assertRaises(TypeError, db.test.find().sort,
273
274
[("hello", DESCENDING)], DESCENDING)
274
self.assertRaises(TypeError, db.test.find().sort, "hello", "world")
465
465
self.assertEqual(type(MyClass()), type(cursor[0]))
467
467
# Just test attributes
468
cursor = self.db.test.find(skip=1,
468
cursor = self.db.test.find({"x": re.compile("^hello.*")},
494
496
self.assertEqual(cursor._Cursor__query_flags,
495
497
cursor2._Cursor__query_flags)
499
# Shallow copies can so can mutate
500
cursor2 = copy.copy(cursor)
501
cursor2._Cursor__fields['cursor2'] = False
502
self.assertTrue('cursor2' in cursor._Cursor__fields)
504
# Deepcopies and shouldn't mutate
505
cursor3 = copy.deepcopy(cursor)
506
cursor3._Cursor__fields['cursor3'] = False
507
self.assertFalse('cursor3' in cursor._Cursor__fields)
509
cursor4 = cursor.clone()
510
cursor4._Cursor__fields['cursor4'] = False
511
self.assertFalse('cursor4' in cursor._Cursor__fields)
513
# Test memo when deepcopying queries
514
query = {"hello": "world"}
515
query["reflexive"] = query
516
cursor = self.db.test.find(query)
518
cursor2 = copy.deepcopy(cursor)
520
self.assertNotEqual(id(cursor._Cursor__spec),
521
id(cursor2._Cursor__spec))
522
self.assertEqual(id(cursor2._Cursor__spec['reflexive']),
523
id(cursor2._Cursor__spec))
524
self.assertEqual(len(cursor2._Cursor__spec), 2)
526
# Ensure hints are cloned as the correct type
527
cursor = self.db.test.find().hint([('z', 1), ("a", 1)])
528
cursor2 = copy.deepcopy(cursor)
529
self.assertTrue(isinstance(cursor2._Cursor__hint, SON))
530
self.assertEqual(cursor._Cursor__hint, cursor2._Cursor__hint)
497
532
def test_add_remove_option(self):
498
533
cursor = self.db.test.find()
499
534
self.assertEqual(0, cursor._Cursor__query_options())
635
670
def test_count_with_limit_and_skip(self):
636
671
if not version.at_least(self.db.connection, (1, 1, 4, -1)):
672
raise SkipTest("count with limit / skip requires MongoDB >= 1.1.4")
639
674
def check_len(cursor, length):
640
675
self.assertEqual(len(list(cursor)), cursor.count(True))
682
717
cursor = db.test.find(tailable=True)
684
db.test.insert({"x": 1})
719
db.test.insert({"x": 1}, safe=True)
686
721
for doc in cursor:
688
723
self.assertEqual(1, doc["x"])
689
724
self.assertEqual(1, count)
691
db.test.insert({"x": 2})
726
db.test.insert({"x": 2}, safe=True)
693
728
for doc in cursor:
695
730
self.assertEqual(2, doc["x"])
696
731
self.assertEqual(1, count)
698
db.test.insert({"x": 3})
733
db.test.insert({"x": 3}, safe=True)
700
735
for doc in cursor:
708
743
def test_distinct(self):
709
744
if not version.at_least(self.db.connection, (1, 1, 3, 1)):
745
raise SkipTest("distinct with query requires MongoDB >= 1.1.3")
712
747
self.db.drop_collection("test")
737
772
def test_max_scan(self):
738
773
if not version.at_least(self.db.connection, (1, 5, 1)):
774
raise SkipTest("maxScan requires MongoDB >= 1.5.1")
741
776
self.db.drop_collection("test")
742
777
for _ in range(100):
750
785
def test_with_statement(self):
751
786
if sys.version_info < (2, 6):
787
raise SkipTest("With statement requires Python >= 2.6")
754
789
self.db.drop_collection("test")
755
790
for _ in range(100):