138 lines
5.5 KiB
JavaScript
138 lines
5.5 KiB
JavaScript
t = db.jstests_rename4;
|
|
t.drop();
|
|
|
|
function bad(f) {
|
|
var docsBeforeUpdate = t.find().toArray();
|
|
var res = eval(f);
|
|
|
|
// Ensure error
|
|
if (!res.hasWriteError()) {
|
|
print("Error:" + res.toString());
|
|
print("Existing docs (before)");
|
|
printjson(docsBeforeUpdate);
|
|
print("Existing docs (after)");
|
|
printjson(t.find().toArray());
|
|
assert(false, "Expected error but didn't get one for: " + f);
|
|
}
|
|
}
|
|
|
|
bad("t.update( {}, {$rename:{'a':'a'}} )");
|
|
bad("t.update( {}, {$rename:{'':'a'}} )");
|
|
bad("t.update( {}, {$rename:{'a':''}} )");
|
|
bad("t.update( {}, {$rename:{'.a':'b'}} )");
|
|
bad("t.update( {}, {$rename:{'a':'.b'}} )");
|
|
bad("t.update( {}, {$rename:{'a.':'b'}} )");
|
|
bad("t.update( {}, {$rename:{'a':'b.'}} )");
|
|
bad("t.update( {}, {$rename:{'a.b':'a'}} )");
|
|
bad("t.update( {}, {$rename:{'a.$':'b'}} )");
|
|
bad("t.update( {}, {$rename:{'a':'b.$'}} )");
|
|
|
|
// Only bad if input doc has field resulting in conflict
|
|
t.save({_id: 1, a: 2});
|
|
bad("t.update( {}, {$rename:{'_id':'a'}} )");
|
|
bad("t.update( {}, {$set:{b:1},$rename:{'a':'b'}} )");
|
|
bad("t.update( {}, {$rename:{'a':'b'},$set:{b:1}} )");
|
|
bad("t.update( {}, {$rename:{'a':'b'},$set:{a:1}} )");
|
|
bad("t.update( {}, {$set:{'b.c':1},$rename:{'a':'b'}} )");
|
|
bad("t.update( {}, {$set:{b:1},$rename:{'a':'b.c'}} )");
|
|
bad("t.update( {}, {$rename:{'a':'b'},$set:{'b.c':1}} )");
|
|
bad("t.update( {}, {$rename:{'a':'b.c'},$set:{b:1}} )");
|
|
|
|
t.remove({});
|
|
t.save({a: [1], b: {c: [2]}, d: [{e: 3}], f: 4});
|
|
bad("t.update( {}, {$rename:{'a.0':'f'}} )");
|
|
bad("t.update( {}, {$rename:{'a.0':'g'}} )");
|
|
bad("t.update( {}, {$rename:{'f':'a.0'}} )");
|
|
bad("t.update( {}, {$rename:{'b.c.0':'f'}} )");
|
|
bad("t.update( {}, {$rename:{'f':'b.c.0'}} )");
|
|
bad("t.update( {}, {$rename:{'d.e':'d.f'}} )");
|
|
bad("t.update( {}, {$rename:{'d.e':'f'}} )");
|
|
bad("t.update( {}, {$rename:{'d.f':'d.e'}} )");
|
|
bad("t.update( {}, {$rename:{'f':'d.e'}} )");
|
|
bad("t.update( {}, {$rename:{'d.0.e':'d.f'}} )");
|
|
bad("t.update( {}, {$rename:{'d.0.e':'f'}} )");
|
|
bad("t.update( {}, {$rename:{'d.f':'d.0.e'}} )");
|
|
bad("t.update( {}, {$rename:{'f':'d.0.e'}} )");
|
|
bad("t.update( {}, {$rename:{'f.g':'a'}} )");
|
|
bad("t.update( {}, {$rename:{'a':'f.g'}} )");
|
|
|
|
function good(start, mod, expected) {
|
|
t.remove({});
|
|
t.save(start);
|
|
var res = t.update({}, mod);
|
|
assert.writeOK(res);
|
|
var got = t.findOne();
|
|
delete got._id;
|
|
assert.docEq(expected, got);
|
|
}
|
|
|
|
good({a: 1}, {$rename: {a: 'b'}}, {b: 1});
|
|
good({a: 1}, {$rename: {a: 'bb'}}, {bb: 1});
|
|
good({b: 1}, {$rename: {b: 'a'}}, {a: 1});
|
|
good({bb: 1}, {$rename: {bb: 'a'}}, {a: 1});
|
|
good({a: {y: 1}}, {$rename: {'a.y': 'a.z'}}, {a: {z: 1}});
|
|
good({a: {yy: 1}}, {$rename: {'a.yy': 'a.z'}}, {a: {z: 1}});
|
|
good({a: {z: 1}}, {$rename: {'a.z': 'a.y'}}, {a: {y: 1}});
|
|
good({a: {zz: 1}}, {$rename: {'a.zz': 'a.y'}}, {a: {y: 1}});
|
|
good({a: {c: 1}}, {$rename: {a: 'b'}}, {b: {c: 1}});
|
|
good({aa: {c: 1}}, {$rename: {aa: 'b'}}, {b: {c: 1}});
|
|
good({a: 1, b: 2}, {$rename: {a: 'b'}}, {b: 1});
|
|
good({aa: 1, b: 2}, {$rename: {aa: 'b'}}, {b: 1});
|
|
good({a: 1, bb: 2}, {$rename: {a: 'bb'}}, {bb: 1});
|
|
good({a: 1}, {$rename: {a: 'b.c'}}, {b: {c: 1}});
|
|
good({aa: 1}, {$rename: {aa: 'b.c'}}, {b: {c: 1}});
|
|
good({a: 1, b: {}}, {$rename: {a: 'b.c'}}, {b: {c: 1}});
|
|
good({aa: 1, b: {}}, {$rename: {aa: 'b.c'}}, {b: {c: 1}});
|
|
good({a: 1}, {$rename: {b: 'c'}}, {a: 1});
|
|
good({aa: 1}, {$rename: {b: 'c'}}, {aa: 1});
|
|
good({}, {$rename: {b: 'c'}}, {});
|
|
good({a: {b: 1, c: 2}}, {$rename: {'a.b': 'd'}}, {a: {c: 2}, d: 1});
|
|
good({a: {bb: 1, c: 2}}, {$rename: {'a.bb': 'd'}}, {a: {c: 2}, d: 1});
|
|
good({a: {b: 1}}, {$rename: {'a.b': 'd'}}, {a: {}, d: 1});
|
|
good({a: [5]}, {$rename: {a: 'b'}}, {b: [5]});
|
|
good({aa: [5]}, {$rename: {aa: 'b'}}, {b: [5]});
|
|
good({'0': 1}, {$rename: {'0': '5'}}, {'5': 1});
|
|
good({a: 1, b: 2}, {$rename: {a: 'c'}, $set: {b: 5}}, {b: 5, c: 1});
|
|
good({aa: 1, b: 2}, {$rename: {aa: 'c'}, $set: {b: 5}}, {b: 5, c: 1});
|
|
good({a: 1, b: 2}, {$rename: {z: 'c'}, $set: {b: 5}}, {a: 1, b: 5});
|
|
good({aa: 1, b: 2}, {$rename: {z: 'c'}, $set: {b: 5}}, {aa: 1, b: 5});
|
|
|
|
// (formerly) rewriting single field
|
|
good({a: {z: 1, b: 1}}, {$rename: {'a.b': 'a.c'}}, {a: {c: 1, z: 1}});
|
|
good({a: {z: 1, tomato: 1}}, {$rename: {'a.tomato': 'a.potato'}}, {a: {potato: 1, z: 1}});
|
|
good({a: {z: 1, b: 1, c: 1}}, {$rename: {'a.b': 'a.c'}}, {a: {c: 1, z: 1}});
|
|
good(
|
|
{a: {z: 1, tomato: 1, potato: 1}}, {$rename: {'a.tomato': 'a.potato'}}, {a: {potato: 1, z: 1}});
|
|
good({a: {z: 1, b: 1}}, {$rename: {'a.b': 'a.cc'}}, {a: {cc: 1, z: 1}});
|
|
good({a: {z: 1, b: 1, c: 1}}, {$rename: {'a.b': 'aa.c'}}, {a: {c: 1, z: 1}, aa: {c: 1}});
|
|
|
|
// invalid target, but missing source
|
|
good({a: 1, c: 4}, {$rename: {b: 'c.d'}}, {a: 1, c: 4});
|
|
|
|
// TODO: This should be supported, and it is with the new update framework, but not with the
|
|
// old, and we currently don't have a good way to check which mode we are in. When we do have
|
|
// that, add this test guarded under that condition. Or, when we remove the old update path
|
|
// just enable this test.
|
|
|
|
// valid to rename away from an invalid name
|
|
// good( {x:1}, {$rename:{'$a.b':'a.b'}}, {x:1} );
|
|
|
|
// check index
|
|
t.drop();
|
|
t.ensureIndex({a: 1});
|
|
|
|
function l(start, mod, query, expected) {
|
|
t.remove({});
|
|
t.save(start);
|
|
var res = t.update({}, mod);
|
|
assert.writeOK(res);
|
|
var got = t.find(query).hint({a: 1}).next();
|
|
delete got._id;
|
|
assert.docEq(expected, got);
|
|
}
|
|
|
|
l({a: 1}, {$rename: {a: 'b'}}, {a: null}, {b: 1});
|
|
l({a: 1}, {$rename: {a: 'bb'}}, {a: null}, {bb: 1});
|
|
l({b: 1}, {$rename: {b: 'a'}}, {a: 1}, {a: 1});
|
|
l({bb: 1}, {$rename: {bb: 'a'}}, {a: 1}, {a: 1});
|