Files
mongo/jstests/core/rename4.js
2016-05-28 17:55:12 -04:00

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});