2009-04-23 20:28:22 +02:00
// javajstests.cpp
2009-02-03 06:14:14 +01:00
//
/**
* Copyright ( C ) 2009 10 gen Inc .
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License , version 3 ,
* as published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Affero General Public License for more details .
*
* 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/>.
*/
2009-09-30 20:32:17 +02:00
# include "stdafx.h"
2009-05-27 23:40:20 +02:00
# include "../db/instance.h"
# include "../stdafx.h"
2009-04-23 20:28:22 +02:00
# include "../scripting/engine.h"
2009-02-03 06:14:14 +01:00
# include "dbtests.h"
2010-01-25 23:07:02 +01:00
# include "util/base64.h"
2009-05-27 21:40:57 +02:00
namespace mongo {
bool dbEval ( const char * ns , BSONObj & cmd , BSONObjBuilder & result , string & errmsg ) ;
} // namespace mongo
2009-04-24 04:44:19 +02:00
namespace JSTests {
2009-06-03 19:18:50 +02:00
2009-02-03 06:14:14 +01:00
class Fundamental {
public :
void run ( ) {
2009-02-03 17:50:30 +01:00
// By calling JavaJSImpl() inside run(), we ensure the unit test framework's
// signal handlers are pre-installed from JNI's perspective. This allows
// JNI to catch signals generated within the JVM and forward other signals
// as appropriate.
2009-04-23 20:28:22 +02:00
ScriptEngine : : setup ( ) ;
globalScriptEngine - > runTest ( ) ;
2009-02-03 06:14:14 +01:00
}
} ;
2009-04-24 04:44:19 +02:00
class BasicScope {
public :
void run ( ) {
2009-10-10 07:30:00 +02:00
auto_ptr < Scope > s ;
2009-12-30 03:27:49 +01:00
s . reset ( globalScriptEngine - > newScope ( ) ) ;
2009-10-10 07:30:00 +02:00
2009-04-24 04:44:19 +02:00
s - > setNumber ( " x " , 5 ) ;
2009-09-30 16:08:58 +02:00
ASSERT ( 5 = = s - > getNumber ( " x " ) ) ;
2009-10-10 07:30:00 +02:00
2009-04-24 04:44:19 +02:00
s - > setNumber ( " x " , 1.67 ) ;
2009-09-30 16:08:58 +02:00
ASSERT ( 1.67 = = s - > getNumber ( " x " ) ) ;
2009-04-24 04:44:19 +02:00
s - > setString ( " s " , " eliot was here " ) ;
2009-09-30 16:08:58 +02:00
ASSERT ( " eliot was here " = = s - > getString ( " s " ) ) ;
2009-04-24 04:44:19 +02:00
s - > setBoolean ( " b " , true ) ;
2009-09-30 16:08:58 +02:00
ASSERT ( s - > getBoolean ( " b " ) ) ;
2009-04-24 04:44:19 +02:00
if ( 0 ) {
s - > setBoolean ( " b " , false ) ;
2009-09-30 16:08:58 +02:00
ASSERT ( ! s - > getBoolean ( " b " ) ) ;
2009-04-24 04:44:19 +02:00
}
}
} ;
2009-04-24 05:52:47 +02:00
2009-12-29 20:04:00 +01:00
class ResetScope {
public :
void run ( ) {
// Not worrying about this for now SERVER-446.
/*
auto_ptr < Scope > s ;
2009-12-30 03:27:49 +01:00
s . reset ( globalScriptEngine - > newScope ( ) ) ;
2009-12-29 20:04:00 +01:00
s - > setBoolean ( " x " , true ) ;
ASSERT ( s - > getBoolean ( " x " ) ) ;
s - > reset ( ) ;
ASSERT ( ! s - > getBoolean ( " x " ) ) ;
*/
}
} ;
2009-04-24 05:52:47 +02:00
class FalseTests {
public :
void run ( ) {
2009-12-30 03:27:49 +01:00
Scope * s = globalScriptEngine - > newScope ( ) ;
2009-04-24 05:52:47 +02:00
2009-09-30 16:08:58 +02:00
ASSERT ( ! s - > getBoolean ( " x " ) ) ;
2009-04-24 05:52:47 +02:00
s - > setString ( " z " , " " ) ;
2009-09-30 16:08:58 +02:00
ASSERT ( ! s - > getBoolean ( " z " ) ) ;
2009-04-24 05:52:47 +02:00
delete s ;
}
} ;
2009-04-24 22:41:40 +02:00
class SimpleFunctions {
public :
void run ( ) {
2009-12-30 03:27:49 +01:00
Scope * s = globalScriptEngine - > newScope ( ) ;
2009-04-24 22:41:40 +02:00
s - > invoke ( " x=5; " , BSONObj ( ) ) ;
2009-09-30 16:08:58 +02:00
ASSERT ( 5 = = s - > getNumber ( " x " ) ) ;
2009-04-24 22:41:40 +02:00
s - > invoke ( " return 17; " , BSONObj ( ) ) ;
2009-09-30 16:08:58 +02:00
ASSERT ( 17 = = s - > getNumber ( " return " ) ) ;
2009-04-24 22:41:40 +02:00
s - > invoke ( " function(){ return 17; } " , BSONObj ( ) ) ;
2009-09-30 16:08:58 +02:00
ASSERT ( 17 = = s - > getNumber ( " return " ) ) ;
2009-04-24 22:41:40 +02:00
s - > setNumber ( " x " , 1.76 ) ;
s - > invoke ( " return x == 1.76; " , BSONObj ( ) ) ;
2009-09-30 16:08:58 +02:00
ASSERT ( s - > getBoolean ( " return " ) ) ;
2009-04-24 22:41:40 +02:00
s - > setNumber ( " x " , 1.76 ) ;
s - > invoke ( " return x == 1.79; " , BSONObj ( ) ) ;
2009-09-30 16:08:58 +02:00
ASSERT ( ! s - > getBoolean ( " return " ) ) ;
2009-10-11 04:41:21 +02:00
s - > invoke ( " function( z ){ return 5 + z; } " , BSON ( " " < < 11 ) ) ;
ASSERT_EQUALS ( 16 , s - > getNumber ( " return " ) ) ;
2009-04-24 22:41:40 +02:00
delete s ;
}
} ;
2009-04-24 23:19:24 +02:00
class ObjectMapping {
public :
void run ( ) {
2009-12-30 03:27:49 +01:00
Scope * s = globalScriptEngine - > newScope ( ) ;
2009-04-24 23:19:24 +02:00
2009-04-29 17:12:35 +02:00
BSONObj o = BSON ( " x " < < 17 < < " y " < < " eliot " < < " z " < < " sara " ) ;
2009-04-24 23:19:24 +02:00
s - > setObject ( " blah " , o ) ;
2009-04-29 16:29:56 +02:00
2009-04-25 03:27:25 +02:00
s - > invoke ( " return blah.x; " , BSONObj ( ) ) ;
2009-04-29 16:16:39 +02:00
ASSERT_EQUALS ( 17 , s - > getNumber ( " return " ) ) ;
2009-04-29 16:29:56 +02:00
s - > invoke ( " return blah.y; " , BSONObj ( ) ) ;
ASSERT_EQUALS ( " eliot " , s - > getString ( " return " ) ) ;
2009-04-24 23:19:24 +02:00
2009-04-29 17:12:35 +02:00
s - > setThis ( & o ) ;
s - > invoke ( " return this.z; " , BSONObj ( ) ) ;
ASSERT_EQUALS ( " sara " , s - > getString ( " return " ) ) ;
2009-05-14 22:50:14 +02:00
2009-10-12 03:35:39 +02:00
s - > invoke ( " return this.z == 'sara'; " , BSONObj ( ) ) ;
ASSERT_EQUALS ( true , s - > getBoolean ( " return " ) ) ;
2009-05-14 22:50:14 +02:00
s - > invoke ( " this.z == 'sara'; " , BSONObj ( ) ) ;
ASSERT_EQUALS ( true , s - > getBoolean ( " return " ) ) ;
s - > invoke ( " this.z == 'asara'; " , BSONObj ( ) ) ;
ASSERT_EQUALS ( false , s - > getBoolean ( " return " ) ) ;
2009-04-29 21:45:11 +02:00
s - > invoke ( " return this.x == 17; " , BSONObj ( ) ) ;
ASSERT_EQUALS ( true , s - > getBoolean ( " return " ) ) ;
s - > invoke ( " return this.x == 18; " , BSONObj ( ) ) ;
ASSERT_EQUALS ( false , s - > getBoolean ( " return " ) ) ;
s - > invoke ( " function(){ return this.x == 17; } " , BSONObj ( ) ) ;
ASSERT_EQUALS ( true , s - > getBoolean ( " return " ) ) ;
2009-04-29 17:12:35 +02:00
2009-04-29 21:45:11 +02:00
s - > invoke ( " function(){ return this.x == 18; } " , BSONObj ( ) ) ;
ASSERT_EQUALS ( false , s - > getBoolean ( " return " ) ) ;
s - > invoke ( " function (){ return this.x == 17; } " , BSONObj ( ) ) ;
ASSERT_EQUALS ( true , s - > getBoolean ( " return " ) ) ;
2009-05-21 16:05:26 +02:00
2009-05-06 21:30:05 +02:00
s - > invoke ( " function z(){ return this.x == 18; } " , BSONObj ( ) ) ;
ASSERT_EQUALS ( false , s - > getBoolean ( " return " ) ) ;
2009-05-21 16:05:26 +02:00
2009-10-12 03:35:39 +02:00
s - > invoke ( " function (){ this.x == 17; } " , BSONObj ( ) ) ;
ASSERT_EQUALS ( false , s - > getBoolean ( " return " ) ) ;
s - > invoke ( " function z(){ this.x == 18; } " , BSONObj ( ) ) ;
ASSERT_EQUALS ( false , s - > getBoolean ( " return " ) ) ;
2009-05-21 16:05:26 +02:00
s - > invoke ( " x = 5; for( ; x <10; x++){ a = 1; } " , BSONObj ( ) ) ;
ASSERT_EQUALS ( 10 , s - > getNumber ( " x " ) ) ;
2009-04-29 17:12:35 +02:00
2009-04-24 23:19:24 +02:00
delete s ;
}
} ;
2009-05-06 17:53:39 +02:00
class ObjectDecoding {
public :
void run ( ) {
2009-12-30 03:27:49 +01:00
Scope * s = globalScriptEngine - > newScope ( ) ;
2009-05-06 17:53:39 +02:00
s - > invoke ( " z = { num : 1 }; " , BSONObj ( ) ) ;
BSONObj out = s - > getObject ( " z " ) ;
ASSERT_EQUALS ( 1 , out [ " num " ] . number ( ) ) ;
ASSERT_EQUALS ( 1 , out . nFields ( ) ) ;
s - > invoke ( " z = { x : 'eliot' }; " , BSONObj ( ) ) ;
out = s - > getObject ( " z " ) ;
ASSERT_EQUALS ( ( string ) " eliot " , out [ " x " ] . valuestr ( ) ) ;
ASSERT_EQUALS ( 1 , out . nFields ( ) ) ;
BSONObj o = BSON ( " x " < < 17 ) ;
s - > setObject ( " blah " , o ) ;
2009-05-06 18:48:19 +02:00
out = s - > getObject ( " blah " ) ;
ASSERT_EQUALS ( 17 , out [ " x " ] . number ( ) ) ;
2009-05-06 17:53:39 +02:00
delete s ;
}
} ;
2009-04-24 04:44:19 +02:00
2009-05-08 17:02:12 +02:00
class JSOIDTests {
public :
void run ( ) {
2009-05-08 23:04:07 +02:00
# ifdef MOZJS
2009-12-30 03:27:49 +01:00
Scope * s = globalScriptEngine - > newScope ( ) ;
2009-05-08 17:02:12 +02:00
s - > localConnect ( " blah " ) ;
s - > invoke ( " z = { _id : new ObjectId() , a : 123 }; " , BSONObj ( ) ) ;
BSONObj out = s - > getObject ( " z " ) ;
ASSERT_EQUALS ( 123 , out [ " a " ] . number ( ) ) ;
ASSERT_EQUALS ( jstOID , out [ " _id " ] . type ( ) ) ;
OID save = out [ " _id " ] . __oid ( ) ;
s - > setObject ( " a " , out ) ;
s - > invoke ( " y = { _id : a._id , a : 124 }; " , BSONObj ( ) ) ;
out = s - > getObject ( " y " ) ;
ASSERT_EQUALS ( 124 , out [ " a " ] . number ( ) ) ;
ASSERT_EQUALS ( jstOID , out [ " _id " ] . type ( ) ) ;
ASSERT_EQUALS ( out [ " _id " ] . __oid ( ) . str ( ) , save . str ( ) ) ;
s - > invoke ( " y = { _id : new ObjectId( a._id ) , a : 125 }; " , BSONObj ( ) ) ;
out = s - > getObject ( " y " ) ;
ASSERT_EQUALS ( 125 , out [ " a " ] . number ( ) ) ;
ASSERT_EQUALS ( jstOID , out [ " _id " ] . type ( ) ) ;
ASSERT_EQUALS ( out [ " _id " ] . __oid ( ) . str ( ) , save . str ( ) ) ;
delete s ;
2009-05-08 23:22:01 +02:00
# endif
2009-05-08 17:02:12 +02:00
}
} ;
2009-12-15 20:22:19 +01:00
class SetImplicit {
public :
void run ( ) {
2009-12-30 03:27:49 +01:00
Scope * s = globalScriptEngine - > newScope ( ) ;
2009-12-15 20:22:19 +01:00
BSONObj o = BSON ( " foo " < < " bar " ) ;
s - > setObject ( " a.b " , o ) ;
ASSERT ( s - > getObject ( " a " ) . isEmpty ( ) ) ;
BSONObj o2 = BSONObj ( ) ;
s - > setObject ( " a " , o2 ) ;
s - > setObject ( " a.b " , o ) ;
ASSERT ( s - > getObject ( " a " ) . isEmpty ( ) ) ;
o2 = fromjson ( " {b:{}} " ) ;
s - > setObject ( " a " , o2 ) ;
s - > setObject ( " a.b " , o ) ;
ASSERT ( ! s - > getObject ( " a " ) . isEmpty ( ) ) ;
}
} ;
class ObjectModReadonlyTests {
2009-05-10 04:07:36 +02:00
public :
void run ( ) {
2009-12-30 03:27:49 +01:00
Scope * s = globalScriptEngine - > newScope ( ) ;
2009-05-10 04:07:36 +02:00
2009-12-15 20:22:19 +01:00
BSONObj o = BSON ( " x " < < 17 < < " y " < < " eliot " < < " z " < < " sara " < < " zz " < < BSONObj ( ) ) ;
2009-05-10 04:07:36 +02:00
s - > setObject ( " blah " , o , true ) ;
2009-12-16 00:52:41 +01:00
s - > invoke ( " blah.y = 'e' " , BSONObj ( ) ) ;
2009-05-10 04:07:36 +02:00
BSONObj out = s - > getObject ( " blah " ) ;
2009-12-16 00:52:41 +01:00
ASSERT ( strlen ( out [ " y " ] . valuestr ( ) ) > 1 ) ;
s - > invoke ( " blah.a = 19; " , BSONObj ( ) ) ;
out = s - > getObject ( " blah " ) ;
2009-05-10 04:07:36 +02:00
ASSERT ( out [ " a " ] . eoo ( ) ) ;
2009-12-15 20:22:19 +01:00
s - > invoke ( " blah.zz.a = 19; " , BSONObj ( ) ) ;
out = s - > getObject ( " blah " ) ;
ASSERT ( out [ " zz " ] . embeddedObject ( ) [ " a " ] . eoo ( ) ) ;
s - > setObject ( " blah.zz " , BSON ( " a " < < 19 ) ) ;
out = s - > getObject ( " blah " ) ;
ASSERT ( out [ " zz " ] . embeddedObject ( ) [ " a " ] . eoo ( ) ) ;
2009-12-16 00:52:41 +01:00
s - > invoke ( " delete blah['x'] " , BSONObj ( ) ) ;
out = s - > getObject ( " blah " ) ;
ASSERT ( ! out [ " x " ] . eoo ( ) ) ;
// read-only object itself can be overwritten
s - > invoke ( " blah = {} " , BSONObj ( ) ) ;
out = s - > getObject ( " blah " ) ;
ASSERT ( out . isEmpty ( ) ) ;
2009-12-16 23:49:22 +01:00
// test array - can't implement this in v8
// o = fromjson( "{a:[1,2,3]}" );
// s->setObject( "blah", o, true );
// out = s->getObject( "blah" );
// s->invoke( "blah.a[ 0 ] = 4;", BSONObj() );
// s->invoke( "delete blah['a'][ 2 ];", BSONObj() );
// out = s->getObject( "blah" );
// ASSERT_EQUALS( 1.0, out[ "a" ].embeddedObject()[ 0 ].number() );
// ASSERT_EQUALS( 3.0, out[ "a" ].embeddedObject()[ 2 ].number() );
2009-12-16 00:52:41 +01:00
2009-05-10 04:07:36 +02:00
delete s ;
}
} ;
2009-05-14 21:34:14 +02:00
class OtherJSTypes {
public :
void run ( ) {
2009-12-30 03:27:49 +01:00
Scope * s = globalScriptEngine - > newScope ( ) ;
2009-05-14 21:34:14 +02:00
{ // date
BSONObj o ;
{
BSONObjBuilder b ;
b . appendDate ( " d " , 123456789 ) ;
o = b . obj ( ) ;
}
s - > setObject ( " x " , o ) ;
s - > invoke ( " return x.d.getTime() != 12; " , BSONObj ( ) ) ;
ASSERT_EQUALS ( true , s - > getBoolean ( " return " ) ) ;
s - > invoke ( " z = x.d.getTime(); " , BSONObj ( ) ) ;
ASSERT_EQUALS ( 123456789 , s - > getNumber ( " z " ) ) ;
2009-05-14 21:48:53 +02:00
s - > invoke ( " z = { z : x.d } " , BSONObj ( ) ) ;
BSONObj out = s - > getObject ( " z " ) ;
ASSERT ( out [ " z " ] . type ( ) = = Date ) ;
2009-05-14 21:34:14 +02:00
}
2009-05-14 21:48:53 +02:00
{ // regex
BSONObj o ;
{
BSONObjBuilder b ;
b . appendRegex ( " r " , " ^a " , " i " ) ;
o = b . obj ( ) ;
}
s - > setObject ( " x " , o ) ;
s - > invoke ( " z = x.r.test( 'b' ); " , BSONObj ( ) ) ;
ASSERT_EQUALS ( false , s - > getBoolean ( " z " ) ) ;
s - > invoke ( " z = x.r.test( 'a' ); " , BSONObj ( ) ) ;
ASSERT_EQUALS ( true , s - > getBoolean ( " z " ) ) ;
2009-05-14 21:34:14 +02:00
2009-05-14 21:48:53 +02:00
s - > invoke ( " z = x.r.test( 'ba' ); " , BSONObj ( ) ) ;
ASSERT_EQUALS ( false , s - > getBoolean ( " z " ) ) ;
s - > invoke ( " z = { a : x.r }; " , BSONObj ( ) ) ;
2009-05-14 21:34:14 +02:00
2009-05-14 22:11:01 +02:00
BSONObj out = s - > getObject ( " z " ) ;
ASSERT_EQUALS ( ( string ) " ^a " , out [ " a " ] . regex ( ) ) ;
ASSERT_EQUALS ( ( string ) " i " , out [ " a " ] . regexFlags ( ) ) ;
2009-05-14 21:48:53 +02:00
}
2009-12-16 03:03:29 +01:00
// array
{
BSONObj o = fromjson ( " {r:[1,2,3]} " ) ;
2009-12-16 18:31:56 +01:00
s - > setObject ( " x " , o , false ) ;
2009-12-16 03:03:29 +01:00
BSONObj out = s - > getObject ( " x " ) ;
ASSERT_EQUALS ( Array , out . firstElement ( ) . type ( ) ) ;
2009-12-16 18:31:56 +01:00
s - > setObject ( " x " , o , true ) ;
out = s - > getObject ( " x " ) ;
ASSERT_EQUALS ( Array , out . firstElement ( ) . type ( ) ) ;
2009-12-16 03:03:29 +01:00
}
2009-05-14 21:34:14 +02:00
delete s ;
}
} ;
2009-05-15 14:31:11 +02:00
class SpecialDBTypes {
public :
void run ( ) {
2009-12-30 03:27:49 +01:00
Scope * s = globalScriptEngine - > newScope ( ) ;
2009-05-15 14:31:11 +02:00
BSONObjBuilder b ;
b . appendTimestamp ( " a " , 123456789 ) ;
b . appendMinKey ( " b " ) ;
b . appendMaxKey ( " c " ) ;
b . appendTimestamp ( " d " , 1234000 , 9876 ) ;
{
BSONObj t = b . done ( ) ;
2009-05-15 19:32:31 +02:00
ASSERT_EQUALS ( 1234000U , t [ " d " ] . timestampTime ( ) ) ;
ASSERT_EQUALS ( 9876U , t [ " d " ] . timestampInc ( ) ) ;
2009-05-15 14:31:11 +02:00
}
2009-05-15 15:19:13 +02:00
2009-05-15 14:31:11 +02:00
s - > setObject ( " z " , b . obj ( ) ) ;
2009-09-30 16:08:58 +02:00
ASSERT ( s - > invoke ( " y = { a : z.a , b : z.b , c : z.c , d: z.d } " , BSONObj ( ) ) = = 0 ) ;
2009-05-15 14:31:11 +02:00
BSONObj out = s - > getObject ( " y " ) ;
ASSERT_EQUALS ( Timestamp , out [ " a " ] . type ( ) ) ;
ASSERT_EQUALS ( MinKey , out [ " b " ] . type ( ) ) ;
ASSERT_EQUALS ( MaxKey , out [ " c " ] . type ( ) ) ;
2009-05-15 15:19:13 +02:00
ASSERT_EQUALS ( Timestamp , out [ " d " ] . type ( ) ) ;
2009-05-15 14:31:11 +02:00
2009-05-15 19:32:31 +02:00
ASSERT_EQUALS ( 9876U , out [ " d " ] . timestampInc ( ) ) ;
ASSERT_EQUALS ( 1234000U , out [ " d " ] . timestampTime ( ) ) ;
ASSERT_EQUALS ( 123456789U , out [ " a " ] . date ( ) ) ;
2009-05-15 14:31:11 +02:00
delete s ;
}
} ;
2009-05-22 16:48:05 +02:00
class TypeConservation {
public :
void run ( ) {
2009-12-30 03:27:49 +01:00
Scope * s = globalScriptEngine - > newScope ( ) ;
2009-05-22 16:48:05 +02:00
// -- A --
BSONObj o ;
{
BSONObjBuilder b ;
b . append ( " a " , ( int ) 5 ) ;
b . append ( " b " , 5.6 ) ;
o = b . obj ( ) ;
}
ASSERT_EQUALS ( NumberInt , o [ " a " ] . type ( ) ) ;
ASSERT_EQUALS ( NumberDouble , o [ " b " ] . type ( ) ) ;
s - > setObject ( " z " , o ) ;
s - > invoke ( " return z " , BSONObj ( ) ) ;
BSONObj out = s - > getObject ( " return " ) ;
ASSERT_EQUALS ( 5 , out [ " a " ] . number ( ) ) ;
ASSERT_EQUALS ( 5.6 , out [ " b " ] . number ( ) ) ;
2009-05-15 14:31:11 +02:00
2009-05-22 16:48:05 +02:00
ASSERT_EQUALS ( NumberDouble , out [ " b " ] . type ( ) ) ;
ASSERT_EQUALS ( NumberInt , out [ " a " ] . type ( ) ) ;
// -- B --
{
BSONObjBuilder b ;
b . append ( " a " , ( int ) 5 ) ;
b . append ( " b " , 5.6 ) ;
o = b . obj ( ) ;
}
s - > setObject ( " z " , o , false ) ;
s - > invoke ( " return z " , BSONObj ( ) ) ;
out = s - > getObject ( " return " ) ;
ASSERT_EQUALS ( 5 , out [ " a " ] . number ( ) ) ;
ASSERT_EQUALS ( 5.6 , out [ " b " ] . number ( ) ) ;
ASSERT_EQUALS ( NumberDouble , out [ " b " ] . type ( ) ) ;
ASSERT_EQUALS ( NumberInt , out [ " a " ] . type ( ) ) ;
2009-05-26 20:43:20 +02:00
2009-05-22 16:48:05 +02:00
2009-05-26 20:43:20 +02:00
// -- C --
2009-05-22 16:48:05 +02:00
2009-05-26 20:43:20 +02:00
{
BSONObjBuilder b ;
{
BSONObjBuilder c ;
c . append ( " 0 " , 5.5 ) ;
c . append ( " 1 " , 6 ) ;
b . appendArray ( " a " , c . obj ( ) ) ;
}
o = b . obj ( ) ;
}
2009-05-22 16:48:05 +02:00
2009-05-26 20:43:20 +02:00
ASSERT_EQUALS ( NumberDouble , o [ " a " ] . embeddedObjectUserCheck ( ) [ " 0 " ] . type ( ) ) ;
ASSERT_EQUALS ( NumberInt , o [ " a " ] . embeddedObjectUserCheck ( ) [ " 1 " ] . type ( ) ) ;
s - > setObject ( " z " , o , false ) ;
out = s - > getObject ( " z " ) ;
ASSERT_EQUALS ( NumberDouble , out [ " a " ] . embeddedObjectUserCheck ( ) [ " 0 " ] . type ( ) ) ;
ASSERT_EQUALS ( NumberInt , out [ " a " ] . embeddedObjectUserCheck ( ) [ " 1 " ] . type ( ) ) ;
2009-05-22 16:48:05 +02:00
2009-05-26 20:43:20 +02:00
s - > invokeSafe ( " z.z = 5; " , BSONObj ( ) ) ;
out = s - > getObject ( " z " ) ;
ASSERT_EQUALS ( 5 , out [ " z " ] . number ( ) ) ;
ASSERT_EQUALS ( NumberDouble , out [ " a " ] . embeddedObjectUserCheck ( ) [ " 0 " ] . type ( ) ) ;
2009-12-16 02:40:53 +01:00
// Commenting so that v8 tests will work
// ASSERT_EQUALS( NumberDouble , out["a"].embeddedObjectUserCheck()["1"].type() ); // TODO: this is technically bad, but here to make sure that i understand the behavior
2009-05-22 16:48:05 +02:00
2009-12-16 19:37:29 +01:00
// Eliot says I don't have to worry about this case
2009-12-16 02:40:53 +01:00
// // -- D --
//
// o = fromjson( "{a:3.0,b:4.5}" );
// ASSERT_EQUALS( NumberDouble , o["a"].type() );
// ASSERT_EQUALS( NumberDouble , o["b"].type() );
//
// s->setObject( "z" , o , false );
// s->invoke( "return z" , BSONObj() );
// out = s->getObject( "return" );
// ASSERT_EQUALS( 3 , out["a"].number() );
// ASSERT_EQUALS( 4.5 , out["b"].number() );
//
// ASSERT_EQUALS( NumberDouble , out["b"].type() );
// ASSERT_EQUALS( NumberDouble , out["a"].type() );
//
2009-05-22 16:48:05 +02:00
delete s ;
}
} ;
2009-05-26 22:04:07 +02:00
2010-01-21 00:02:46 +01:00
class NumberLong {
public :
void run ( ) {
Scope * s = globalScriptEngine - > newScope ( ) ;
s - > localConnect ( " blah " ) ;
BSONObjBuilder b ;
2010-01-21 01:21:19 +01:00
long long val = ( long long ) ( 0xbabadeadbeefbaddULL ) ;
2010-01-21 00:02:46 +01:00
b . append ( " a " , val ) ;
BSONObj in = b . obj ( ) ;
s - > setObject ( " a " , in ) ;
BSONObj out = s - > getObject ( " a " ) ;
ASSERT_EQUALS ( mongo : : NumberLong , out . firstElement ( ) . type ( ) ) ;
ASSERT ( s - > exec ( " b = {b:a.a} " , " foo " , false , true , false ) ) ;
out = s - > getObject ( " b " ) ;
ASSERT_EQUALS ( mongo : : NumberLong , out . firstElement ( ) . type ( ) ) ;
ASSERT_EQUALS ( val , out . firstElement ( ) . numberLong ( ) ) ;
ASSERT ( s - > exec ( " c = {c:a.a.toString()} " , " foo " , false , true , false ) ) ;
out = s - > getObject ( " c " ) ;
stringstream ss ;
ss < < val ;
ASSERT_EQUALS ( ss . str ( ) , out . firstElement ( ) . valuestr ( ) ) ;
ASSERT ( s - > exec ( " d = {d:a.a.toNumber()} " , " foo " , false , true , false ) ) ;
out = s - > getObject ( " d " ) ;
ASSERT_EQUALS ( NumberDouble , out . firstElement ( ) . type ( ) ) ;
ASSERT_EQUALS ( double ( val ) , out . firstElement ( ) . number ( ) ) ;
}
} ;
2009-05-24 03:10:37 +02:00
class WeirdObjects {
public :
BSONObj build ( int depth ) {
BSONObjBuilder b ;
b . append ( " 0 " , depth ) ;
if ( depth > 0 )
b . appendArray ( " 1 " , build ( depth - 1 ) ) ;
return b . obj ( ) ;
}
void run ( ) {
2009-12-30 03:27:49 +01:00
Scope * s = globalScriptEngine - > newScope ( ) ;
2009-05-24 03:10:37 +02:00
s - > localConnect ( " blah " ) ;
for ( int i = 5 ; i < 100 ; i + = 10 ) {
s - > setObject ( " a " , build ( i ) , false ) ;
s - > invokeSafe ( " tojson( a ) " , BSONObj ( ) ) ;
s - > setObject ( " a " , build ( 5 ) , true ) ;
s - > invokeSafe ( " tojson( a ) " , BSONObj ( ) ) ;
}
delete s ;
}
} ;
2009-05-15 14:31:11 +02:00
2009-05-27 21:40:57 +02:00
void dummy_function_to_force_dbeval_cpp_linking ( ) {
BSONObj cmd ;
BSONObjBuilder result ;
string errmsg ;
dbEval ( " " , cmd , result , errmsg ) ;
}
DBDirectClient client ;
2009-05-27 21:20:09 +02:00
class Utf8Check {
public :
2009-05-27 21:43:26 +02:00
Utf8Check ( ) { reset ( ) ; }
~ Utf8Check ( ) { reset ( ) ; }
2009-05-27 21:20:09 +02:00
void run ( ) {
if ( ! globalScriptEngine - > utf8Ok ( ) ) {
2009-06-30 19:46:12 +02:00
log ( ) < < " warning: utf8 not supported " < < endl ;
2009-05-27 21:20:09 +02:00
return ;
}
2009-05-27 21:40:57 +02:00
string utf8ObjSpec = " {'_id':' \\ u0001 \\ u007f \\ u07ff \\ uffff'} " ;
BSONObj utf8Obj = fromjson ( utf8ObjSpec ) ;
client . insert ( ns ( ) , utf8Obj ) ;
client . eval ( " unittest " , " v = db.jstests.utf8check.findOne(); db.jstests.utf8check.remove( {} ); db.jstests.utf8check.insert( v ); " ) ;
check ( utf8Obj , client . findOne ( ns ( ) , BSONObj ( ) ) ) ;
}
private :
void check ( const BSONObj & one , const BSONObj & two ) {
if ( one . woCompare ( two ) ! = 0 ) {
static string fail = string ( " Assertion failure expected " ) + string ( one ) + " , got " + string ( two ) ;
FAIL ( fail . c_str ( ) ) ;
}
2009-05-27 21:20:09 +02:00
}
2009-05-27 21:40:57 +02:00
void reset ( ) {
client . dropCollection ( ns ( ) ) ;
}
static const char * ns ( ) { return " unittest.jstests.utf8check " ; }
2009-05-27 21:20:09 +02:00
} ;
2009-05-27 22:09:59 +02:00
class LongUtf8String {
public :
LongUtf8String ( ) { reset ( ) ; }
~ LongUtf8String ( ) { reset ( ) ; }
void run ( ) {
if ( ! globalScriptEngine - > utf8Ok ( ) )
return ;
2009-05-27 23:32:22 +02:00
client . eval ( " unittest " , " db.jstests.longutf8string.save( {_id:' \\ uffff \\ uffff \\ uffff \\ uffff'} ) " ) ;
2009-05-27 22:09:59 +02:00
}
private :
void reset ( ) {
client . dropCollection ( ns ( ) ) ;
}
static const char * ns ( ) { return " unittest.jstests.longutf8string " ; }
} ;
2009-05-27 21:20:09 +02:00
2009-06-01 18:53:24 +02:00
class CodeTests {
public :
void run ( ) {
2009-12-30 03:27:49 +01:00
Scope * s = globalScriptEngine - > newScope ( ) ;
2009-06-01 18:53:24 +02:00
{
BSONObjBuilder b ;
b . append ( " a " , 1 ) ;
b . appendCode ( " b " , " function(){ out.b = 11; } " ) ;
b . appendCodeWScope ( " c " , " function(){ out.c = 12; } " , BSONObj ( ) ) ;
b . appendCodeWScope ( " d " , " function(){ out.d = 13 + bleh; } " , BSON ( " bleh " < < 5 ) ) ;
s - > setObject ( " foo " , b . obj ( ) ) ;
}
s - > invokeSafe ( " out = {}; out.a = foo.a; foo.b(); foo.c(); " , BSONObj ( ) ) ;
BSONObj out = s - > getObject ( " out " ) ;
ASSERT_EQUALS ( 1 , out [ " a " ] . number ( ) ) ;
ASSERT_EQUALS ( 11 , out [ " b " ] . number ( ) ) ;
ASSERT_EQUALS ( 12 , out [ " c " ] . number ( ) ) ;
2009-12-16 19:37:29 +01:00
// Guess we don't care about this
2009-06-01 18:53:24 +02:00
//s->invokeSafe( "foo.d() " , BSONObj() );
//out = s->getObject( "out" );
//ASSERT_EQUALS( 18 , out["d"].number() );
delete s ;
}
} ;
2009-06-03 19:18:50 +02:00
class DBRefTest {
public :
DBRefTest ( ) {
_a = " unittest.dbref.a " ;
_b = " unittest.dbref.b " ;
reset ( ) ;
}
~ DBRefTest ( ) {
//reset();
}
void run ( ) {
client . insert ( _a , BSON ( " a " < < " 17 " ) ) ;
{
BSONObj fromA = client . findOne ( _a , BSONObj ( ) ) ;
cout < < " Froma : " < < fromA < < endl ;
BSONObjBuilder b ;
b . append ( " b " , 18 ) ;
b . appendDBRef ( " c " , " dbref.a " , fromA [ " _id " ] . __oid ( ) ) ;
client . insert ( _b , b . obj ( ) ) ;
}
2009-09-30 16:08:58 +02:00
ASSERT ( client . eval ( " unittest " , " x = db.dbref.b.findOne(); assert.eq( 17 , x.c.fetch().a , 'ref working' ); " ) ) ;
2009-12-17 01:50:36 +01:00
// BSON DBRef <=> JS DBPointer
ASSERT ( client . eval ( " unittest " , " x = db.dbref.b.findOne(); db.dbref.b.drop(); x.c = new DBPointer( x.c.ns, x.c.id ); db.dbref.b.insert( x ); " ) ) ;
ASSERT_EQUALS ( DBRef , client . findOne ( " unittest.dbref.b " , " " ) [ " c " ] . type ( ) ) ;
// BSON Object <=> JS DBRef
ASSERT ( client . eval ( " unittest " , " x = db.dbref.b.findOne(); db.dbref.b.drop(); x.c = new DBRef( x.c.ns, x.c.id ); db.dbref.b.insert( x ); " ) ) ;
ASSERT_EQUALS ( Object , client . findOne ( " unittest.dbref.b " , " " ) [ " c " ] . type ( ) ) ;
ASSERT_EQUALS ( string ( " dbref.a " ) , client . findOne ( " unittest.dbref.b " , " " ) [ " c " ] . embeddedObject ( ) . getStringField ( " $ref " ) ) ;
2009-06-03 19:18:50 +02:00
}
void reset ( ) {
client . dropCollection ( _a ) ;
client . dropCollection ( _b ) ;
}
const char * _a ;
const char * _b ;
} ;
2009-06-05 15:54:35 +02:00
class BinDataType {
public :
void pp ( const char * s , BSONElement e ) {
int len ;
const char * data = e . binData ( len ) ;
cout < < s < < " : " < < e . binDataType ( ) < < " \t " < < len < < endl ;
cout < < " \t " ;
for ( int i = 0 ; i < len ; i + + )
cout < < ( int ) ( data [ i ] ) < < " " ;
cout < < endl ;
}
void run ( ) {
2009-12-30 03:27:49 +01:00
Scope * s = globalScriptEngine - > newScope ( ) ;
2009-06-05 15:54:35 +02:00
s - > localConnect ( " asd " ) ;
2009-12-21 18:57:04 +01:00
const char * foo = " asdas \0 asdasd " ;
2010-01-25 23:07:02 +01:00
const char * base64 = " YXNkYXMAYXNkYXNk " ;
2009-06-05 15:54:35 +02:00
BSONObj in ;
{
BSONObjBuilder b ;
b . append ( " a " , 7 ) ;
2009-12-21 18:57:04 +01:00
b . appendBinData ( " b " , 12 , ByteArray , foo ) ;
2009-06-05 15:54:35 +02:00
in = b . obj ( ) ;
s - > setObject ( " x " , in ) ;
}
s - > invokeSafe ( " myb = x.b; print( myb ); printjson( myb ); " , BSONObj ( ) ) ;
s - > invokeSafe ( " y = { c : myb }; " , BSONObj ( ) ) ;
BSONObj out = s - > getObject ( " y " ) ;
ASSERT_EQUALS ( BinData , out [ " c " ] . type ( ) ) ;
2010-01-25 23:07:02 +01:00
// pp( "in " , in["b"] );
// pp( "out" , out["c"] );
2009-06-05 15:54:35 +02:00
ASSERT_EQUALS ( 0 , in [ " b " ] . woCompare ( out [ " c " ] , false ) ) ;
2009-12-17 03:37:31 +01:00
// check that BinData js class is utilized
2010-01-25 23:07:02 +01:00
s - > invokeSafe ( " q = x.b.toString(); " , BSONObj ( ) ) ;
stringstream expected ;
expected < < " BinData( type: " < < ByteArray < < " , base64: \" " < < base64 < < " \" ) " ;
ASSERT_EQUALS ( expected . str ( ) , s - > getString ( " q " ) ) ;
2009-12-17 03:37:31 +01:00
2009-06-05 15:54:35 +02:00
delete s ;
}
} ;
2009-06-03 19:18:50 +02:00
2009-06-12 02:15:01 +02:00
class VarTests {
public :
void run ( ) {
2009-12-30 03:27:49 +01:00
Scope * s = globalScriptEngine - > newScope ( ) ;
2009-06-12 02:15:01 +02:00
2009-09-30 16:08:58 +02:00
ASSERT ( s - > exec ( " a = 5; " , " a " , false , true , false ) ) ;
2009-06-12 02:15:01 +02:00
ASSERT_EQUALS ( 5 , s - > getNumber ( " a " ) ) ;
2009-09-30 16:08:58 +02:00
ASSERT ( s - > exec ( " var b = 6; " , " b " , false , true , false ) ) ;
2009-06-12 02:15:01 +02:00
ASSERT_EQUALS ( 6 , s - > getNumber ( " b " ) ) ;
delete s ;
}
} ;
2009-05-12 22:37:23 +02:00
class All : public Suite {
2009-02-03 06:14:14 +01:00
public :
2009-09-17 23:23:38 +02:00
All ( ) : Suite ( " js " ) {
}
void setupTests ( ) {
2009-02-03 06:14:14 +01:00
add < Fundamental > ( ) ;
2009-04-24 04:44:19 +02:00
add < BasicScope > ( ) ;
2009-12-29 20:04:00 +01:00
add < ResetScope > ( ) ;
2009-04-24 05:52:47 +02:00
add < FalseTests > ( ) ;
2009-04-24 22:41:40 +02:00
add < SimpleFunctions > ( ) ;
2009-06-01 18:53:24 +02:00
2009-04-24 23:19:24 +02:00
add < ObjectMapping > ( ) ;
2009-05-06 17:53:39 +02:00
add < ObjectDecoding > ( ) ;
2009-05-08 17:02:12 +02:00
add < JSOIDTests > ( ) ;
2009-12-15 20:22:19 +01:00
add < SetImplicit > ( ) ;
add < ObjectModReadonlyTests > ( ) ;
2009-05-14 21:34:14 +02:00
add < OtherJSTypes > ( ) ;
2009-05-15 14:31:11 +02:00
add < SpecialDBTypes > ( ) ;
2009-05-22 16:48:05 +02:00
add < TypeConservation > ( ) ;
2010-01-21 00:02:46 +01:00
add < NumberLong > ( ) ;
2009-06-01 18:53:24 +02:00
2009-05-24 03:10:37 +02:00
add < WeirdObjects > ( ) ;
2009-05-27 21:20:09 +02:00
add < Utf8Check > ( ) ;
2009-05-27 22:09:59 +02:00
add < LongUtf8String > ( ) ;
2009-06-01 18:53:24 +02:00
add < CodeTests > ( ) ;
2009-06-03 19:18:50 +02:00
add < DBRefTest > ( ) ;
2009-06-05 15:54:35 +02:00
add < BinDataType > ( ) ;
2009-06-12 02:15:01 +02:00
add < VarTests > ( ) ;
2009-02-03 06:14:14 +01:00
}
2009-09-17 23:23:38 +02:00
} myall ;
2009-02-03 06:14:14 +01:00
} // namespace JavaJSTests