
org.specs.mock.Mocks.scala Maven / Gradle / Ivy
package org.specs.mock
import org.specs.Sugar._
import scala.collection.mutable.Stack
import org.specs.collection.ExtendedList._
/**
* The Protocol
class stores the expectations of mocks, alongside with the actual received calls
* It can be exclusive or not: i.e. return an error in case of unexpected calls or not
* A protocol
has 3 functions:
* - be defined by nested protocol definitions and expected calls
*
- store received calls
*
- return failures if there are unmatched calls
*/
class Protocol extends ProtocolTypes {
/** actual calls received by mocks */
var receivedCalls: List[ReceivedCall] = Nil
/** if true, will check unexpected calls too */
var exclusive = false
/**
* protocol definitions which are stacked during the protocol creation
* but which will be nested after creation.
Each protocol definition corresponds to
* a block of an "expect" declaration:
* expect(twoOf) {
* expect(inSequence) {
* mock.callMethod1
* mock.callMethod2
* }
* }
*/
private var allDefinitions: Stack[ProtocolDef] = new Stack
/**
* definition of the protocol
*/
def definition = allDefinitions.top
/**
* takes a value v
which will declare some mocks expectations
* By default the protocol type is inAnyOrder
*/
def expect(v: => Any): ProtocolDef = expect(inAnyOrder)(v)
/**
* takes a value v
which will declare some mocks expectations
* The protocol type is specified by the parameter t
*/
def expect(t: ProtocolType)(v: => Any): ProtocolDef = {
// open a new protocol definition of type t with no expected calls
allDefinitions.push(new ProtocolDef(t, Nil))
// v is supposed to contain mock expectations
v
// if there are more than one protocol definition
// the last protocol on the stack is "poped" and becomes a specified call for the previous protocol definition
if (allDefinitions.size > 1) {
val p = allDefinitions.pop
allDefinitions.top.expect(p)
p
}
else
allDefinitions.top // else return the outermost protocol
}
/**
* adds an expected method name to the current protocol definition
*/
def expectCall(methodName: String) = allDefinitions.top.expect(methodName)
/**
* adds a received call to the list of received calls
*/
def receiveCall(methodName: String) = receivedCalls = receivedCalls:::List(new ReceivedCall(methodName))
/**
* @return an error message if the protocol definition
* has some expected calls which don't match the received calls
*/
def failures: String = {
val f = definition.failures(receivedCalls, exclusive)
// if there are no failures that are the result of unmatched calls
// and if the protocol is defined as exclusive, return a message with unexpected calls if there are some
if (exclusive && f.isEmpty)
receivedCalls.filter(!_.consumed).map(_.toString + " should not have been called").mkString("\n")
else
f
}
/**
* A Protocol
is specified if there it contains one protocol definition
*/
def isSpecified = !allDefinitions.isEmpty
/**
* Removes any previous protocol definition and received calls
*/
def clear = {
allDefinitions = new Stack
receivedCalls = Nil
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy