mongo/jstests/core/crud_api.js

738 lines
27 KiB
JavaScript

// Cannot implicitly shard accessed collections because of following errmsg: A single
// update/delete on a sharded collection must contain an exact match on _id or contain the shard
// key.
//
// @tags: [
// assumes_unsharded_collection,
// assumes_write_concern_unchanged,
// requires_fastcount,
// ]
(function() {
"use strict";
load("jstests/aggregation/extras/utils.js"); // For arrayEq.
var crudAPISpecTests = function crudAPISpecTests() {
"use strict";
// Get the colllection
var coll = db.crud_tests;
// Setup
function createTestExecutor(coll, method, verifyResult) {
return function(args) {
// Drop collection
coll.drop();
// Insert test data
var r = coll.insertMany(args.insert);
assert.eq(args.insert.length, r.insertedIds.length);
// Execute the method with arguments
r = coll[method].apply(coll, args.params);
verifyResult(args.result, r);
// Get all the results
assert.soonNoExcept(
function() {
var results = coll.find({}).sort({_id: 1}).toArray();
assert.docEq(args.expected, results);
return true;
},
function() {
return "collection never contained expected documents";
});
};
}
function checkResultObject(first, second) {
// Only assert on the "modifiedCount" property when write commands are enabled
if (db.getMongo().writeMode() === 'commands') {
assert.docEq(first, second);
} else {
var overrideModifiedCount = {modifiedCount: undefined};
assert.docEq(Object.merge(first, overrideModifiedCount),
Object.merge(second, overrideModifiedCount));
}
}
// Setup executors
var deleteManyExecutor = createTestExecutor(coll, 'deleteMany', checkResultObject);
var deleteOneExecutor = createTestExecutor(coll, 'deleteOne', checkResultObject);
var bulkWriteExecutor = createTestExecutor(coll, 'bulkWrite', checkResultObject);
var findOneAndDeleteExecutor = createTestExecutor(coll, 'findOneAndDelete', checkResultObject);
var findOneAndReplaceExecutor =
createTestExecutor(coll, 'findOneAndReplace', checkResultObject);
var findOneAndUpdateExecutor = createTestExecutor(coll, 'findOneAndUpdate', checkResultObject);
var insertManyExecutor = createTestExecutor(coll, 'insertMany', checkResultObject);
var insertOneExecutor = createTestExecutor(coll, 'insertOne', checkResultObject);
var replaceOneExecutor = createTestExecutor(coll, 'replaceOne', checkResultObject);
var updateManyExecutor = createTestExecutor(coll, 'updateMany', checkResultObject);
var updateOneExecutor = createTestExecutor(coll, 'updateOne', checkResultObject);
var countExecutor = createTestExecutor(coll, 'count', assert.eq);
var distinctExecutor = createTestExecutor(coll, 'distinct', (a, b) => assert(arrayEq(a, b)));
//
// BulkWrite
//
bulkWriteExecutor({
insert: [{_id: 1, c: 1}, {_id: 2, c: 2}, {_id: 3, c: 3}],
params: [[
{insertOne: {document: {_id: 4, a: 1}}},
{updateOne: {filter: {_id: 5, a: 2}, update: {$set: {a: 2}}, upsert: true}},
{updateMany: {filter: {_id: 6, a: 3}, update: {$set: {a: 3}}, upsert: true}},
{deleteOne: {filter: {c: 1}}},
{insertOne: {document: {_id: 7, c: 2}}},
{deleteMany: {filter: {c: 2}}},
{replaceOne: {filter: {c: 3}, replacement: {c: 4}, upsert: true}}
]],
result: {
acknowledged: true,
insertedCount: 2,
matchedCount: 1,
deletedCount: 3,
upsertedCount: 2,
insertedIds: {'0': 4, '4': 7},
upsertedIds: {'1': 5, '2': 6}
},
expected: [{"_id": 3, "c": 4}, {"_id": 4, "a": 1}, {"_id": 5, "a": 2}, {"_id": 6, "a": 3}]
});
bulkWriteExecutor({
insert: [{_id: 1, c: 1}, {_id: 2, c: 2}, {_id: 3, c: 3}],
params: [
[
{insertOne: {document: {_id: 4, a: 1}}},
{updateOne: {filter: {_id: 5, a: 2}, update: {$set: {a: 2}}, upsert: true}},
{updateMany: {filter: {_id: 6, a: 3}, update: {$set: {a: 3}}, upsert: true}},
{deleteOne: {filter: {c: 1}}},
{deleteMany: {filter: {c: 2}}},
{replaceOne: {filter: {c: 3}, replacement: {c: 4}, upsert: true}}
],
{ordered: false}
],
result: {
acknowledged: true,
insertedCount: 1,
matchedCount: 1,
deletedCount: 2,
upsertedCount: 2,
insertedIds: {'0': 4},
upsertedIds: {'1': 5, '2': 6}
},
expected: [{"_id": 3, "c": 4}, {"_id": 4, "a": 1}, {"_id": 5, "a": 2}, {"_id": 6, "a": 3}]
});
// DeleteMany
//
// DeleteMany when many documents match
deleteManyExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: {$gt: 1}}],
result: {acknowledged: true, deletedCount: 2},
expected: [{_id: 1, x: 11}]
});
// DeleteMany when no document matches
deleteManyExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 4}],
result: {acknowledged: true, deletedCount: 0},
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// DeleteMany when many documents match, no write concern
deleteManyExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: {$gt: 1}}, {w: 0}],
result: {acknowledged: false},
expected: [{_id: 1, x: 11}]
});
//
// DeleteOne
//
// DeleteOne when many documents match
deleteOneExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: {$gt: 1}}],
result: {acknowledged: true, deletedCount: 1},
expected: [{_id: 1, x: 11}, {_id: 3, x: 33}]
});
// DeleteOne when one document matches
deleteOneExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 2}],
result: {acknowledged: true, deletedCount: 1},
expected: [{_id: 1, x: 11}, {_id: 3, x: 33}]
});
// DeleteOne when no documents match
deleteOneExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 4}],
result: {acknowledged: true, deletedCount: 0},
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// DeleteOne when many documents match, no write concern
deleteOneExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: {$gt: 1}}, {w: 0}],
result: {acknowledged: false},
expected: [{_id: 1, x: 11}, {_id: 3, x: 33}]
});
//
// FindOneAndDelete
//
// FindOneAndDelete when one document matches
findOneAndDeleteExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: {$gt: 2}}, {projection: {x: 1, _id: 0}, sort: {x: 1}}],
result: {x: 33},
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}]
});
// FindOneAndDelete when one document matches
findOneAndDeleteExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 2}, {projection: {x: 1, _id: 0}, sort: {x: 1}}],
result: {x: 22},
expected: [{_id: 1, x: 11}, {_id: 3, x: 33}]
});
// FindOneAndDelete when no documents match
findOneAndDeleteExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 4}, {projection: {x: 1, _id: 0}, sort: {x: 1}}],
result: null,
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
//
// FindOneAndReplace
//
// FindOneAndReplace when many documents match returning the document before modification
findOneAndReplaceExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: {$gt: 1}}, {x: 32}, {projection: {x: 1, _id: 0}, sort: {x: 1}}],
result: {x: 22},
expected: [{_id: 1, x: 11}, {_id: 2, x: 32}, {_id: 3, x: 33}]
});
// FindOneAndReplace when many documents match returning the document after modification
findOneAndReplaceExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [
{_id: {$gt: 1}},
{x: 32},
{projection: {x: 1, _id: 0}, sort: {x: 1}, returnNewDocument: true}
],
result: {x: 32},
expected: [{_id: 1, x: 11}, {_id: 2, x: 32}, {_id: 3, x: 33}]
});
// FindOneAndReplace when one document matches returning the document before modification
findOneAndReplaceExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 2}, {x: 32}, {projection: {x: 1, _id: 0}, sort: {x: 1}}],
result: {x: 22},
expected: [{_id: 1, x: 11}, {_id: 2, x: 32}, {_id: 3, x: 33}]
});
// FindOneAndReplace when one document matches returning the document after modification
findOneAndReplaceExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [
{_id: 2},
{x: 32},
{projection: {x: 1, _id: 0}, sort: {x: 1}, returnNewDocument: true}
],
result: {x: 32},
expected: [{_id: 1, x: 11}, {_id: 2, x: 32}, {_id: 3, x: 33}]
});
// FindOneAndReplace when no documents match returning the document before modification
findOneAndReplaceExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 4}, {x: 44}, {projection: {x: 1, _id: 0}, sort: {x: 1}}],
result: null,
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// FindOneAndReplace when no documents match with upsert returning the document before
// modification
findOneAndReplaceExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 4}, {x: 44}, {projection: {x: 1, _id: 0}, sort: {x: 1}, upsert: true}],
result: null,
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}, {_id: 4, x: 44}]
});
// FindOneAndReplace when no documents match returning the document after modification
findOneAndReplaceExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [
{_id: 4},
{x: 44},
{projection: {x: 1, _id: 0}, sort: {x: 1}, returnNewDocument: true}
],
result: null,
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// FindOneAndReplace when no documents match with upsert returning the document after
// modification
findOneAndReplaceExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [
{_id: 4},
{x: 44},
{projection: {x: 1, _id: 0}, sort: {x: 1}, returnNewDocument: true, upsert: true}
],
result: {x: 44},
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}, {_id: 4, x: 44}]
});
assert.throws(function() {
coll.findOneAndReplace({a: 1}, {$set: {b: 1}});
});
//
// FindOneAndUpdate
//
// FindOneAndUpdate when many documents match returning the document before modification
findOneAndUpdateExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: {$gt: 1}}, {$inc: {x: 1}}, {projection: {x: 1, _id: 0}, sort: {x: 1}}],
result: {x: 22},
expected: [{_id: 1, x: 11}, {_id: 2, x: 23}, {_id: 3, x: 33}]
});
// FindOneAndUpdate when many documents match returning the document after modification
findOneAndUpdateExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [
{_id: {$gt: 1}},
{$inc: {x: 1}},
{projection: {x: 1, _id: 0}, sort: {x: 1}, returnNewDocument: true}
],
result: {x: 23},
expected: [{_id: 1, x: 11}, {_id: 2, x: 23}, {_id: 3, x: 33}]
});
// FindOneAndUpdate when one document matches returning the document before modification
findOneAndUpdateExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 2}, {$inc: {x: 1}}, {projection: {x: 1, _id: 0}, sort: {x: 1}}],
result: {x: 22},
expected: [{_id: 1, x: 11}, {_id: 2, x: 23}, {_id: 3, x: 33}]
});
// FindOneAndUpdate when one document matches returning the document after modification
findOneAndUpdateExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [
{_id: 2},
{$inc: {x: 1}},
{projection: {x: 1, _id: 0}, sort: {x: 1}, returnNewDocument: true}
],
result: {x: 23},
expected: [{_id: 1, x: 11}, {_id: 2, x: 23}, {_id: 3, x: 33}]
});
// FindOneAndUpdate when no documents match returning the document before modification
findOneAndUpdateExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 4}, {$inc: {x: 1}}, {projection: {x: 1, _id: 0}, sort: {x: 1}}],
result: null,
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// FindOneAndUpdate when no documents match with upsert returning the document before
// modification
findOneAndUpdateExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params:
[{_id: 4}, {$inc: {x: 1}}, {projection: {x: 1, _id: 0}, sort: {x: 1}, upsert: true}],
result: null,
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}, {_id: 4, x: 1}]
});
// FindOneAndUpdate when no documents match returning the document after modification
findOneAndUpdateExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [
{_id: 4},
{$inc: {x: 1}},
{projection: {x: 1, _id: 0}, sort: {x: 1}, returnNewDocument: true}
],
result: null,
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// FindOneAndUpdate when no documents match with upsert returning the document after
// modification
findOneAndUpdateExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [
{_id: 4},
{$inc: {x: 1}},
{projection: {x: 1, _id: 0}, sort: {x: 1}, returnNewDocument: true, upsert: true}
],
result: {x: 1},
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}, {_id: 4, x: 1}]
});
assert.throws(function() {
coll.findOneAndUpdate({a: 1}, {});
});
assert.throws(function() {
coll.findOneAndUpdate({a: 1}, {b: 1});
});
//
// InsertMany
//
// InsertMany with non-existing documents
insertManyExecutor({
insert: [{_id: 1, x: 11}],
params: [[{_id: 2, x: 22}, {_id: 3, x: 33}]],
result: {acknowledged: true, insertedIds: [2, 3]},
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// InsertMany with non-existing documents, no write concern
insertManyExecutor({
insert: [{_id: 1, x: 11}],
params: [[{_id: 2, x: 22}, {_id: 3, x: 33}], {w: 0}],
result: {acknowledged: false},
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
//
// InsertOne
//
// InsertOne with non-existing documents
insertOneExecutor({
insert: [{_id: 1, x: 11}],
params: [{_id: 2, x: 22}],
result: {acknowledged: true, insertedId: 2},
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}]
});
// InsertOne with non-existing documents, no write concern
insertOneExecutor({
insert: [{_id: 1, x: 11}],
params: [{_id: 2, x: 22}, {w: 0}],
result: {acknowledged: false},
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}]
});
//
// ReplaceOne
//
// ReplaceOne when many documents match
replaceOneExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: {$gt: 1}}, {x: 111}],
result: {acknowledged: true, matchedCount: 1, modifiedCount: 1},
expected: [{_id: 1, x: 11}, {_id: 2, x: 111}, {_id: 3, x: 33}]
});
// ReplaceOne when one document matches
replaceOneExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 1}, {_id: 1, x: 111}],
result: {acknowledged: true, matchedCount: 1, modifiedCount: 1},
expected: [{_id: 1, x: 111}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// ReplaceOne when no documents match
replaceOneExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 4}, {_id: 4, x: 1}],
result: {acknowledged: true, matchedCount: 0, modifiedCount: 0},
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// ReplaceOne with upsert when no documents match without an id specified
replaceOneExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 4}, {x: 1}, {upsert: true}],
result: {acknowledged: true, matchedCount: 0, modifiedCount: 0, upsertedId: 4},
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}, {_id: 4, x: 1}]
});
// ReplaceOne with upsert when no documents match with an id specified
replaceOneExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 4}, {_id: 4, x: 1}, {upsert: true}],
result: {acknowledged: true, matchedCount: 0, modifiedCount: 0, upsertedId: 4},
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}, {_id: 4, x: 1}]
});
// ReplaceOne with upsert when no documents match with an id specified, no write concern
replaceOneExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 4}, {_id: 4, x: 1}, {upsert: true, w: 0}],
result: {acknowledged: false},
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}, {_id: 4, x: 1}]
});
// ReplaceOne with upsert when no documents match with an id specified, no write concern
replaceOneExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 4}, {_id: 4, x: 1}, {upsert: true, writeConcern: {w: 0}}],
result: {acknowledged: false},
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}, {_id: 4, x: 1}]
});
assert.throws(function() {
coll.replaceOne({a: 1}, {$set: {b: 1}});
});
//
// UpdateMany
//
// UpdateMany when many documents match
updateManyExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: {$gt: 1}}, {$inc: {x: 1}}],
result: {acknowledged: true, matchedCount: 2, modifiedCount: 2},
expected: [{_id: 1, x: 11}, {_id: 2, x: 23}, {_id: 3, x: 34}]
});
// UpdateMany when one document matches
updateManyExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 1}, {$inc: {x: 1}}],
result: {acknowledged: true, matchedCount: 1, modifiedCount: 1},
expected: [{_id: 1, x: 12}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// UpdateMany when no documents match
updateManyExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 4}, {$inc: {x: 1}}],
result: {acknowledged: true, matchedCount: 0, modifiedCount: 0},
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// UpdateMany with upsert when no documents match
updateManyExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 4}, {$inc: {x: 1}}, {upsert: true}],
result: {acknowledged: true, matchedCount: 0, modifiedCount: 0, upsertedId: 4},
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}, {_id: 4, x: 1}]
});
// UpdateMany with upsert when no documents match, no write concern
updateManyExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 4}, {$inc: {x: 1}}, {upsert: true, w: 0}],
result: {acknowledged: false},
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}, {_id: 4, x: 1}]
});
assert.throws(function() {
coll.updateMany({a: 1}, {});
});
assert.throws(function() {
coll.updateMany({a: 1}, {b: 1});
});
//
// UpdateOne
//
// UpdateOne when many documents match
updateOneExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: {$gt: 1}}, {$inc: {x: 1}}],
result: {acknowledged: true, matchedCount: 1, modifiedCount: 1},
expected: [{_id: 1, x: 11}, {_id: 2, x: 23}, {_id: 3, x: 33}]
});
// UpdateOne when one document matches
updateOneExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 1}, {$inc: {x: 1}}],
result: {acknowledged: true, matchedCount: 1, modifiedCount: 1},
expected: [{_id: 1, x: 12}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// UpdateOne when no documents match
updateOneExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 4}, {$inc: {x: 1}}],
result: {acknowledged: true, matchedCount: 0, modifiedCount: 0},
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// UpdateOne with upsert when no documents match
updateOneExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: 4}, {$inc: {x: 1}}, {upsert: true}],
result: {acknowledged: true, matchedCount: 0, modifiedCount: 0, upsertedId: 4},
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}, {_id: 4, x: 1}]
});
// UpdateOne when many documents match, no write concern
updateOneExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: {$gt: 1}}, {$inc: {x: 1}}, {w: 0}],
result: {acknowledged: false},
expected: [{_id: 1, x: 11}, {_id: 2, x: 23}, {_id: 3, x: 33}]
});
assert.throws(function() {
coll.updateOne({a: 1}, {});
});
assert.throws(function() {
coll.updateOne({a: 1}, {b: 1});
});
//
// Count
//
// Simple count of all elements
countExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{}],
result: 3,
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// Simple count no arguments
countExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [],
result: 3,
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// Simple count filtered
countExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{_id: {$gt: 1}}],
result: 2,
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// Simple count of all elements, applying limit
countExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{}, {limit: 1}],
result: 1,
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// Simple count of all elements, applying skip
countExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{}, {skip: 1}],
result: 2,
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// Simple count no arguments, applying hint
countExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: [{}, {hint: {"_id": 1}}],
result: 3,
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
//
// Distinct
//
// Simple distinct of field x no filter
distinctExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: ['x'],
result: [11, 22, 33],
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// Simple distinct of field x
distinctExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: ['x', {}],
result: [11, 22, 33],
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// Simple distinct of field x filtered
distinctExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: ['x', {x: {$gt: 11}}],
result: [22, 33],
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
// Simple distinct of field x filtered with maxTimeMS
distinctExecutor({
insert: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}],
params: ['x', {x: {$gt: 11}}, {maxTimeMS: 100000}],
result: [22, 33],
expected: [{_id: 1, x: 11}, {_id: 2, x: 22}, {_id: 3, x: 33}]
});
//
// Find
//
coll.deleteMany({});
// Insert all of them
coll.insertMany([{a: 0, b: 0}, {a: 1, b: 1}]);
// Simple projection
var result = coll.find({}).sort({a: 1}).limit(1).skip(1).projection({_id: 0, a: 1}).toArray();
assert.docEq(result, [{a: 1}]);
// Simple tailable cursor
var cursor = coll.find({}).sort({a: 1}).tailable();
assert.eq(34, (cursor._options & ~DBQuery.Option.slaveOk));
var cursor = coll.find({}).sort({a: 1}).tailable(false);
assert.eq(2, (cursor._options & ~DBQuery.Option.slaveOk));
// Check modifiers
var cursor = coll.find({}).modifiers({$hint: 'a_1'});
assert.eq('a_1', cursor._query['$hint']);
// allowPartialResults
var cursor = coll.find({}).allowPartialResults();
assert.eq(128, (cursor._options & ~DBQuery.Option.slaveOk));
// noCursorTimeout
var cursor = coll.find({}).noCursorTimeout();
assert.eq(16, (cursor._options & ~DBQuery.Option.slaveOk));
//
// Aggregation
//
coll.deleteMany({});
// Insert all of them
coll.insertMany([{a: 0, b: 0}, {a: 1, b: 1}]);
// Simple aggregation with useCursor
var result = coll.aggregate([{$match: {}}], {useCursor: true}).toArray();
assert.eq(2, result.length);
// Simple aggregation with batchSize
var result = coll.aggregate([{$match: {}}], {batchSize: 2}).toArray();
assert.eq(2, result.length);
// Drop collection
coll.drop();
coll.ensureIndex({a: 1}, {unique: true});
// Should throw duplicate key error
assert.throws(function() {
coll.insertMany([{a: 0, b: 0}, {a: 0, b: 1}]);
});
assert(coll.findOne({a: 0, b: 0}) != null);
assert.throws(function() {
coll.insertOne({a: 0, b: 0});
});
assert.throws(function() {
coll.updateOne({b: 2}, {$set: {a: 0}}, {upsert: true});
});
assert.throws(function() {
coll.updateMany({b: 2}, {$set: {a: 0}}, {upsert: true});
});
assert.throws(function() {
coll.deleteOne({$invalidFieldName: {a: 1}});
});
assert.throws(function() {
coll.deleteMany({$set: {a: 1}});
});
assert.throws(function() {
coll.bulkWrite([{insertOne: {document: {_id: 4, a: 0}}}]);
});
};
crudAPISpecTests();
})();