summaryrefslogtreecommitdiff
path: root/src/mongo/dbtests/documenttests.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/dbtests/documenttests.cpp')
-rw-r--r--src/mongo/dbtests/documenttests.cpp332
1 files changed, 200 insertions, 132 deletions
diff --git a/src/mongo/dbtests/documenttests.cpp b/src/mongo/dbtests/documenttests.cpp
index 57bf7f8b55d..fa6156e473b 100644
--- a/src/mongo/dbtests/documenttests.cpp
+++ b/src/mongo/dbtests/documenttests.cpp
@@ -14,15 +14,26 @@
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects
+ * for all of the code used other than as permitted herein. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you do not
+ * wish to do so, delete this exception statement from your version. If you
+ * delete this exception statement from all source files in the program,
+ * then also delete it in the license file.
*/
-#include "pch.h"
+#include "mongo/pch.h"
#include "mongo/db/pipeline/document.h"
#include "mongo/db/pipeline/field_path.h"
#include "mongo/db/pipeline/value.h"
-
-#include "dbtests.h"
+#include "mongo/dbtests/dbtests.h"
namespace DocumentTests {
@@ -38,13 +49,11 @@ namespace DocumentTests {
using mongo::Document;
BSONObj toBson( const Document& document ) {
- BSONObjBuilder bob;
- document->toBson( &bob );
- return bob.obj();
+ return document.toBson();
}
Document fromBson( BSONObj obj ) {
- return Document::createFromBsonObj( &obj );
+ return Document(obj);
}
void assertRoundTrips( const Document& document1 ) {
@@ -52,7 +61,7 @@ namespace DocumentTests {
Document document2 = fromBson( obj1 );
BSONObj obj2 = toBson( document2 );
ASSERT_EQUALS( obj1, obj2 );
- ASSERT_EQUALS( 0, Document::compare( document1, document2 ) );
+ ASSERT_EQUALS( document1, document2 );
}
/** Create a Document. */
@@ -60,7 +69,7 @@ namespace DocumentTests {
public:
void run() {
Document document;
- ASSERT_EQUALS( 0U, document->getFieldCount() );
+ ASSERT_EQUALS( 0U, document.size() );
assertRoundTrips( document );
}
};
@@ -70,9 +79,9 @@ namespace DocumentTests {
public:
void run() {
Document document = fromBson( BSONObj() );
- ASSERT_EQUALS( 0U, document->getFieldCount() );
+ ASSERT_EQUALS( 0U, document.size() );
document = fromBson( BSON( "a" << 1 << "b" << "q" ) );
- ASSERT_EQUALS( 2U, document->getFieldCount() );
+ ASSERT_EQUALS( 2U, document.size() );
ASSERT_EQUALS( "a", getNthField(document, 0).first.toString() );
ASSERT_EQUALS( 1, getNthField(document, 0).second.getInt() );
ASSERT_EQUALS( "b", getNthField(document, 1).first.toString() );
@@ -86,17 +95,17 @@ namespace DocumentTests {
public:
void run() {
MutableDocument md;
- md.addField( "foo", Value::createInt( 1 ) );
- ASSERT_EQUALS( 1U, md.peek().getFieldCount() );
- ASSERT_EQUALS( 1, md.peek().getValue( "foo" ).getInt() );
- md.addField( "bar", Value::createInt( 99 ) );
- ASSERT_EQUALS( 2U, md.peek().getFieldCount() );
- ASSERT_EQUALS( 99, md.peek().getValue( "bar" ).getInt() );
+ md.addField( "foo", Value( 1 ) );
+ ASSERT_EQUALS( 1U, md.peek().size() );
+ ASSERT_EQUALS( 1, md.peek()["foo"].getInt() );
+ md.addField( "bar", Value( 99 ) );
+ ASSERT_EQUALS( 2U, md.peek().size() );
+ ASSERT_EQUALS( 99, md.peek()["bar"].getInt() );
// No assertion is triggered by a duplicate field name.
- md.addField( "a", Value::createInt( 5 ) );
+ md.addField( "a", Value( 5 ) );
Document final = md.freeze();
- ASSERT_EQUALS( 3U, final.getFieldCount() );
+ ASSERT_EQUALS( 3U, final.size() );
assertRoundTrips( final );
}
};
@@ -106,13 +115,13 @@ namespace DocumentTests {
public:
void run() {
Document document = fromBson( BSON( "a" << 1 << "b" << 2.2 ) );
- ASSERT_EQUALS( 1, document->getValue( "a" ).getInt() );
- ASSERT_EQUALS( 1, document->getField( "a" ).getInt() );
- ASSERT_EQUALS( 2.2, document->getValue( "b" ).getDouble() );
- ASSERT_EQUALS( 2.2, document->getField( "b" ).getDouble() );
+ ASSERT_EQUALS( 1, document["a"].getInt() );
+ ASSERT_EQUALS( 1, document["a"].getInt() );
+ ASSERT_EQUALS( 2.2, document["b"].getDouble() );
+ ASSERT_EQUALS( 2.2, document["b"].getDouble() );
// Missing field.
- ASSERT( document->getValue( "c" ).missing() );
- ASSERT( document->getField( "c" ).missing() );
+ ASSERT( document["c"].missing() );
+ ASSERT( document["c"].missing() );
assertRoundTrips( document );
}
};
@@ -132,44 +141,60 @@ namespace DocumentTests {
// Set the first field.
md.setField( "a" , Value( "foo" ) );
- ASSERT_EQUALS( 3U, md.peek().getFieldCount() );
- ASSERT_EQUALS( "foo", md.peek().getValue( "a" ).getString() );
+ ASSERT_EQUALS( 3U, md.peek().size() );
+ ASSERT_EQUALS( "foo", md.peek()["a"].getString() );
ASSERT_EQUALS( "foo", getNthField(md.peek(), 0).second.getString() );
assertRoundTrips( md.peek() );
// Set the second field.
md["b"] = Value("bar");
- ASSERT_EQUALS( 3U, md.peek().getFieldCount() );
- ASSERT_EQUALS( "bar", md.peek().getValue( "b" ).getString() );
+ ASSERT_EQUALS( 3U, md.peek().size() );
+ ASSERT_EQUALS( "bar", md.peek()["b"].getString() );
ASSERT_EQUALS( "bar", getNthField(md.peek(), 1).second.getString() );
assertRoundTrips( md.peek() );
// Remove the second field.
md.setField("b", Value());
PRINT(md.peek().toString());
- ASSERT_EQUALS( 2U, md.peek().getFieldCount() );
- ASSERT( md.peek().getValue( "b" ).missing() );
+ ASSERT_EQUALS( 2U, md.peek().size() );
+ ASSERT( md.peek()["b"].missing() );
ASSERT_EQUALS( "a", getNthField(md.peek(), 0 ).first.toString() );
ASSERT_EQUALS( "c", getNthField(md.peek(), 1 ).first.toString() );
- ASSERT_EQUALS( 99, md.peek().getValue("c").getInt() );
+ ASSERT_EQUALS( 99, md.peek()["c"].getInt() );
assertRoundTrips( md.peek() );
// Remove the first field.
md["a"] = Value();
- ASSERT_EQUALS( 1U, md.peek().getFieldCount() );
- ASSERT( md.peek().getValue( "a" ).missing() );
+ ASSERT_EQUALS( 1U, md.peek().size() );
+ ASSERT( md.peek()["a"].missing() );
ASSERT_EQUALS( "c", getNthField(md.peek(), 0 ).first.toString() );
- ASSERT_EQUALS( 99, md.peek().getValue("c").getInt() );
+ ASSERT_EQUALS( 99, md.peek()["c"].getInt() );
assertRoundTrips( md.peek() );
// Remove the final field. Verify document is empty.
md.remove("c");
ASSERT( md.peek().empty() );
- ASSERT_EQUALS( 0U, md.peek().getFieldCount() );
- ASSERT_EQUALS( 0, Document::compare(md.peek(), Document()) );
+ ASSERT_EQUALS( 0U, md.peek().size() );
+ ASSERT_EQUALS( md.peek(), Document() );
ASSERT( !FieldIterator(md.peek()).more() );
- ASSERT( md.peek().getValue( "c" ).missing() );
+ ASSERT( md.peek()["c"].missing() );
assertRoundTrips( md.peek() );
+ // Set a nested field using []
+ md["x"]["y"]["z"] = Value("nested");
+ ASSERT_EQUALS(md.peek()["x"]["y"]["z"], Value("nested"));
+
+ // Set a nested field using setNestedField
+ FieldPath xxyyzz = string("xx.yy.zz");
+ md.setNestedField(xxyyzz, Value("nested"));
+ ASSERT_EQUALS(md.peek().getNestedField(xxyyzz), Value("nested") );
+
+ // Set a nested fields through an existing empty document
+ md["xxx"] = Value(Document());
+ md["xxx"]["yyy"] = Value(Document());
+ FieldPath xxxyyyzzz = string("xxx.yyy.zzz");
+ md.setNestedField(xxxyyyzzz, Value("nested"));
+ ASSERT_EQUALS(md.peek().getNestedField(xxxyyyzzz), Value("nested") );
+
// Make sure nothing moved
ASSERT_EQUALS(apos, md.peek().positionOf("a"));
ASSERT_EQUALS(bpos, md.peek().positionOf("c"));
@@ -211,7 +236,7 @@ namespace DocumentTests {
}
size_t hash( const BSONObj& obj ) {
size_t seed = 0x106e1e1;
- fromBson( obj )->hash_combine( seed );
+ Document(obj).hash_combine(seed);
return seed;
}
};
@@ -237,29 +262,29 @@ namespace DocumentTests {
MutableDocument cloneOnDemand (document);
// Check equality.
- ASSERT_EQUALS( 0, Document::compare( document, cloneOnDemand.peek() ) );
+ ASSERT_EQUALS(document, cloneOnDemand.peek());
// Check pointer equality of sub document.
- ASSERT_EQUALS( document->getValue( "a" ).getDocument().getPtr(),
- cloneOnDemand.peek().getValue( "a" ).getDocument().getPtr() );
+ ASSERT_EQUALS( document["a"].getDocument().getPtr(),
+ cloneOnDemand.peek()["a"].getDocument().getPtr() );
// Change field in clone and ensure the original document's field is unchanged.
cloneOnDemand.setField( StringData("a"), Value(2) );
- ASSERT_EQUALS( Value(1), document->getNestedField(FieldPath("a.b")) );
+ ASSERT_EQUALS( Value(1), document.getNestedField(FieldPath("a.b")) );
// setNestedField and ensure the original document is unchanged.
cloneOnDemand.reset(document);
vector<Position> path;
- ASSERT_EQUALS( Value(1), document->getNestedField(FieldPath("a.b"), &path) );
+ ASSERT_EQUALS( Value(1), document.getNestedField(FieldPath("a.b"), &path) );
cloneOnDemand.setNestedField(path, Value(2));
ASSERT_EQUALS( Value(1), document.getNestedField(FieldPath("a.b")) );
ASSERT_EQUALS( Value(2), cloneOnDemand.peek().getNestedField(FieldPath("a.b")) );
- ASSERT_EQUALS( BSON( "a" << BSON( "b" << 1 ) ), toBson( document ) );
- ASSERT_EQUALS( BSON( "a" << BSON( "b" << 2 ) ), toBson( cloneOnDemand.freeze() ) );
+ ASSERT_EQUALS( DOC( "a" << DOC( "b" << 1 ) ), document );
+ ASSERT_EQUALS( DOC( "a" << DOC( "b" << 2 ) ), cloneOnDemand.freeze() );
}
};
@@ -269,8 +294,8 @@ namespace DocumentTests {
void run() {
Document document =
fromBson( fromjson( "{a:1,b:['ra',4],c:{z:1},d:'lal'}" ) );
- Document clonedDocument = document->clone();
- ASSERT_EQUALS( 0, Document::compare( document, clonedDocument ) );
+ Document clonedDocument = document.clone();
+ ASSERT_EQUALS(document, clonedDocument);
}
};
@@ -372,15 +397,21 @@ namespace DocumentTests {
// logical equality
ASSERT_EQUALS(obj, obj2);
- if (Document::compare(doc, doc2)) {
- PRINT(doc);
- PRINT(doc2);
- }
- ASSERT_EQUALS(Document::compare(doc, doc2), 0);
+ ASSERT_EQUALS(doc, doc2);
// binary equality
ASSERT_EQUALS(obj.objsize(), obj2.objsize());
ASSERT_EQUALS(memcmp(obj.objdata(), obj2.objdata(), obj.objsize()), 0);
+
+ // ensure sorter serialization round-trips correctly
+ BufBuilder bb;
+ doc.serializeForSorter(bb);
+ BufReader reader(bb.buf(), bb.len());
+ const Document doc3 = Document::deserializeForSorter(
+ reader, Document::SorterDeserializeSettings());
+ BSONObj obj3 = toBson(doc3);
+ ASSERT_EQUALS(obj.objsize(), obj3.objsize());
+ ASSERT_EQUALS(memcmp(obj.objdata(), obj3.objdata(), obj.objsize()), 0);
}
template <typename T>
@@ -413,7 +444,7 @@ namespace DocumentTests {
Value fromBson( const BSONObj& obj ) {
BSONElement element = obj.firstElement();
- return Value::createFromBsonElement( &element );
+ return Value( element );
}
void assertRoundTrips( const Value& value1 ) {
@@ -425,11 +456,19 @@ namespace DocumentTests {
ASSERT_EQUALS(value1.getType(), value2.getType());
}
+ class BSONArrayTest {
+ public:
+ void run() {
+ ASSERT_EQUALS(Value(BSON_ARRAY(1 << 2 << 3)), DOC_ARRAY(1 << 2 << 3));
+ ASSERT_EQUALS(Value(BSONArray()), Value(vector<Value>()));
+ }
+ };
+
/** Int type. */
class Int {
public:
void run() {
- Value value = Value::createInt( 5 );
+ Value value = Value( 5 );
ASSERT_EQUALS( 5, value.getInt() );
ASSERT_EQUALS( 5, value.getLong() );
ASSERT_EQUALS( 5, value.getDouble() );
@@ -442,7 +481,7 @@ namespace DocumentTests {
class Long {
public:
void run() {
- Value value = Value::createLong( 99 );
+ Value value = Value( 99LL );
ASSERT_EQUALS( 99, value.getLong() );
ASSERT_EQUALS( 99, value.getDouble() );
ASSERT_EQUALS( NumberLong, value.getType() );
@@ -454,7 +493,7 @@ namespace DocumentTests {
class Double {
public:
void run() {
- Value value = Value::createDouble( 5.5 );
+ Value value = Value( 5.5 );
ASSERT_EQUALS( 5.5, value.getDouble() );
ASSERT_EQUALS( NumberDouble, value.getType() );
assertRoundTrips( value );
@@ -465,7 +504,7 @@ namespace DocumentTests {
class String {
public:
void run() {
- Value value = Value::createString( "foo" );
+ Value value = Value( "foo" );
ASSERT_EQUALS( "foo", value.getString() );
ASSERT_EQUALS( mongo::String, value.getType() );
assertRoundTrips( value );
@@ -489,7 +528,7 @@ namespace DocumentTests {
class Date {
public:
void run() {
- Value value = Value::createDate(999);
+ Value value = Value(Date_t(999));
ASSERT_EQUALS( 999, value.getDate() );
ASSERT_EQUALS( mongo::Date, value.getType() );
assertRoundTrips( value );
@@ -500,7 +539,7 @@ namespace DocumentTests {
class Timestamp {
public:
void run() {
- Value value = Value::createTimestamp( OpTime( 777 ) );
+ Value value = Value( OpTime( 777 ) );
ASSERT( OpTime( 777 ) == value.getTimestamp() );
ASSERT_EQUALS( mongo::Timestamp, value.getType() );
assertRoundTrips( value );
@@ -512,7 +551,7 @@ namespace DocumentTests {
public:
void run() {
mongo::Document document = mongo::Document();
- Value value = Value::createDocument( document );
+ Value value = Value( document );
ASSERT_EQUALS( document.getPtr(), value.getDocument().getPtr() );
ASSERT_EQUALS( Object, value.getType() );
assertRoundTrips( value );
@@ -524,18 +563,18 @@ namespace DocumentTests {
public:
void run() {
mongo::MutableDocument md;
- md.addField( "a", Value::createInt( 5 ) );
- md.addField( "apple", Value::createString( "rrr" ) );
- md.addField( "banana", Value::createDouble( -.3 ) );
+ md.addField( "a", Value( 5 ) );
+ md.addField( "apple", Value( "rrr" ) );
+ md.addField( "banana", Value( -.3 ) );
mongo::Document document = md.freeze();
- Value value = Value::createDocument( document );
+ Value value = Value( document );
// Check document pointers are equal.
ASSERT_EQUALS( document.getPtr(), value.getDocument().getPtr() );
// Check document contents.
- ASSERT_EQUALS( 5, document->getValue( "a" ).getInt() );
- ASSERT_EQUALS( "rrr", document->getValue( "apple" ).getString() );
- ASSERT_EQUALS( -.3, document->getValue( "banana" ).getDouble() );
+ ASSERT_EQUALS( 5, document["a"].getInt() );
+ ASSERT_EQUALS( "rrr", document["apple"].getString() );
+ ASSERT_EQUALS( -.3, document["banana"].getDouble() );
ASSERT_EQUALS( Object, value.getType() );
assertRoundTrips( value );
}
@@ -561,10 +600,10 @@ namespace DocumentTests {
public:
void run() {
vector<Value> array;
- array.push_back( Value::createInt( 5 ) );
- array.push_back( Value::createString( "lala" ) );
- array.push_back( Value::createDouble( 3.14 ) );
- Value value = Value::createArray( array );
+ array.push_back( Value( 5 ) );
+ array.push_back( Value( "lala" ) );
+ array.push_back( Value( 3.14 ) );
+ Value value = Value( array );
const vector<Value>& array2 = value.getArray();
ASSERT( !array2.empty() );
@@ -627,7 +666,7 @@ namespace DocumentTests {
class Undefined {
public:
void run() {
- Value value = Value(mongo::Undefined);
+ Value value = Value(BSONUndefined);
ASSERT_EQUALS( mongo::Undefined, value.getType() );
assertRoundTrips( value );
}
@@ -637,7 +676,7 @@ namespace DocumentTests {
class Null {
public:
void run() {
- Value value = Value(mongo::jstNULL);
+ Value value = Value(BSONNULL);
ASSERT_EQUALS( jstNULL, value.getType() );
assertRoundTrips( value );
}
@@ -722,56 +761,56 @@ namespace DocumentTests {
/** Coerce 0 to bool. */
class ZeroIntToBool : public ToBoolFalse {
- Value value() { return Value::createInt( 0 ); }
+ Value value() { return Value( 0 ); }
};
/** Coerce -1 to bool. */
class NonZeroIntToBool : public ToBoolTrue {
- Value value() { return Value::createInt( -1 ); }
+ Value value() { return Value( -1 ); }
};
/** Coerce 0LL to bool. */
class ZeroLongToBool : public ToBoolFalse {
- Value value() { return Value::createLong( 0 ); }
+ Value value() { return Value( 0LL ); }
};
/** Coerce 5LL to bool. */
class NonZeroLongToBool : public ToBoolTrue {
- Value value() { return Value::createLong( 5 ); }
+ Value value() { return Value( 5LL ); }
};
/** Coerce 0.0 to bool. */
class ZeroDoubleToBool : public ToBoolFalse {
- Value value() { return Value::createDouble( 0 ); }
+ Value value() { return Value( 0 ); }
};
/** Coerce -1.3 to bool. */
class NonZeroDoubleToBool : public ToBoolTrue {
- Value value() { return Value::createDouble( -1.3 ); }
+ Value value() { return Value( -1.3 ); }
};
/** Coerce "" to bool. */
class StringToBool : public ToBoolTrue {
- Value value() { return Value::createString( "" ); }
+ Value value() { return Value( "" ); }
};
/** Coerce {} to bool. */
class ObjectToBool : public ToBoolTrue {
Value value() {
- return Value::createDocument( mongo::Document() );
+ return Value( mongo::Document() );
}
};
/** Coerce [] to bool. */
class ArrayToBool : public ToBoolTrue {
Value value() {
- return Value::createArray( vector<Value>() );
+ return Value( vector<Value>() );
}
};
/** Coerce Date(0) to bool. */
class DateToBool : public ToBoolTrue {
- Value value() { return Value::createDate(0); }
+ Value value() { return Value(Date_t(0)); }
};
/** Coerce js literal regex to bool. */
@@ -791,12 +830,12 @@ namespace DocumentTests {
/** Coerce null to bool. */
class NullToBool : public ToBoolFalse {
- Value value() { return Value(mongo::jstNULL); }
+ Value value() { return Value(BSONNULL); }
};
/** Coerce undefined to bool. */
class UndefinedToBool : public ToBoolFalse {
- Value value() { return Value(mongo::Undefined); }
+ Value value() { return Value(BSONUndefined); }
};
class ToIntBase {
@@ -817,31 +856,31 @@ namespace DocumentTests {
/** Coerce -5 to int. */
class IntToInt : public ToIntBase {
- Value value() { return Value::createInt( -5 ); }
+ Value value() { return Value( -5 ); }
int expected() { return -5; }
};
/** Coerce long to int. */
class LongToInt : public ToIntBase {
- Value value() { return Value::createLong( 0xff00000007LL ); }
+ Value value() { return Value( 0xff00000007LL ); }
int expected() { return 7; }
};
/** Coerce 9.8 to int. */
class DoubleToInt : public ToIntBase {
- Value value() { return Value::createDouble( 9.8 ); }
+ Value value() { return Value( 9.8 ); }
int expected() { return 9; }
};
/** Coerce null to int. */
class NullToInt : public ToIntBase {
- Value value() { return Value(mongo::jstNULL); }
+ Value value() { return Value(BSONNULL); }
bool asserts() { return true; }
};
/** Coerce undefined to int. */
class UndefinedToInt : public ToIntBase {
- Value value() { return Value(mongo::Undefined); }
+ Value value() { return Value(BSONUndefined); }
bool asserts() { return true; }
};
@@ -849,7 +888,7 @@ namespace DocumentTests {
class StringToInt {
public:
void run() {
- ASSERT_THROWS( Value::createString( "" ).coerceToInt(), UserException );
+ ASSERT_THROWS( Value( "" ).coerceToInt(), UserException );
}
};
@@ -871,31 +910,31 @@ namespace DocumentTests {
/** Coerce -5 to long. */
class IntToLong : public ToLongBase {
- Value value() { return Value::createInt( -5 ); }
+ Value value() { return Value( -5 ); }
long long expected() { return -5; }
};
/** Coerce long to long. */
class LongToLong : public ToLongBase {
- Value value() { return Value::createLong( 0xff00000007LL ); }
+ Value value() { return Value( 0xff00000007LL ); }
long long expected() { return 0xff00000007LL; }
};
/** Coerce 9.8 to long. */
class DoubleToLong : public ToLongBase {
- Value value() { return Value::createDouble( 9.8 ); }
+ Value value() { return Value( 9.8 ); }
long long expected() { return 9; }
};
/** Coerce null to long. */
class NullToLong : public ToLongBase {
- Value value() { return Value(mongo::jstNULL); }
+ Value value() { return Value(BSONNULL); }
bool asserts() { return true; }
};
/** Coerce undefined to long. */
class UndefinedToLong : public ToLongBase {
- Value value() { return Value(mongo::Undefined); }
+ Value value() { return Value(BSONUndefined); }
bool asserts() { return true; }
};
@@ -903,7 +942,7 @@ namespace DocumentTests {
class StringToLong {
public:
void run() {
- ASSERT_THROWS( Value::createString( "" ).coerceToLong(), UserException );
+ ASSERT_THROWS( Value( "" ).coerceToLong(), UserException );
}
};
@@ -925,7 +964,7 @@ namespace DocumentTests {
/** Coerce -5 to double. */
class IntToDouble : public ToDoubleBase {
- Value value() { return Value::createInt( -5 ); }
+ Value value() { return Value( -5 ); }
double expected() { return -5; }
};
@@ -933,26 +972,26 @@ namespace DocumentTests {
class LongToDouble : public ToDoubleBase {
Value value() {
// A long that cannot be exactly represented as a double.
- return Value::createDouble( static_cast<double>( 0x8fffffffffffffffLL ) );
+ return Value( static_cast<double>( 0x8fffffffffffffffLL ) );
}
double expected() { return static_cast<double>( 0x8fffffffffffffffLL ); }
};
/** Coerce double to double. */
class DoubleToDouble : public ToDoubleBase {
- Value value() { return Value::createDouble( 9.8 ); }
+ Value value() { return Value( 9.8 ); }
double expected() { return 9.8; }
};
/** Coerce null to double. */
class NullToDouble : public ToDoubleBase {
- Value value() { return Value(mongo::jstNULL); }
+ Value value() { return Value(BSONNULL); }
bool asserts() { return true; }
};
/** Coerce undefined to double. */
class UndefinedToDouble : public ToDoubleBase {
- Value value() { return Value(mongo::Undefined); }
+ Value value() { return Value(BSONUndefined); }
bool asserts() { return true; }
};
@@ -960,7 +999,7 @@ namespace DocumentTests {
class StringToDouble {
public:
void run() {
- ASSERT_THROWS( Value::createString( "" ).coerceToDouble(), UserException );
+ ASSERT_THROWS( Value( "" ).coerceToDouble(), UserException );
}
};
@@ -978,7 +1017,7 @@ namespace DocumentTests {
/** Coerce date to date. */
class DateToDate : public ToDateBase {
- Value value() { return Value::createDate(888); }
+ Value value() { return Value(Date_t(888)); }
long long expected() { return 888; }
};
@@ -988,7 +1027,7 @@ namespace DocumentTests {
*/
class TimestampToDate : public ToDateBase {
Value value() {
- return Value::createTimestamp( OpTime( 777, 666 ) );
+ return Value( OpTime( 777, 666 ) );
}
long long expected() { return 777 * 1000; }
};
@@ -997,7 +1036,7 @@ namespace DocumentTests {
class StringToDate {
public:
void run() {
- ASSERT_THROWS( Value::createString( "" ).coerceToDate(), UserException );
+ ASSERT_THROWS( Value( "" ).coerceToDate(), UserException );
}
};
@@ -1015,57 +1054,57 @@ namespace DocumentTests {
/** Coerce -0.2 to string. */
class DoubleToString : public ToStringBase {
- Value value() { return Value::createDouble( -0.2 ); }
+ Value value() { return Value( -0.2 ); }
string expected() { return "-0.2"; }
};
/** Coerce -4 to string. */
class IntToString : public ToStringBase {
- Value value() { return Value::createInt( -4 ); }
+ Value value() { return Value( -4 ); }
string expected() { return "-4"; }
};
/** Coerce 10000LL to string. */
class LongToString : public ToStringBase {
- Value value() { return Value::createLong( 10000 ); }
+ Value value() { return Value( 10000LL ); }
string expected() { return "10000"; }
};
/** Coerce string to string. */
class StringToString : public ToStringBase {
- Value value() { return Value::createString( "fO_o" ); }
+ Value value() { return Value( "fO_o" ); }
string expected() { return "fO_o"; }
};
/** Coerce timestamp to string. */
class TimestampToString : public ToStringBase {
Value value() {
- return Value::createTimestamp( OpTime( 1, 2 ) );
+ return Value( OpTime( 1, 2 ) );
}
string expected() { return OpTime( 1, 2 ).toStringPretty(); }
};
/** Coerce date to string. */
class DateToString : public ToStringBase {
- Value value() { return Value::createDate(1234567890LL*1000); }
+ Value value() { return Value(Date_t(1234567890LL*1000)); }
string expected() { return "2009-02-13T23:31:30"; } // from js
};
/** Coerce null to string. */
class NullToString : public ToStringBase {
- Value value() { return Value(mongo::jstNULL); }
+ Value value() { return Value(BSONNULL); }
};
/** Coerce undefined to string. */
class UndefinedToString : public ToStringBase {
- Value value() { return Value(mongo::Undefined); }
+ Value value() { return Value(BSONUndefined); }
};
/** Coerce document to string unsupported. */
class DocumentToString {
public:
void run() {
- ASSERT_THROWS( Value::createDocument
+ ASSERT_THROWS( Value
( mongo::Document() ).coerceToString(),
UserException );
}
@@ -1075,7 +1114,7 @@ namespace DocumentTests {
class TimestampToTimestamp {
public:
void run() {
- Value value = Value::createTimestamp( OpTime( 1010 ) );
+ Value value = Value( OpTime( 1010 ) );
ASSERT( OpTime( 1010 ) == value.coerceToTimestamp() );
}
};
@@ -1084,7 +1123,7 @@ namespace DocumentTests {
class DateToTimestamp {
public:
void run() {
- ASSERT_THROWS( Value::createDate(1010).coerceToTimestamp(),
+ ASSERT_THROWS( Value(Date_t(1010)).coerceToTimestamp(),
UserException );
}
};
@@ -1134,9 +1173,9 @@ namespace DocumentTests {
public:
void run() {
BSONObjBuilder bob;
- Value::createDouble( 4.4 ).addToBsonObj( &bob, "a" );
- Value::createInt( 22 ).addToBsonObj( &bob, "b" );
- Value::createString( "astring" ).addToBsonObj( &bob, "c" );
+ Value( 4.4 ).addToBsonObj( &bob, "a" );
+ Value( 22 ).addToBsonObj( &bob, "b" );
+ Value( "astring" ).addToBsonObj( &bob, "c" );
ASSERT_EQUALS( BSON( "a" << 4.4 << "b" << 22 << "c" << "astring" ), bob.obj() );
}
};
@@ -1146,9 +1185,9 @@ namespace DocumentTests {
public:
void run() {
BSONArrayBuilder bab;
- Value::createDouble( 4.4 ).addToBsonArray( &bab );
- Value::createInt( 22 ).addToBsonArray( &bab );
- Value::createString( "astring" ).addToBsonArray( &bab );
+ Value( 4.4 ).addToBsonArray( &bab );
+ Value( 22 ).addToBsonArray( &bab );
+ Value( "astring" ).addToBsonArray( &bab );
ASSERT_EQUALS( BSON_ARRAY( 4.4 << 22 << "astring" ), bab.arr() );
}
};
@@ -1240,17 +1279,17 @@ namespace DocumentTests {
// Cross-type comparisons. Listed in order of canonical types.
assertComparison(-1, Value(mongo::MINKEY), Value());
- assertComparison(0, Value(), Value(mongo::EOO));
- assertComparison(0, Value(), Value(mongo::Undefined));
- assertComparison(-1, Value(mongo::Undefined), Value(mongo::jstNULL));
- assertComparison(-1, Value(mongo::jstNULL), Value(1));
+ assertComparison(0, Value(), Value());
+ assertComparison(0, Value(), Value(BSONUndefined));
+ assertComparison(-1, Value(BSONUndefined), Value(BSONNULL));
+ assertComparison(-1, Value(BSONNULL), Value(1));
assertComparison(0, Value(1), Value(1LL));
assertComparison(0, Value(1), Value(1.0));
assertComparison(-1, Value(1), Value("string"));
assertComparison(0, Value("string"), Value(BSONSymbol("string")));
assertComparison(-1, Value("string"), Value(mongo::Document()));
- assertComparison(-1, Value(mongo::Document()), Value(mongo::Array));
- assertComparison(-1, Value(mongo::Array), Value(BSONBinData("", 0, MD5Type)));
+ assertComparison(-1, Value(mongo::Document()), Value(vector<Value>()));
+ assertComparison(-1, Value(vector<Value>()), Value(BSONBinData("", 0, MD5Type)));
assertComparison(-1, Value(BSONBinData("", 0, MD5Type)), Value(mongo::OID()));
assertComparison(-1, Value(mongo::OID()), Value(false));
assertComparison(-1, Value(false), Value(OpTime()));
@@ -1285,7 +1324,8 @@ namespace DocumentTests {
assertComparison(expectedResult, fromBson(a), fromBson(b));
}
void assertComparison(int expectedResult, const Value& a, const Value& b) {
- log() << "testing " << a.toString() << " and " << b.toString() << endl;
+ mongo::unittest::log() <<
+ "testing " << a.toString() << " and " << b.toString() << endl;
// reflexivity
ASSERT_EQUALS(0, cmp(a, a));
ASSERT_EQUALS(0, cmp(b, b));
@@ -1294,10 +1334,15 @@ namespace DocumentTests {
ASSERT_EQUALS( expectedResult, cmp( a, b ) );
ASSERT_EQUALS( -expectedResult, cmp( b, a ) );
- // equal values must hash equally.
if ( expectedResult == 0 ) {
+ // equal values must hash equally.
ASSERT_EQUALS( hash( a ), hash( b ) );
}
+ else {
+ // unequal values must hash unequally.
+ // (not true in general but we should error if it fails in any of these cases)
+ ASSERT_NOT_EQUALS( hash( a ), hash( b ) );
+ }
// same as BSON
ASSERT_EQUALS(expectedResult, sign(toBson(a).firstElement().woCompare(
@@ -1342,6 +1387,27 @@ namespace DocumentTests {
}
};
+
+ class SerializationOfMissingForSorter {
+ // Can't be tested in AllTypesDoc since missing values are omitted when adding to BSON.
+ public:
+ void run() {
+ const Value missing;
+ const Value arrayOfMissing = Value(vector<Value>(10));
+
+ BufBuilder bb;
+ missing.serializeForSorter(bb);
+ arrayOfMissing.serializeForSorter(bb);
+
+ BufReader reader(bb.buf(), bb.len());
+ ASSERT_EQUALS(
+ missing,
+ Value::deserializeForSorter(reader, Value::SorterDeserializeSettings()));
+ ASSERT_EQUALS(
+ arrayOfMissing,
+ Value::deserializeForSorter(reader, Value::SorterDeserializeSettings()));
+ }
+ };
} // namespace Value
class All : public Suite {
@@ -1363,6 +1429,7 @@ namespace DocumentTests {
add<Document::FieldIteratorMultiple>();
add<Document::AllTypesDoc>();
+ add<Value::BSONArrayTest>();
add<Value::Int>();
add<Value::Long>();
add<Value::Double>();
@@ -1438,6 +1505,7 @@ namespace DocumentTests {
add<Value::AddToBsonArray>();
add<Value::Compare>();
add<Value::SubFields>();
+ add<Value::SerializationOfMissingForSorter>();
}
} myall;