summaryrefslogtreecommitdiff
path: root/src/mongo/dbtests/matchertests.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/dbtests/matchertests.cpp')
-rw-r--r--src/mongo/dbtests/matchertests.cpp465
1 files changed, 230 insertions, 235 deletions
diff --git a/src/mongo/dbtests/matchertests.cpp b/src/mongo/dbtests/matchertests.cpp
index 194769d7cb7..17e00d3f1ec 100644
--- a/src/mongo/dbtests/matchertests.cpp
+++ b/src/mongo/dbtests/matchertests.cpp
@@ -40,246 +40,241 @@
namespace MatcherTests {
- using std::cout;
- using std::endl;
- using std::string;
-
- class CollectionBase {
- public:
- CollectionBase() { }
-
- virtual ~CollectionBase() { }
- };
-
- template <typename M>
- class Basic {
- public:
- void run() {
- BSONObj query = fromjson( "{\"a\":\"b\"}" );
- M m(query, MatchExpressionParser::WhereCallback());
- ASSERT( m.matches( fromjson( "{\"a\":\"b\"}" ) ) );
- }
- };
-
- template <typename M>
- class DoubleEqual {
- public:
- void run() {
- BSONObj query = fromjson( "{\"a\":5}" );
- M m(query, MatchExpressionParser::WhereCallback());
- ASSERT( m.matches( fromjson( "{\"a\":5}" ) ) );
- }
- };
-
- template <typename M>
- class MixedNumericEqual {
- public:
- void run() {
- BSONObjBuilder query;
- query.append( "a", 5 );
- M m(query.done(), MatchExpressionParser::WhereCallback());
- ASSERT( m.matches( fromjson( "{\"a\":5}" ) ) );
- }
- };
-
- template <typename M>
- class MixedNumericGt {
- public:
- void run() {
- BSONObj query = fromjson( "{\"a\":{\"$gt\":4}}" );
- M m(query, MatchExpressionParser::WhereCallback());
+using std::cout;
+using std::endl;
+using std::string;
+
+class CollectionBase {
+public:
+ CollectionBase() {}
+
+ virtual ~CollectionBase() {}
+};
+
+template <typename M>
+class Basic {
+public:
+ void run() {
+ BSONObj query = fromjson("{\"a\":\"b\"}");
+ M m(query, MatchExpressionParser::WhereCallback());
+ ASSERT(m.matches(fromjson("{\"a\":\"b\"}")));
+ }
+};
+
+template <typename M>
+class DoubleEqual {
+public:
+ void run() {
+ BSONObj query = fromjson("{\"a\":5}");
+ M m(query, MatchExpressionParser::WhereCallback());
+ ASSERT(m.matches(fromjson("{\"a\":5}")));
+ }
+};
+
+template <typename M>
+class MixedNumericEqual {
+public:
+ void run() {
+ BSONObjBuilder query;
+ query.append("a", 5);
+ M m(query.done(), MatchExpressionParser::WhereCallback());
+ ASSERT(m.matches(fromjson("{\"a\":5}")));
+ }
+};
+
+template <typename M>
+class MixedNumericGt {
+public:
+ void run() {
+ BSONObj query = fromjson("{\"a\":{\"$gt\":4}}");
+ M m(query, MatchExpressionParser::WhereCallback());
+ BSONObjBuilder b;
+ b.append("a", 5);
+ ASSERT(m.matches(b.done()));
+ }
+};
+
+template <typename M>
+class MixedNumericIN {
+public:
+ void run() {
+ BSONObj query = fromjson("{ a : { $in : [4,6] } }");
+ ASSERT_EQUALS(4, query["a"].embeddedObject()["$in"].embeddedObject()["0"].number());
+ ASSERT_EQUALS(NumberInt, query["a"].embeddedObject()["$in"].embeddedObject()["0"].type());
+
+ M m(query, MatchExpressionParser::WhereCallback());
+
+ {
BSONObjBuilder b;
- b.append( "a", 5 );
- ASSERT( m.matches( b.done() ) );
+ b.append("a", 4.0);
+ ASSERT(m.matches(b.done()));
}
- };
-
- template <typename M>
- class MixedNumericIN {
- public:
- void run() {
- BSONObj query = fromjson( "{ a : { $in : [4,6] } }" );
- ASSERT_EQUALS( 4 , query["a"].embeddedObject()["$in"].embeddedObject()["0"].number() );
- ASSERT_EQUALS( NumberInt , query["a"].embeddedObject()["$in"].embeddedObject()["0"].type() );
-
- M m(query, MatchExpressionParser::WhereCallback());
-
- {
- BSONObjBuilder b;
- b.append( "a" , 4.0 );
- ASSERT( m.matches( b.done() ) );
- }
- {
- BSONObjBuilder b;
- b.append( "a" , 5 );
- ASSERT( ! m.matches( b.done() ) );
- }
-
-
- {
- BSONObjBuilder b;
- b.append( "a" , 4 );
- ASSERT( m.matches( b.done() ) );
- }
-
- }
- };
-
- template <typename M>
- class MixedNumericEmbedded {
- public:
- void run() {
- M m(BSON("a" << BSON("x" << 1)), MatchExpressionParser::WhereCallback());
- ASSERT( m.matches( BSON( "a" << BSON( "x" << 1 ) ) ) );
- ASSERT( m.matches( BSON( "a" << BSON( "x" << 1.0 ) ) ) );
- }
- };
-
- template <typename M>
- class Size {
- public:
- void run() {
- M m(fromjson("{a:{$size:4}}"), MatchExpressionParser::WhereCallback());
- ASSERT( m.matches( fromjson( "{a:[1,2,3,4]}" ) ) );
- ASSERT( !m.matches( fromjson( "{a:[1,2,3]}" ) ) );
- ASSERT( !m.matches( fromjson( "{a:[1,2,3,'a','b']}" ) ) );
- ASSERT( !m.matches( fromjson( "{a:[[1,2,3,4]]}" ) ) );
- }
- };
-
- template <typename M>
- class WithinBox {
- public:
- void run() {
- M m(fromjson("{loc:{$within:{$box:[{x: 4, y:4},[6,6]]}}}"),
- MatchExpressionParser::WhereCallback());
- ASSERT(!m.matches(fromjson("{loc: [3,4]}")));
- ASSERT(m.matches(fromjson("{loc: [4,4]}")));
- ASSERT(m.matches(fromjson("{loc: [5,5]}")));
- ASSERT(m.matches(fromjson("{loc: [5,5.1]}")));
- ASSERT(m.matches(fromjson("{loc: {x: 5, y:5.1}}")));
- }
- };
-
- template <typename M>
- class WithinPolygon {
- public:
- void run() {
- M m(fromjson("{loc:{$within:{$polygon:[{x:0,y:0},[0,5],[5,5],[5,0]]}}}"),
- MatchExpressionParser::WhereCallback());
- ASSERT(m.matches(fromjson("{loc: [3,4]}")));
- ASSERT(m.matches(fromjson("{loc: [4,4]}")));
- ASSERT(m.matches(fromjson("{loc: {x:5,y:5}}")));
- ASSERT(!m.matches(fromjson("{loc: [5,5.1]}")));
- ASSERT(!m.matches(fromjson("{loc: {}}")));
- }
- };
-
- template <typename M>
- class WithinCenter {
- public:
- void run() {
- M m(fromjson("{loc:{$within:{$center:[{x:30,y:30},10]}}}"),
- MatchExpressionParser::WhereCallback());
- ASSERT(!m.matches(fromjson("{loc: [3,4]}")));
- ASSERT(m.matches(fromjson("{loc: {x:30,y:30}}")));
- ASSERT(m.matches(fromjson("{loc: [20,30]}")));
- ASSERT(m.matches(fromjson("{loc: [30,20]}")));
- ASSERT(m.matches(fromjson("{loc: [40,30]}")));
- ASSERT(m.matches(fromjson("{loc: [30,40]}")));
- ASSERT(!m.matches(fromjson("{loc: [31,40]}")));
- }
- };
-
- /** Test that MatchDetails::elemMatchKey() is set correctly after a match. */
- template <typename M>
- class ElemMatchKey {
- public:
- void run() {
- M matcher(BSON("a.b" << 1),
- MatchExpressionParser::WhereCallback());
- MatchDetails details;
- details.requestElemMatchKey();
- ASSERT( !details.hasElemMatchKey() );
- ASSERT( matcher.matches( fromjson( "{ a:[ { b:1 } ] }" ), &details ) );
- // The '0' entry of the 'a' array is matched.
- ASSERT( details.hasElemMatchKey() );
- ASSERT_EQUALS( string( "0" ), details.elemMatchKey() );
- }
- };
-
- template <typename M>
- class WhereSimple1 {
- public:
- void run() {
- OperationContextImpl txn;
- AutoGetCollectionForRead ctx(&txn, "unittests.matchertests");
-
- M m(BSON("$where" << "function(){ return this.a == 1; }"),
- WhereCallbackReal(&txn, StringData("unittests")));
- ASSERT( m.matches( BSON( "a" << 1 ) ) );
- ASSERT( !m.matches( BSON( "a" << 2 ) ) );
- }
- };
-
- template< typename M >
- class TimingBase {
- public:
- long dotime( const BSONObj& patt , const BSONObj& obj ) {
- M m(patt, MatchExpressionParser::WhereCallback());
- Timer t;
- for ( int i=0; i<900000; i++ ) {
- if ( !m.matches( obj ) ) {
- ASSERT( 0 );
- }
- }
- return t.millis();
- }
- };
-
- template< typename M >
- class AllTiming : public TimingBase<M> {
- public:
- void run() {
- long normal = TimingBase<M>::dotime( BSON( "x" << 5 ),
- BSON( "x" << 5 ) );
-
- long all = TimingBase<M>::dotime( BSON( "x" << BSON( "$all" << BSON_ARRAY( 5 ) ) ),
- BSON( "x" << 5 ) );
-
- cout << "AllTiming " << demangleName(typeid(M))
- << " normal: " << normal << " all: " << all << endl;
+ {
+ BSONObjBuilder b;
+ b.append("a", 5);
+ ASSERT(!m.matches(b.done()));
}
- };
- class All : public Suite {
- public:
- All() : Suite( "matcher" ) {
+ {
+ BSONObjBuilder b;
+ b.append("a", 4);
+ ASSERT(m.matches(b.done()));
}
-
-#define ADD_BOTH(TEST) \
- add< TEST<Matcher> >();
-
- void setupTests() {
- ADD_BOTH(Basic);
- ADD_BOTH(DoubleEqual);
- ADD_BOTH(MixedNumericEqual);
- ADD_BOTH(MixedNumericGt);
- ADD_BOTH(MixedNumericIN);
- ADD_BOTH(Size);
- ADD_BOTH(MixedNumericEmbedded);
- ADD_BOTH(ElemMatchKey);
- ADD_BOTH(WhereSimple1);
- ADD_BOTH(AllTiming);
- ADD_BOTH(WithinBox);
- ADD_BOTH(WithinCenter);
- ADD_BOTH(WithinPolygon);
+ }
+};
+
+template <typename M>
+class MixedNumericEmbedded {
+public:
+ void run() {
+ M m(BSON("a" << BSON("x" << 1)), MatchExpressionParser::WhereCallback());
+ ASSERT(m.matches(BSON("a" << BSON("x" << 1))));
+ ASSERT(m.matches(BSON("a" << BSON("x" << 1.0))));
+ }
+};
+
+template <typename M>
+class Size {
+public:
+ void run() {
+ M m(fromjson("{a:{$size:4}}"), MatchExpressionParser::WhereCallback());
+ ASSERT(m.matches(fromjson("{a:[1,2,3,4]}")));
+ ASSERT(!m.matches(fromjson("{a:[1,2,3]}")));
+ ASSERT(!m.matches(fromjson("{a:[1,2,3,'a','b']}")));
+ ASSERT(!m.matches(fromjson("{a:[[1,2,3,4]]}")));
+ }
+};
+
+template <typename M>
+class WithinBox {
+public:
+ void run() {
+ M m(fromjson("{loc:{$within:{$box:[{x: 4, y:4},[6,6]]}}}"),
+ MatchExpressionParser::WhereCallback());
+ ASSERT(!m.matches(fromjson("{loc: [3,4]}")));
+ ASSERT(m.matches(fromjson("{loc: [4,4]}")));
+ ASSERT(m.matches(fromjson("{loc: [5,5]}")));
+ ASSERT(m.matches(fromjson("{loc: [5,5.1]}")));
+ ASSERT(m.matches(fromjson("{loc: {x: 5, y:5.1}}")));
+ }
+};
+
+template <typename M>
+class WithinPolygon {
+public:
+ void run() {
+ M m(fromjson("{loc:{$within:{$polygon:[{x:0,y:0},[0,5],[5,5],[5,0]]}}}"),
+ MatchExpressionParser::WhereCallback());
+ ASSERT(m.matches(fromjson("{loc: [3,4]}")));
+ ASSERT(m.matches(fromjson("{loc: [4,4]}")));
+ ASSERT(m.matches(fromjson("{loc: {x:5,y:5}}")));
+ ASSERT(!m.matches(fromjson("{loc: [5,5.1]}")));
+ ASSERT(!m.matches(fromjson("{loc: {}}")));
+ }
+};
+
+template <typename M>
+class WithinCenter {
+public:
+ void run() {
+ M m(fromjson("{loc:{$within:{$center:[{x:30,y:30},10]}}}"),
+ MatchExpressionParser::WhereCallback());
+ ASSERT(!m.matches(fromjson("{loc: [3,4]}")));
+ ASSERT(m.matches(fromjson("{loc: {x:30,y:30}}")));
+ ASSERT(m.matches(fromjson("{loc: [20,30]}")));
+ ASSERT(m.matches(fromjson("{loc: [30,20]}")));
+ ASSERT(m.matches(fromjson("{loc: [40,30]}")));
+ ASSERT(m.matches(fromjson("{loc: [30,40]}")));
+ ASSERT(!m.matches(fromjson("{loc: [31,40]}")));
+ }
+};
+
+/** Test that MatchDetails::elemMatchKey() is set correctly after a match. */
+template <typename M>
+class ElemMatchKey {
+public:
+ void run() {
+ M matcher(BSON("a.b" << 1), MatchExpressionParser::WhereCallback());
+ MatchDetails details;
+ details.requestElemMatchKey();
+ ASSERT(!details.hasElemMatchKey());
+ ASSERT(matcher.matches(fromjson("{ a:[ { b:1 } ] }"), &details));
+ // The '0' entry of the 'a' array is matched.
+ ASSERT(details.hasElemMatchKey());
+ ASSERT_EQUALS(string("0"), details.elemMatchKey());
+ }
+};
+
+template <typename M>
+class WhereSimple1 {
+public:
+ void run() {
+ OperationContextImpl txn;
+ AutoGetCollectionForRead ctx(&txn, "unittests.matchertests");
+
+ M m(BSON("$where"
+ << "function(){ return this.a == 1; }"),
+ WhereCallbackReal(&txn, StringData("unittests")));
+ ASSERT(m.matches(BSON("a" << 1)));
+ ASSERT(!m.matches(BSON("a" << 2)));
+ }
+};
+
+template <typename M>
+class TimingBase {
+public:
+ long dotime(const BSONObj& patt, const BSONObj& obj) {
+ M m(patt, MatchExpressionParser::WhereCallback());
+ Timer t;
+ for (int i = 0; i < 900000; i++) {
+ if (!m.matches(obj)) {
+ ASSERT(0);
+ }
}
- };
-
- SuiteInstance<All> dball;
-
-} // namespace MatcherTests
-
+ return t.millis();
+ }
+};
+
+template <typename M>
+class AllTiming : public TimingBase<M> {
+public:
+ void run() {
+ long normal = TimingBase<M>::dotime(BSON("x" << 5), BSON("x" << 5));
+
+ long all =
+ TimingBase<M>::dotime(BSON("x" << BSON("$all" << BSON_ARRAY(5))), BSON("x" << 5));
+
+ cout << "AllTiming " << demangleName(typeid(M)) << " normal: " << normal << " all: " << all
+ << endl;
+ }
+};
+
+
+class All : public Suite {
+public:
+ All() : Suite("matcher") {}
+
+#define ADD_BOTH(TEST) add<TEST<Matcher>>();
+
+ void setupTests() {
+ ADD_BOTH(Basic);
+ ADD_BOTH(DoubleEqual);
+ ADD_BOTH(MixedNumericEqual);
+ ADD_BOTH(MixedNumericGt);
+ ADD_BOTH(MixedNumericIN);
+ ADD_BOTH(Size);
+ ADD_BOTH(MixedNumericEmbedded);
+ ADD_BOTH(ElemMatchKey);
+ ADD_BOTH(WhereSimple1);
+ ADD_BOTH(AllTiming);
+ ADD_BOTH(WithinBox);
+ ADD_BOTH(WithinCenter);
+ ADD_BOTH(WithinPolygon);
+ }
+};
+
+SuiteInstance<All> dball;
+
+} // namespace MatcherTests