Created
May 29, 2011 03:03
-
-
Save etorreborre/997433 to your computer and use it in GitHub Desktop.
Using implicit contexts to remove duplication
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
/** | |
* You can compare this Specification with: | |
* https://github.com/etorreborre/hammersmith/blob/master/mongo-driver/src/test/scala/DirectConnectionSpec.scala | |
* | |
* Note that: | |
* * connectIsMaster returns a function (not a method anymore) | |
* * distinctValue returns 'ok' (a MatchResult) instead of 'success' (a Result) | |
*/ | |
class DirectConnectionSpec extends Specification with Logging { def is = | |
"The MongoDB Direct Connection" ^ | |
"Connect correctly and grab isMaster, then disconnect" ! connectIsMaster^ | |
"Iterate a simple cursor correctly" ! iterateSimpleCursor^ | |
"Iterate a complex (iteratee) cursor correctly" ! iterateComplexCursor^ | |
"Correctly calculate values for 'distinct'" ! distinctValue^ | |
p^ | |
"The write behavior" ^ | |
"Support 'blind' (NoOp) writes" ! noopInsert^ | |
"Support inserts with no (default) write concern" ! insertWithDefaultWriteConcern^ | |
"Support inserts with implicit safe write concern" ! insertWithSafeImplicitWriteConcern^ | |
end | |
implicit object mongo extends mongoConn | |
trait mongoConn extends AroundOutside[MongoConnection] { | |
var conn = MongoConnection() | |
def around[T <% Result](t: =>T) = { | |
conn.connected_? must eventually(beTrue) | |
t | |
/*conn.close() | |
conn.connected_? must eventually(beFalse)*/ | |
} | |
def outside: MongoConnection = { conn = MongoConnection() | |
conn } | |
} | |
def connectIsMaster = (conn: MongoConnection) => { | |
conn.databaseNames({ dbs: Seq[String] => dbs.foreach(log.trace("DB: %s", _)) }) | |
conn("test").collectionNames({ colls: Seq[String] => colls.foreach(log.trace("Collection: %s", _)) }) | |
conn.connected_? must eventually(beTrue) | |
} | |
// todo - this relies heavily on whats on my local workstation; needs to be generic | |
def iterateSimpleCursor = (conn: MongoConnection) => { | |
var x = 0 | |
conn("bookstore").find("inventory")(Document.empty, Document.empty)((cursor: Cursor) => { | |
for (doc <- cursor) { | |
x += 1 | |
} | |
}) | |
x must eventually (be_==(336)) | |
} | |
def iterateComplexCursor = (conn: MongoConnection) => { | |
var x = 0 | |
conn("bookstore").find("inventory")(Document.empty, Document.empty)((cursor: Cursor) => { | |
def next(op: Cursor.IterState): Cursor.IterCmd = op match { | |
case Cursor.Entry(doc) => { | |
x += 1 | |
if (x < 100) Cursor.Next(next) else Cursor.Done | |
} | |
case Cursor.Empty => { | |
if (x < 100) Cursor.NextBatch(next) else Cursor.Done | |
} | |
case Cursor.EOF => { | |
Cursor.Done | |
} | |
} | |
Cursor.iterate(cursor)(next) | |
}) | |
x must eventually(5, 5.seconds) (be_==(100)) | |
} | |
def distinctValue = (conn: MongoConnection) => { | |
conn("bookstore")("inventory").distinct("author")((values: Seq[Any]) => { | |
for (item <- values) { | |
log.trace("Got a value: %s", item.asInstanceOf[String]) | |
} | |
}) | |
ok | |
} | |
def noopInsert = (conn: MongoConnection) => { | |
val mongo = conn("testHammersmith")("test_insert") | |
mongo.dropCollection()(success => { | |
log.info("Dropped collection... Success? " + success) | |
}) | |
mongo.insert(Document("foo" -> "bar", "bar" -> "baz")){} | |
// TODO - Implement 'count' | |
var doc: BSONDocument = null | |
mongo.findOne(Document("foo" -> "bar"))((_doc: BSONDocument) => { | |
doc = _doc | |
}) | |
doc must not (beNull.eventually) | |
doc must eventually (havePairs("foo" -> "bar", "bar" -> "baz")) | |
} | |
def insertWithDefaultWriteConcern = (conn: MongoConnection) => { | |
val mongo = conn("testHammersmith")("test_insert") | |
mongo.dropCollection()(success => { | |
log.info("Dropped collection... Success? " + success) | |
}) | |
var id: AnyRef = null | |
mongo.insert(Document("foo" -> "bar", "bar" -> "baz"))((oid: Option[AnyRef], res: WriteResult) => { | |
id = oid.getOrElse(null) | |
}) | |
// TODO - Implement 'count' | |
var doc: BSONDocument = null | |
mongo.findOne(Document("foo" -> "bar"))((_doc: BSONDocument) => { | |
doc = _doc | |
}) | |
doc must not (beNull.eventually) | |
doc must eventually (havePairs("foo" -> "bar", "bar" -> "baz")) | |
} | |
def insertWithSafeImplicitWriteConcern = (conn: MongoConnection) => { | |
val mongo = conn("testHammersmith")("test_insert") | |
implicit val safeWrite = WriteConcern.Safe | |
mongo.dropCollection()(success => { | |
log.info("Dropped collection... Success? " + success) | |
}) | |
var id: Option[AnyRef] = null | |
var ok: Option[Boolean] = None | |
val handler = RequestFutures.write((result: Either[Throwable, (Option[AnyRef], WriteResult)]) => { | |
result match { | |
case Right((oid, wr)) => { | |
ok = Some(true) | |
id = oid } | |
case Left(t) => { | |
ok = Some(false) | |
log.error(t, "Command Failed.") | |
} | |
} | |
}) | |
mongo.insert(Document("foo" -> "bar", "bar" -> "baz"))(handler) | |
ok must eventually { beSome(true) } | |
id must not (beNull.eventually) | |
// TODO - Implement 'count' | |
var doc: BSONDocument = null | |
mongo.findOne(Document("foo" -> "bar"))((_doc: BSONDocument) => { | |
doc = _doc | |
}) | |
doc must not (beNull.eventually) | |
doc must eventually (havePairs("foo" -> "bar", "bar" -> "baz")) | |
} | |
/* "Support findAndModify" in { | |
val mongo = conn("testHammersmith")("test_findModify") | |
mongo.insert(Document("x" -> 1), Document("x" -> 2), Document("x" -> 3)) | |
}*/ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment