Created
October 10, 2009 18:25
-
-
Save royw/206993 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'mongo_mapper' | |
require 'spec' | |
require 'log4r' | |
require 'versionomy' | |
# Logger used for logging MongoDB database commands | |
Log4r::Logger.new('TMP') | |
Log4r::Logger['TMP'].outputters = Log4r::StdoutOutputter.new(:console) | |
Log4r::Outputter[:console].formatter = Log4r::PatternFormatter.new(:pattern => "%m") | |
Log4r::Logger['TMP'].level = Log4r::DEBUG | |
# Monkey patch the driver to get buildinfo which contains the version of the MongoDB server | |
# The version is checked because saving functions on the server requires MongoDB 1.1.1 or newer | |
module Mongo | |
class Admin | |
def buildinfo | |
oh = OrderedHash.new | |
oh[:buildinfo] = 1 | |
doc = @db.db_command(oh) | |
raise "Error with buildinfo command: #{doc.inspect}" unless @db.ok?(doc) | |
doc | |
end | |
end | |
end | |
# connect with a logger! Whoooop! Great feature | |
MongoMapper.connection = Mongo::Connection.new('localhost', nil, :logger => Log4r::Logger['TMP']) | |
# grab the version from the admin database | |
MongoMapper.database = 'admin' | |
mongo_version = Versionomy.parse(MongoMapper.database.admin.buildinfo['version']) | |
# now switch to our testing database | |
MongoMapper.database = 'test' | |
# test model | |
class Test | |
include MongoMapper::Document | |
key :first, Integer | |
key :second, Integer | |
end | |
describe '$where usage' do | |
before :all do | |
Log4r::Logger['TMP'].debug { 'writing server-side functions' } | |
# remove any functions saved on the server | |
MongoMapper.database.eval(Mongo::Code.new('db.system.js.remove({});')) | |
end | |
before :each do | |
Log4r::Logger['TMP'].debug { 'setting up initial database contents' } | |
# clean database for each test | |
Test.collection.clear | |
Test.create(:first => 10, :second => 15) | |
Test.create(:first => 17, :second => 23) | |
end | |
it "should run js evals" do | |
Log4r::Logger['TMP'].debug { 'should run js evals' } | |
MongoMapper.database.eval(Mongo::Code.new('function(){ return 11 + 6; }')).should == 17 | |
MongoMapper.database.eval(Mongo::Code.new('function( x ){ return 10 + x; }'), 7).should == 17 | |
# notice that the Mongo::Code.new() is not necessary | |
MongoMapper.database.eval('function( z ){ return 17 + z; }', 5).should == 22 | |
end | |
it "should run server-side functions" do | |
Log4r::Logger['TMP'].debug { 'should run server-side functions' } | |
Test.count.should == 2 | |
Test.all(:conditions => {'$where' => Mongo::Code.new("this.first + this.second > 30;")}).size.should == 1 | |
Test.all(:conditions => {'$where' => "this.first + this.second > 30;"}).size.should == 1 | |
Test.all(:conditions => {:first => {'$gt' => 15}}).size.should == 1 | |
# can't get the function(x){...} notation to work | |
# Test.all(:conditions => {'$where' => Mongo::Code.new("function( a ){ return a.first > 15; }")}).size.should == 1 | |
# | |
# RuntimeError in 'Wishful Thinking should run server-side functions' | |
# error on invocation of $where function: | |
# JS Error: TypeError: a has no properties nofile_b:0 | |
# | |
# server reports: | |
# Sat Oct 10 01:06:56 tmp.tests Caught Assertion in runQuery ns:tmp.tests massert:error on invocation of $where function: | |
# JS Error: TypeError: a has no properties nofile_b:0 | |
end | |
it "should store and run server-side functions" do | |
Log4r::Logger['TMP'].debug { 'should store and run server-side functions' } | |
# storing functions on the server side requires MongoDB 1.1.1 or newer | |
minimum_mongo_version = Versionomy.parse('1.1.1') | |
(mongo_version <=> minimum_mongo_version).should >= 0 | |
# with or without Mongo::Code.new | |
MongoMapper.database.eval(Mongo::Code.new('db.system.js.count();')).should == 0 | |
MongoMapper.database.eval('db.system.js.count();').should == 0 | |
# need to add the following server-side function: | |
# note, can be either with or without Mongo::Code.new | |
javascript = "db.system.js.insert( { _id : 'combine', value : function( a ) " + | |
"{ return a.first + a.second; } } );" | |
MongoMapper.database.eval(javascript) | |
MongoMapper.database.eval('db.system.js.count();').should == 1 | |
# just making sure we have the two documents | |
Test.count.should == 2 | |
# use the function stored on the servera | |
# with or without Mongo::Code.new | |
Test.all(:conditions => {"$where" => Mongo::Code.new("combine(this) > 30")}).size.should == 1 | |
min = 30 | |
Test.all(:conditions => {"$where" => "combine(this) > #{min}"}).size.should == 1 | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment