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

206 lines
7.5 KiB
JavaScript

t = db.borders;
t.drop();
epsilon = 0.0001;
// For these tests, *required* that step ends exactly on max
min = -1;
max = 1;
step = 1;
numItems = 0;
for (var x = min; x <= max; x += step) {
for (var y = min; y <= max; y += step) {
t.insert({loc: {x: x, y: y}});
numItems++;
}
}
overallMin = -1;
overallMax = 1;
// Create a point index slightly smaller than the points we have
var res =
t.ensureIndex({loc: "2d"}, {max: overallMax - epsilon / 2, min: overallMin + epsilon / 2});
assert.commandFailed(res);
// Create a point index only slightly bigger than the points we have
res = t.ensureIndex({loc: "2d"}, {max: overallMax + epsilon, min: overallMin - epsilon});
assert.commandWorked(res);
// ************
// Box Tests
// ************
// If the bounds are bigger than the box itself, just clip at the borders
assert.eq(numItems, t.find({
loc: {
$within: {
$box: [
[overallMin - 2 * epsilon, overallMin - 2 * epsilon],
[overallMax + 2 * epsilon, overallMax + 2 * epsilon]
]
}
}
}).count());
// Check this works also for bounds where only a single dimension is off-bounds
assert.eq(numItems - 5, t.find({
loc: {
$within: {
$box: [
[overallMin - 2 * epsilon, overallMin - 0.5 * epsilon],
[overallMax - epsilon, overallMax - epsilon]
]
}
}
}).count());
// Make sure we can get at least close to the bounds of the index
assert.eq(numItems, t.find({
loc: {
$within: {
$box: [
[overallMin - epsilon / 2, overallMin - epsilon / 2],
[overallMax + epsilon / 2, overallMax + epsilon / 2]
]
}
}
}).count());
// Make sure we can get at least close to the bounds of the index
assert.eq(numItems, t.find({
loc: {
$within: {
$box: [
[overallMax + epsilon / 2, overallMax + epsilon / 2],
[overallMin - epsilon / 2, overallMin - epsilon / 2]
]
}
}
}).count());
// Check that swapping min/max has good behavior
assert.eq(numItems, t.find({
loc: {
$within: {
$box: [
[overallMax + epsilon / 2, overallMax + epsilon / 2],
[overallMin - epsilon / 2, overallMin - epsilon / 2]
]
}
}
}).count());
assert.eq(numItems, t.find({
loc: {
$within: {
$box: [
[overallMax + epsilon / 2, overallMin - epsilon / 2],
[overallMin - epsilon / 2, overallMax + epsilon / 2]
]
}
}
}).count());
// **************
// Circle tests
// **************
center = (overallMax + overallMin) / 2;
center = [center, center];
radius = overallMax;
offCenter = [center[0] + radius, center[1] + radius];
onBounds = [offCenter[0] + epsilon, offCenter[1] + epsilon];
offBounds = [onBounds[0] + epsilon, onBounds[1] + epsilon];
onBoundsNeg = [-onBounds[0], -onBounds[1]];
// Make sure we can get all points when radius is exactly at full bounds
assert.lt(0, t.find({loc: {$within: {$center: [center, radius + epsilon]}}}).count());
// Make sure we can get points when radius is over full bounds
assert.lt(0, t.find({loc: {$within: {$center: [center, radius + 2 * epsilon]}}}).count());
// Make sure we can get points when radius is over full bounds, off-centered
assert.lt(0, t.find({loc: {$within: {$center: [offCenter, radius + 2 * epsilon]}}}).count());
// Make sure we get correct corner point when center is in bounds
// (x bounds wrap, so could get other corner)
cornerPt = t.findOne({loc: {$within: {$center: [offCenter, step / 2]}}});
assert.eq(cornerPt.loc.y, overallMax);
// Make sure we get correct corner point when center is on bounds
// NOTE: Only valid points on MIN bounds
cornerPt = t.findOne(
{loc: {$within: {$center: [onBoundsNeg, Math.sqrt(2 * epsilon * epsilon) + (step / 2)]}}});
assert.eq(cornerPt.loc.y, overallMin);
// Make sure we can't get corner point when center is over bounds
// TODO: SERVER-5800 clean up wrapping rules for different CRS queries - not sure this is an error
/*
assert.throws(function(){
t.findOne( { loc : { $within : { $center : [ offBounds, Math.sqrt( 8 * epsilon * epsilon ) + (
step / 2 ) ] } } } );
});
*/
// Make sure we can't get corner point when center is on max bounds
// Broken - see SERVER-13581
// assert.throws(function(){
// t.findOne( { loc : { $within : { $center : [ onBounds, Math.sqrt( 8 * epsilon * epsilon ) + (
// step / 2 ) ] } } } );
//});
// ***********
// Near tests
// ***********
// Make sure we can get all nearby points to point in range
assert.eq(overallMax, t.find({loc: {$near: offCenter}}).next().loc.y);
// Make sure we can get all nearby points to point on boundary
assert.eq(overallMin, t.find({loc: {$near: onBoundsNeg}}).next().loc.y);
// Make sure we can't get all nearby points to point over boundary
// TODO: SERVER-9986 clean up wrapping rules for different CRS queries - not sure this is an error
/*
assert.throws(function(){
t.findOne( { loc : { $near : offBounds } } );
});
*/
// Make sure we can't get all nearby points to point on max boundary
// Broken - see SERVER-13581
// assert.throws(function(){
// t.findOne( { loc : { $near : onBoundsNeg } } );
//});
// Make sure we can get all nearby points within one step (4 points in top
// corner)
assert.eq(4, t.find({loc: {$near: offCenter, $maxDistance: step * 1.9}}).count());
// **************
// Command Tests
// **************
// Make sure we can get all nearby points to point in range
assert.eq(overallMax, db.runCommand({geoNear: "borders", near: offCenter}).results[0].obj.loc.y);
// Make sure we can get all nearby points to point on boundary
assert.eq(overallMin, db.runCommand({geoNear: "borders", near: onBoundsNeg}).results[0].obj.loc.y);
// Make sure we can't get all nearby points to point over boundary
// TODO: SERVER-9986 clean up wrapping rules for different CRS queries - not sure this is an error
/*
assert.commandFailed( db.runCommand( { geoNear : "borders", near : offBounds } ));
*/
// Make sure we can't get all nearby points to point on max boundary
assert.commandWorked(db.runCommand({geoNear: "borders", near: onBounds}));
// Make sure we can get all nearby points within one step (4 points in top
// corner)
assert.eq(
4,
db.runCommand({geoNear: "borders", near: offCenter, maxDistance: step * 1.5}).results.length);