2216 lines
83 KiB
Plaintext
2216 lines
83 KiB
Plaintext
'/**
|
|
' * rooibos - simple, flexible, fun brightscript test framework for roku scenegraph apps
|
|
' * @version v2.3.0
|
|
' * @link https://github.com/georgejecook/rooibos#readme
|
|
' * @license MIT
|
|
' */
|
|
function Rooibos__Init(preTestSetup = invalid, testUtilsDecoratorMethodName = invalid, testSceneName = invalid, nodeContext = invalid) as void
|
|
args = {}
|
|
if createObject("roAPPInfo").IsDev() <> true then
|
|
? " not running in dev mode! - rooibos tests only support sideloaded builds - aborting"
|
|
return
|
|
end if
|
|
args.testUtilsDecoratorMethodName = testUtilsDecoratorMethodName
|
|
args.nodeContext = nodeContext
|
|
screen = CreateObject("roSGScreen")
|
|
m.port = CreateObject("roMessagePort")
|
|
screen.setMessagePort(m.port)
|
|
if testSceneName = invalid
|
|
testSceneName = "TestsScene"
|
|
end if
|
|
? "Starting test using test scene with name TestsScene" ; testSceneName
|
|
scene = screen.CreateScene(testSceneName)
|
|
scene.id = "ROOT"
|
|
screen.show()
|
|
m.global = screen.getGlobalNode()
|
|
m.global.addFields({"testsScene": scene})
|
|
if (preTestSetup <> invalid)
|
|
preTestSetup(screen)
|
|
end if
|
|
testId = args.TestId
|
|
if (testId = invalid)
|
|
testId = "UNDEFINED_TEST_ID"
|
|
end if
|
|
? "#########################################################################"
|
|
? "#TEST START : ###" ; testId ; "###"
|
|
args.testScene = scene
|
|
args.global = m.global
|
|
runner = RBS_TR_TestRunner(args)
|
|
runner.Run()
|
|
while(true)
|
|
msg = wait(0, m.port)
|
|
msgType = type(msg)
|
|
if msgType = "roSGScreenEvent"
|
|
if msg.isScreenClosed()
|
|
return
|
|
end if
|
|
end if
|
|
end while
|
|
end function
|
|
function BaseTestSuite() as object
|
|
this = {}
|
|
this.Name = "BaseTestSuite"
|
|
this.invalidValue = "#ROIBOS#INVALID_VALUE" ' special value used in mock arguments
|
|
this.ignoreValue = "#ROIBOS#IGNORE_VALUE" ' special value used in mock arguments
|
|
this.allowNonExistingMethodsOnMocks = true
|
|
this.isAutoAssertingMocks = true
|
|
this.TestCases = []
|
|
this.AddTest = RBS_BTS_AddTest
|
|
this.CreateTest = RBS_BTS_CreateTest
|
|
this.GetLegacyCompatibleReturnValue = RBS_BTS_GetLegacyCompatibleReturnValue
|
|
this.Fail = RBS_BTS_Fail
|
|
this.AssertFalse = RBS_BTS_AssertFalse
|
|
this.AssertTrue = RBS_BTS_AssertTrue
|
|
this.AssertEqual = RBS_BTS_AssertEqual
|
|
this.AssertLike = RBS_BTS_AssertLike
|
|
this.AssertNotEqual = RBS_BTS_AssertNotEqual
|
|
this.AssertInvalid = RBS_BTS_AssertInvalid
|
|
this.AssertNotInvalid = RBS_BTS_AssertNotInvalid
|
|
this.AssertAAHasKey = RBS_BTS_AssertAAHasKey
|
|
this.AssertAANotHasKey = RBS_BTS_AssertAANotHasKey
|
|
this.AssertAAHasKeys = RBS_BTS_AssertAAHasKeys
|
|
this.AssertAANotHasKeys = RBS_BTS_AssertAANotHasKeys
|
|
this.AssertArrayContains = RBS_BTS_AssertArrayContains
|
|
this.AssertArrayNotContains = RBS_BTS_AssertArrayNotContains
|
|
this.AssertArrayContainsSubset = RBS_BTS_AssertArrayContainsSubset
|
|
this.AssertArrayContainsAAs = RBS_BTS_AssertArrayContainsAAs
|
|
this.AssertArrayNotContainsSubset = RBS_BTS_AssertArrayNotContainsSubset
|
|
this.AssertArrayCount = RBS_BTS_AssertArrayCount
|
|
this.AssertArrayNotCount = RBS_BTS_AssertArrayNotCount
|
|
this.AssertEmpty = RBS_BTS_AssertEmpty
|
|
this.AssertNotEmpty = RBS_BTS_AssertNotEmpty
|
|
this.AssertArrayContainsOnlyValuesOfType = RBS_BTS_AssertArrayContainsOnlyValuesOfType
|
|
this.AssertType = RBS_BTS_AssertType
|
|
this.AssertSubType = RBS_BTS_AssertSubType
|
|
this.AssertNodeCount = RBS_BTS_AssertNodeCount
|
|
this.AssertNodeNotCount = RBS_BTS_AssertNodeNotCount
|
|
this.AssertNodeEmpty = RBS_BTS_AssertNodeEmpty
|
|
this.AssertNodeNotEmpty = RBS_BTS_AssertNodenotEmpty
|
|
this.AssertNodeContains = RBS_BTS_AssertNodeContains
|
|
this.AssertNodeNotContains = RBS_BTS_AssertNodeNotContains
|
|
this.AssertNodeContainsFields = RBS_BTS_AssertNodeContainsFields
|
|
this.AssertNodeNotContainsFields = RBS_BTS_AssertNodeNotContainsFields
|
|
this.AssertAAContainsSubset = RBS_BTS_AssertAAContainsSubset
|
|
this.EqValues = RBS_BTS_EqValues
|
|
this.EqAssocArrays = RBS_BTS_EqAssocArray
|
|
this.EqArray = RBS_BTS_EqArray
|
|
this.Stub = RBS_BTS_Stub
|
|
this.Mock = RBS_BTS_Mock
|
|
this.AssertMocks = RBS_BTS_AssertMocks
|
|
this.CreateFake = RBS_BTS_CreateFake
|
|
this.CombineFakes = RBS_BTS_CombineFakes
|
|
this.MockFail = RBS_BTS_MockFail
|
|
this.CleanMocks = RBS_BTS_CleanMocks
|
|
this.CleanStubs = RBS_BTS_CleanStubs
|
|
this.ExpectOnce = RBS_BTS_ExpectOnce
|
|
this.ExpectNone = RBS_BTS_ExpectNone
|
|
this.Expect = RBS_BTS_Expect
|
|
this.ExpectOnceOrNone = RBS_BTS_ExpectOnceOrNone
|
|
this.MockCallback0 = RBS_BTS_MockCallback0
|
|
this.MockCallback1 = RBS_BTS_MockCallback1
|
|
this.MockCallback2 = RBS_BTS_MockCallback2
|
|
this.MockCallback3 = RBS_BTS_MockCallback3
|
|
this.MockCallback4 = RBS_BTS_MockCallback4
|
|
this.MockCallback5 = RBS_BTS_MockCallback5
|
|
this.StubCallback0 = RBS_BTS_StubCallback0
|
|
this.StubCallback1 = RBS_BTS_StubCallback1
|
|
this.StubCallback2 = RBS_BTS_StubCallback2
|
|
this.StubCallback3 = RBS_BTS_StubCallback3
|
|
this.StubCallback4 = RBS_BTS_StubCallback4
|
|
this.StubCallback5 = RBS_BTS_StubCallback5
|
|
this.pathAsArray_ = RBS_BTS_rodash_pathsAsArray_
|
|
this.g = RBS_BTS_rodash_get_
|
|
return this
|
|
end function
|
|
sub RBS_BTS_AddTest(name, func,funcName, setup = invalid, teardown = invalid)
|
|
m.testCases.Push(m.createTest(name, func, setup, teardown))
|
|
end sub
|
|
function RBS_BTS_CreateTest(name, func, funcName, setup = invalid, teardown = invalid ) as object
|
|
if (func = invalid)
|
|
? " ASKED TO CREATE TEST WITH INVALID FUNCITON POINTER FOR FUNCTION " ; funcName
|
|
end if
|
|
return {
|
|
Name: name
|
|
Func: func
|
|
FuncName: funcName
|
|
SetUp: setup
|
|
TearDown: teardown
|
|
}
|
|
end function
|
|
function RBS_BTS_Fail(msg = "Error" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end function
|
|
function RBS_BTS_GetLegacyCompatibleReturnValue(value) as object
|
|
if (value = true)
|
|
if (m.isLegacy = true)
|
|
return ""
|
|
else
|
|
return true
|
|
end if
|
|
else
|
|
if (m.isLegacy = true)
|
|
return "ERROR"
|
|
else
|
|
return false
|
|
end if
|
|
end if
|
|
end function
|
|
function RBS_BTS_AssertFalse(expr , msg = "Expression evaluates to true" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if not RBS_CMN_IsBoolean(expr) or expr
|
|
m.currentResult.AddResult(msg)
|
|
return m.fail(msg)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertTrue(expr , msg = "Expression evaluates to false" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if not RBS_CMN_IsBoolean(expr) or not expr then
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertEqual(first , second , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if not m.eqValues(first, second)
|
|
if msg = ""
|
|
first_as_string = RBS_CMN_AsString(first)
|
|
second_as_string = RBS_CMN_AsString(second)
|
|
msg = first_as_string + " != " + second_as_string
|
|
end if
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertLike(first , second , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if first <> second
|
|
if msg = ""
|
|
first_as_string = RBS_CMN_AsString(first)
|
|
second_as_string = RBS_CMN_AsString(second)
|
|
msg = first_as_string + " != " + second_as_string
|
|
end if
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertNotEqual(first , second , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if m.eqValues(first, second)
|
|
if msg = ""
|
|
first_as_string = RBS_CMN_AsString(first)
|
|
second_as_string = RBS_CMN_AsString(second)
|
|
msg = first_as_string + " == " + second_as_string
|
|
end if
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertInvalid(value , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if value <> invalid
|
|
if msg = ""
|
|
expr_as_string = RBS_CMN_AsString(value)
|
|
msg = expr_as_string + " <> Invalid"
|
|
end if
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertNotInvalid(value , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if value = invalid
|
|
if msg = ""
|
|
expr_as_string = RBS_CMN_AsString(value)
|
|
msg = expr_as_string + " = Invalid"
|
|
end if
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertAAHasKey(array , key , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if RBS_CMN_IsAssociativeArray(array)
|
|
if not array.DoesExist(key)
|
|
if msg = ""
|
|
msg = "Array doesn't have the '" + key + "' key."
|
|
end if
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
else
|
|
msg = "Input value is not an Associative Array."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertAANotHasKey(array , key , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if RBS_CMN_IsAssociativeArray(array)
|
|
if array.DoesExist(key)
|
|
if msg = ""
|
|
msg = "Array has the '" + key + "' key."
|
|
end if
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
else
|
|
msg = "Input value is not an Associative Array."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertAAHasKeys(array , keys , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if RBS_CMN_IsAssociativeArray(array) and RBS_CMN_IsArray(keys)
|
|
for each key in keys
|
|
if not array.DoesExist(key)
|
|
if msg = ""
|
|
msg = "Array doesn't have the '" + key + "' key."
|
|
end if
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
end for
|
|
else
|
|
msg = "Input value is not an Associative Array."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertAANotHasKeys(array , keys , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if RBS_CMN_IsAssociativeArray(array) and RBS_CMN_IsArray(keys)
|
|
for each key in keys
|
|
if array.DoesExist(key)
|
|
if msg = ""
|
|
msg = "Array has the '" + key + "' key."
|
|
end if
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
end for
|
|
else
|
|
msg = "Input value is not an Associative Array."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertArrayContains(array , value , key = invalid , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if RBS_CMN_IsAssociativeArray(array) or RBS_CMN_IsArray(array)
|
|
if not RBS_CMN_ArrayContains(array, value, key)
|
|
msg = "Array doesn't have the '" + RBS_CMN_AsString(value) + "' value."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
else
|
|
msg = "Input value is not an Array."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertArrayContainsAAs(array , values , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if not RBS_CMN_IsArray(values)
|
|
msg = "values to search for are not an Array."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
if RBS_CMN_IsArray(array)
|
|
for each value in values
|
|
isMatched = false
|
|
if not RBS_CMN_IsAssociativeArray(value)
|
|
msg = "Value to search for was not associativeArray "+ RBS_CMN_AsString(value)
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
for each item in array
|
|
if (RBS_CMN_IsAssociativeArray(item))
|
|
isValueMatched = true
|
|
for each key in value
|
|
fieldValue = value[key]
|
|
itemValue = item[key]
|
|
if (not m.EqValues(fieldValue, itemValue))
|
|
isValueMatched = false
|
|
exit for
|
|
end if
|
|
end for
|
|
if (isValueMatched)
|
|
isMatched = true
|
|
exit for
|
|
end if
|
|
end if
|
|
end for ' items in array
|
|
if not isMatched
|
|
msg = "array missing value: "+ RBS_CMN_AsString(value)
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
end for 'values to match
|
|
else
|
|
msg = "Input value is not an Array."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertArrayNotContains(array , value , key = invalid , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if RBS_CMN_IsAssociativeArray(array) or RBS_CMN_IsArray(array)
|
|
if RBS_CMN_ArrayContains(array, value, key)
|
|
msg = "Array has the '" + RBS_CMN_AsString(value) + "' value."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
else
|
|
msg = "Input value is not an Array."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertArrayContainsSubset(array , subset , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if (RBS_CMN_IsAssociativeArray(array) and RBS_CMN_IsAssociativeArray(subset)) or (RBS_CMN_IsArray(array) and RBS_CMN_IsArray(subset))
|
|
isAA = RBS_CMN_IsAssociativeArray(subset)
|
|
for each item in subset
|
|
key = invalid
|
|
value = item
|
|
if isAA
|
|
key = item
|
|
value = subset[key]
|
|
end if
|
|
if not RBS_CMN_ArrayContains(array, value, key)
|
|
msg = "Array doesn't have the '" + RBS_CMN_AsString(value) + "' value."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
end for
|
|
else
|
|
msg = "Input value is not an Array."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertArrayNotContainsSubset(array , subset , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if (RBS_CMN_IsAssociativeArray(array) and RBS_CMN_IsAssociativeArray(subset)) or (RBS_CMN_IsArray(array) and RBS_CMN_IsArray(subset))
|
|
isAA = RBS_CMN_IsAssociativeArray(subset)
|
|
for each item in subset
|
|
key = invalid
|
|
value = item
|
|
if isAA
|
|
key = item
|
|
value = item[key]
|
|
end if
|
|
if RBS_CMN_ArrayContains(array, value, key)
|
|
msg = "Array has the '" + RBS_CMN_AsString(value) + "' value."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
end for
|
|
else
|
|
msg = "Input value is not an Array."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertArrayCount(array , count , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if RBS_CMN_IsAssociativeArray(array) or RBS_CMN_IsArray(array)
|
|
if array.Count() <> count
|
|
msg = "Array items count " + RBS_CMN_AsString(array.Count()) + " <> " + RBS_CMN_AsString(count) + "."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
else
|
|
msg = "Input value is not an Array."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertArrayNotCount(array , count , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if RBS_CMN_IsAssociativeArray(array) or RBS_CMN_IsArray(array)
|
|
if array.Count() = count
|
|
msg = "Array items count = " + RBS_CMN_AsString(count) + "."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
else
|
|
msg = "Input value is not an Array."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertEmpty(item , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if RBS_CMN_IsAssociativeArray(item) or RBS_CMN_IsArray(item)
|
|
if item.Count() > 0
|
|
msg = "Array is not empty."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
else if (RBS_CMN_IsString(item))
|
|
if (RBS_CMN_AsString(item) <> "")
|
|
msg = "Input value is not empty."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
else
|
|
msg = "AssertEmpty: Input value was not an array or a string"
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertNotEmpty(item , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if RBS_CMN_IsAssociativeArray(item) or RBS_CMN_IsArray(item)
|
|
if item.Count() = 0
|
|
msg = "Array is empty."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
else if RBS_CMN_IsString(item)
|
|
if (item = "")
|
|
msg = "Input value is empty."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
else
|
|
msg = "Input value is not a string or array."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertArrayContainsOnlyValuesOfType(array , typeStr , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if typeStr <> "String" and typeStr <> "Integer" and typeStr <> "Boolean" and typeStr <> "Array" and typeStr <> "AssociativeArray"
|
|
msg = "Type must be Boolean, String, Array, Integer, or AssociativeArray"
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
if RBS_CMN_IsAssociativeArray(array) or RBS_CMN_IsArray(array)
|
|
methodName = "RBS_CMN_Is" + typeStr
|
|
typeCheckFunction = RBS_CMN_GetIsTypeFunction(methodName)
|
|
if (typeCheckFunction <> invalid)
|
|
for each item in array
|
|
if not typeCheckFunction(item)
|
|
msg = RBS_CMN_AsString(item) + "is not a '" + typeStr + "' type."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
end for
|
|
else
|
|
msg = "could not find comparator for type '" + typeStr + "' type."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
else
|
|
msg = "Input value is not an Array."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_CMN_GetIsTypeFunction(name)
|
|
if name = "RBS_CMN_IsFunction"
|
|
return RBS_CMN_IsFunction
|
|
else if name = "RBS_CMN_IsXmlElement"
|
|
return RBS_CMN_IsXmlElement
|
|
else if name = "RBS_CMN_IsInteger"
|
|
return RBS_CMN_IsInteger
|
|
else if name = "RBS_CMN_IsBoolean"
|
|
return RBS_CMN_IsBoolean
|
|
else if name = "RBS_CMN_IsFloat"
|
|
return RBS_CMN_IsFloat
|
|
else if name = "RBS_CMN_IsDouble"
|
|
return RBS_CMN_IsDouble
|
|
else if name = "RBS_CMN_IsLongInteger"
|
|
return RBS_CMN_IsLongInteger
|
|
else if name = "RBS_CMN_IsNumber"
|
|
return RBS_CMN_IsNumber
|
|
else if name = "RBS_CMN_IsList"
|
|
return RBS_CMN_IsList
|
|
else if name = "RBS_CMN_IsArray"
|
|
return RBS_CMN_IsArray
|
|
else if name = "RBS_CMN_IsAssociativeArray"
|
|
return RBS_CMN_IsAssociativeArray
|
|
else if name = "RBS_CMN_IsSGNode"
|
|
return RBS_CMN_IsSGNode
|
|
else if name = "RBS_CMN_IsString"
|
|
return RBS_CMN_IsString
|
|
else if name = "RBS_CMN_IsDateTime"
|
|
return RBS_CMN_IsDateTime
|
|
else if name = "RBS_CMN_IsUndefined"
|
|
return RBS_CMN_IsUndefined
|
|
else
|
|
return invalid
|
|
end if
|
|
end function
|
|
function RBS_BTS_AssertType(value , typeStr , msg ="" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if type(value) <> typeStr
|
|
if msg = ""
|
|
expr_as_string = RBS_CMN_AsString(value)
|
|
msg = expr_as_string + " was not expected type " + typeStr
|
|
end if
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertSubType(value , typeStr , msg ="" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if type(value) <> "roSGNode"
|
|
if msg = ""
|
|
expr_as_string = RBS_CMN_AsString(value)
|
|
msg = expr_as_string + " was not a node, so could not match subtype " + typeStr
|
|
end if
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
else if (value.subType() <> typeStr)
|
|
if msg = ""
|
|
expr_as_string = RBS_CMN_AsString(value)
|
|
msg = expr_as_string + "( type : " + value.subType() +") was not of subType " + typeStr
|
|
end if
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_EqValues(Value1 , Value2 ) as dynamic
|
|
val1Type = type(Value1)
|
|
val2Type = type(Value2)
|
|
if val1Type = "<uninitialized>" or val2Type = "<uninitialized>" or val1Type = "" or val2Type = ""
|
|
? "ERROR!!!! - undefined value passed"
|
|
return false
|
|
end if
|
|
if val1Type = "roString" or val1Type = "String"
|
|
Value1 = RBS_CMN_AsString(Value1)
|
|
else
|
|
Value1 = box(Value1)
|
|
end if
|
|
if val2Type = "roString" or val2Type = "String"
|
|
Value2 = RBS_CMN_AsString(Value2)
|
|
else
|
|
Value2 = box(Value2)
|
|
end if
|
|
val1Type = type(Value1)
|
|
val2Type = type(Value2)
|
|
if val1Type = "roFloat" and val2Type = "roInt"
|
|
Value2 = box(Cdbl(Value2))
|
|
else if val2Type = "roFloat" and val1Type = "roInt"
|
|
Value1 = box(Cdbl(Value1))
|
|
end if
|
|
if val1Type <> val2Type
|
|
return false
|
|
else
|
|
valtype = val1Type
|
|
if valtype = "roList"
|
|
return RBS_BTS_EqArray(Value1, Value2)
|
|
else if valtype = "roAssociativeArray"
|
|
return RBS_BTS_EqAssocArray(Value1, Value2)
|
|
else if valtype = "roArray"
|
|
return RBS_BTS_EqArray(Value1, Value2)
|
|
else if (valtype = "roSGNode")
|
|
if (val2Type <> "roSGNode")
|
|
return false
|
|
else
|
|
return Value1.isSameNode(Value2)
|
|
end if
|
|
else
|
|
return Value1 = Value2
|
|
end if
|
|
end if
|
|
end function
|
|
function RBS_BTS_EqAssocArray(Value1 , Value2 ) as dynamic
|
|
l1 = Value1.Count()
|
|
l2 = Value2.Count()
|
|
if not l1 = l2
|
|
return false
|
|
else
|
|
for each k in Value1
|
|
if not Value2.DoesExist(k)
|
|
return false
|
|
else
|
|
v1 = Value1[k]
|
|
v2 = Value2[k]
|
|
if not RBS_BTS_EqValues(v1, v2)
|
|
return false
|
|
end if
|
|
end if
|
|
end for
|
|
return true
|
|
end if
|
|
end function
|
|
function RBS_BTS_EqArray(Value1 , Value2 ) as dynamic
|
|
if not (RBS_CMN_IsArray(Value1)) or not RBS_CMN_IsArray(Value2) then return false
|
|
l1 = Value1.Count()
|
|
l2 = Value2.Count()
|
|
if not l1 = l2
|
|
return false
|
|
else
|
|
for i = 0 to l1 - 1
|
|
v1 = Value1[i]
|
|
v2 = Value2[i]
|
|
if not RBS_BTS_EqValues(v1, v2) then
|
|
return false
|
|
end if
|
|
end for
|
|
return true
|
|
end if
|
|
end function
|
|
function RBS_BTS_AssertNodeCount(node , count , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if type(node) = "roSGNode"
|
|
if node.getChildCount() <> count
|
|
msg = "node items count <> " + RBS_CMN_AsString(count) + ". Received " + RBS_CMN_AsString(node.getChildCount())
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
else
|
|
msg = "Input value is not an node."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertNodeNotCount(node , count , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if type(node) = "roSGNode"
|
|
if node.getChildCount() = count
|
|
msg = "node items count = " + RBS_CMN_AsString(count) + "."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
else
|
|
msg = "Input value is not an node."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertNodeEmpty(node , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if type(node) = "roSGNode"
|
|
if node.getChildCount() > 0
|
|
msg = "node is not empty."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertNodeNotEmpty(node , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if type(node) = "roSGNode"
|
|
if node.Count() = 0
|
|
msg = "Array is empty."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertNodeContains(node , value , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if type(node) = "roSGNode"
|
|
if not RBS_CMN_NodeContains(node, value)
|
|
msg = "Node doesn't have the '" + RBS_CMN_AsString(value) + "' value."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
else
|
|
msg = "Input value is not an Node."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertNodeContainsOnly(node , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if type(node) = "roSGNode"
|
|
if not RBS_CMN_NodeContains(node, value)
|
|
msg = "Node doesn't have the '" + RBS_CMN_AsString(value) + "' value."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
else if node.getChildCount() <> 1
|
|
msg = "Node Contains speicified value; but other values as well"
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
else
|
|
msg = "Input value is not an Node."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertNodeNotContains(node , value , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if type(node) = "roSGNode"
|
|
if RBS_CMN_NodeContains(node, value)
|
|
msg = "Node has the '" + RBS_CMN_AsString(value) + "' value."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
else
|
|
msg = "Input value is not an Node."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertNodeContainsFields(node , subset , ignoredFields=invalid, msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if ( type(node) = "roSGNode" and RBS_CMN_IsAssociativeArray(subset)) or ( type(node) = "roSGNode" and RBS_CMN_IsArray(subset))
|
|
isAA = RBS_CMN_IsAssociativeArray(subset)
|
|
isIgnoredFields = RBS_CMN_IsArray(ignoredFields)
|
|
for each key in subset
|
|
if (key <> "")
|
|
if (not isIgnoredFields or not RBS_CMN_ArrayContains(ignoredFields, key))
|
|
subsetValue = subset[key]
|
|
nodeValue = node[key]
|
|
if not m.eqValues(nodeValue, subsetValue)
|
|
msg = key + ": Expected '" + RBS_CMN_AsString(subsetValue) + "', got '" + RBS_CMN_AsString(nodeValue) + "'"
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
end if
|
|
else
|
|
? "Found empty key!"
|
|
end if
|
|
end for
|
|
else
|
|
msg = "Input value is not an Node."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertNodeNotContainsFields(node , subset , msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if ( type(node) = "roSGNode" and RBS_CMN_IsAssociativeArray(subset)) or ( type(node) = "roSGNode" and RBS_CMN_IsArray(subset))
|
|
isAA = RBS_CMN_IsAssociativeArray(subset)
|
|
for each item in subset
|
|
key = invalid
|
|
value = item
|
|
if isAA
|
|
key = item
|
|
value = item[key]
|
|
end if
|
|
if RBS_CMN_NodeContains(node, value, key)
|
|
msg = "Node has the '" + RBS_CMN_AsString(value) + "' value."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
end for
|
|
else
|
|
msg = "Input value is not an Node."
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_AssertAAContainsSubset(array , subset , ignoredFields = invalid, msg = "" ) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
if (RBS_CMN_IsAssociativeArray(array) and RBS_CMN_IsAssociativeArray(subset))
|
|
isAA = RBS_CMN_IsAssociativeArray(subset)
|
|
isIgnoredFields = RBS_CMN_IsArray(ignoredFields)
|
|
for each key in subset
|
|
if (key <> "")
|
|
if (not isIgnoredFields or not RBS_CMN_ArrayContains(ignoredFields, key))
|
|
subsetValue = subset[key]
|
|
arrayValue = array[key]
|
|
if not m.eqValues(arrayValue, subsetValue)
|
|
msg = key + ": Expected '" + RBS_CMN_AsString(subsetValue) + "', got '" + RBS_CMN_AsString(arrayValue) + "'"
|
|
m.currentResult.AddResult(msg)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
end if
|
|
else
|
|
? "Found empty key!"
|
|
end if
|
|
end for
|
|
else
|
|
msg = "Input values are not an Associative Array."
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end if
|
|
m.currentResult.AddResult("")
|
|
return m.GetLegacyCompatibleReturnValue(true)
|
|
end function
|
|
function RBS_BTS_Stub(target, methodName, returnValue = invalid, allowNonExistingMethods = false) as object
|
|
if (type(target) <> "roAssociativeArray")
|
|
m.Fail("could not create Stub provided target was null")
|
|
return {}
|
|
end if
|
|
if (m.stubs =invalid)
|
|
m.__stubId = -1
|
|
m.stubs = {}
|
|
end if
|
|
m.__stubId++
|
|
if (m.__stubId > 5)
|
|
? "ERROR ONLY 6 STUBS PER TEST ARE SUPPORTED!!"
|
|
return invalid
|
|
end if
|
|
id = stri(m.__stubId).trim()
|
|
fake = m.CreateFake(id, target, methodName, 1, invalid, returnValue)
|
|
m.stubs[id] = fake
|
|
allowNonExisting = m.allowNonExistingMethodsOnMocks = true or allowNonExistingMethods
|
|
isMethodPresent = type(target[methodName]) = "Function" or type(target[methodName]) = "roFunction"
|
|
if (isMethodPresent or allowNonExisting)
|
|
target[methodName] = m["StubCallback" + id]
|
|
target.__stubs = m.stubs
|
|
if (not isMethodPresent)
|
|
? "WARNING - stubbing call " ; methodName; " which did not exist on target object"
|
|
end if
|
|
else
|
|
? "ERROR - could not create Stub : method not found "; target ; "." ; methodName
|
|
end if
|
|
return fake
|
|
end function
|
|
function RBS_BTS_ExpectOnce(target, methodName, expectedArgs = invalid, returnValue = invalid, allowNonExistingMethods = false) as object
|
|
return m.Mock(target, methodName, 1, expectedArgs, returnValue, allowNonExistingMethods)
|
|
end function
|
|
function RBS_BTS_ExpectOnceOrNone(target, methodName, isExpected, expectedArgs = invalid, returnValue = invalid, allowNonExistingMethods = false) as object
|
|
if isExpected
|
|
return m.ExpectOnce(target, methodName, expectedArgs, returnValue, allowNonExistingMethods)
|
|
else
|
|
return m.ExpectNone(target, methodName, allowNonExistingMethods)
|
|
end if
|
|
end function
|
|
function RBS_BTS_ExpectNone(target, methodName, allowNonExistingMethods = false) as object
|
|
return m.Mock(target, methodName, 0, invalid, invalid, allowNonExistingMethods)
|
|
end function
|
|
function RBS_BTS_Expect(target, methodName, expectedInvocations = 1, expectedArgs = invalid, returnValue = invalid, allowNonExistingMethods = false) as object
|
|
return m.Mock(target, methodName, expectedInvocations, expectedArgs, returnValue, allowNonExistingMethods)
|
|
end function
|
|
function RBS_BTS_Mock(target, methodName, expectedInvocations = 1, expectedArgs = invalid, returnValue = invalid, allowNonExistingMethods = false) as object
|
|
if not RBS_CMN_IsAssociativeArray(target)
|
|
m.Fail("mock args: target was not an AA")
|
|
else if not RBS_CMN_IsString(methodName)
|
|
m.Fail("mock args: methodName was not a string")
|
|
else if not RBS_CMN_IsNumber(expectedInvocations)
|
|
m.Fail("mock args: expectedInvocations was not an int")
|
|
else if not RBS_CMN_IsArray(expectedArgs) and RBS_CMN_IsValid(expectedArgs)
|
|
m.Fail("mock args: expectedArgs was not invalid or an array of args")
|
|
else if RBS_CMN_IsUndefined(expectedArgs)
|
|
m.Fail("mock args: expectedArgs undefined")
|
|
end if
|
|
if m.currentResult.isFail
|
|
? "ERROR: "; m.currentResult.messages[m.currentResult.currentAssertIndex - 1]
|
|
return {}
|
|
end if
|
|
if (m.mocks = invalid)
|
|
m.__mockId = -1
|
|
m.__mockTargetId = -1
|
|
m.mocks = {}
|
|
end if
|
|
fake = invalid
|
|
if not target.doesExist("__rooibosTargetId")
|
|
m.__mockTargetId++
|
|
target["__rooibosTargetId"] = m.__mockTargetId
|
|
end if
|
|
for i = 0 to m.__mockId
|
|
id = stri(i).trim()
|
|
mock = m.mocks[id]
|
|
if mock <> invalid and mock.methodName = methodName and mock.target.__rooibosTargetId = target.__rooibosTargetId
|
|
fake = mock
|
|
exit for
|
|
end if
|
|
end for
|
|
if fake = invalid
|
|
m.__mockId++
|
|
id = stri(m.__mockId).trim()
|
|
if (m.__mockId > 6)
|
|
? "ERROR ONLY 6 MOCKS PER TEST ARE SUPPORTED!! you're on # " ; m.__mockId
|
|
? " Method was " ; methodName
|
|
return invalid
|
|
end if
|
|
fake = m.CreateFake(id, target, methodName, expectedInvocations, expectedArgs, returnValue)
|
|
m.mocks[id] = fake 'this will bind it to m
|
|
allowNonExisting = m.allowNonExistingMethodsOnMocks = true or allowNonExistingMethods
|
|
isMethodPresent = type(target[methodName]) = "Function" or type(target[methodName]) = "roFunction"
|
|
if (isMethodPresent or allowNonExisting)
|
|
target[methodName] = m["MockCallback" + id]
|
|
target.__mocks = m.mocks
|
|
if (not isMethodPresent)
|
|
? "WARNING - mocking call " ; methodName; " which did not exist on target object"
|
|
end if
|
|
else
|
|
? "ERROR - could not create Mock : method not found "; target ; "." ; methodName
|
|
end if
|
|
else
|
|
m.CombineFakes(fake, m.CreateFake(id, target, methodName, expectedInvocations, expectedArgs, returnValue))
|
|
end if
|
|
return fake
|
|
end function
|
|
function RBS_BTS_CreateFake(id, target, methodName, expectedInvocations = 1, expectedArgs =invalid, returnValue=invalid ) as object
|
|
expectedArgsValues = []
|
|
hasArgs = RBS_CMN_IsArray(expectedArgs)
|
|
if (hasArgs)
|
|
defaultValue = m.invalidValue
|
|
else
|
|
defaultValue = m.ignoreValue
|
|
expectedArgs = []
|
|
end if
|
|
for i = 0 to 9
|
|
if (hasArgs and expectedArgs.count() > i)
|
|
value = expectedArgs[i]
|
|
if not RBS_CMN_IsUndefined(value)
|
|
expectedArgsValues.push(expectedArgs[i])
|
|
else
|
|
expectedArgsValues.push("#ERR-UNDEFINED!")
|
|
end if
|
|
else
|
|
expectedArgsValues.push(defaultValue)
|
|
end if
|
|
end for
|
|
fake = {
|
|
id : id,
|
|
target: target,
|
|
methodName: methodName,
|
|
returnValue: returnValue,
|
|
isCalled: false,
|
|
invocations: 0,
|
|
invokedArgs: [invalid, invalid, invalid, invalid, invalid, invalid, invalid, invalid, invalid],
|
|
expectedArgs: expectedArgsValues,
|
|
expectedInvocations: expectedInvocations,
|
|
callback: function (arg1=invalid, arg2=invalid, arg3=invalid, arg4=invalid, arg5=invalid, arg6=invalid, arg7=invalid, arg8=invalid, arg9 =invalid)as dynamic
|
|
if (m.allInvokedArgs = invalid)
|
|
m.allInvokedArgs = []
|
|
end if
|
|
m.invokedArgs = [arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 ]
|
|
m.allInvokedArgs.push ([arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 ])
|
|
m.isCalled = true
|
|
m.invocations++
|
|
if (type(m.returnValue) = "roAssociativeArray" and m.returnValue.doesExist("multiResult"))
|
|
returnValues = m.returnValue["multiResult"]
|
|
returnIndex = m.invocations -1
|
|
if (type(returnValues) = "roArray" and returnValues.count() > 0)
|
|
if returnValues.count() <= m.invocations
|
|
returnIndex = returnValues.count() -1
|
|
print "Multi return values all used up - repeating last value"
|
|
end if
|
|
return returnValues[returnIndex]
|
|
else
|
|
? "Multi return value was specified; but no array of results were found"
|
|
return invalid
|
|
end if
|
|
else
|
|
return m.returnValue
|
|
end if
|
|
end function
|
|
}
|
|
return fake
|
|
end function
|
|
function RBS_BTS_CombineFakes(fake, otherFake)
|
|
if type(fake.expectedArgs) <> "roAssociativeArray" or not fake.expectedArgs.doesExist("multiInvoke")
|
|
currentExpectedArgsArgs = fake.expectedArgs
|
|
fake.expectedArgs = {
|
|
"multiInvoke": [currentExpectedArgsArgs]
|
|
}
|
|
end if
|
|
fake.expectedArgs.multiInvoke.push(otherFake.expectedArgs)
|
|
if type(fake.returnValue) <> "roAssociativeArray" or not fake.returnValue.doesExist("multiResult")
|
|
currentReturnValue = fake.returnValue
|
|
fake.returnValue = {
|
|
"multiResult": [currentReturnValue]
|
|
}
|
|
end if
|
|
fake.returnValue.multiResult.push(otherFake.returnValue)
|
|
fake.expectedInvocations++
|
|
end function
|
|
function RBS_BTS_AssertMocks() as void
|
|
if (m.__mockId = invalid or not RBS_CMN_IsAssociativeArray(m.mocks))
|
|
return
|
|
end if
|
|
lastId = int(m.__mockId)
|
|
for each id in m.mocks
|
|
mock = m.mocks[id]
|
|
methodName = mock.methodName
|
|
if (mock.expectedInvocations <> mock.invocations)
|
|
m.MockFail(methodName, "Wrong number of calls. (" + stri(mock.invocations).trim() + " / " + stri(mock.expectedInvocations).trim() + ")")
|
|
m.CleanMocks()
|
|
return
|
|
else if mock.expectedInvocations > 0 and (RBS_CMN_IsArray(mock.expectedArgs) or (type(mock.expectedArgs) = "roAssociativeArray" and RBS_CMN_IsArray(mock.expectedArgs.multiInvoke)))
|
|
isMultiArgsSupported = type(mock.expectedArgs) = "roAssociativeArray" and RBS_CMN_IsArray(mock.expectedArgs.multiInvoke)
|
|
for invocationIndex = 0 to mock.invocations - 1
|
|
invokedArgs = mock.allInvokedArgs[invocationIndex]
|
|
if isMultiArgsSupported
|
|
expectedArgs = mock.expectedArgs.multiInvoke[invocationIndex]
|
|
else
|
|
expectedArgs = mock.expectedArgs
|
|
end if
|
|
for i = 0 to expectedArgs.count() -1
|
|
value = invokedArgs[i]
|
|
expected = expectedArgs[i]
|
|
didNotExpectArg = RBS_CMN_IsString(expected) and expected = m.invalidValue
|
|
if (didNotExpectArg)
|
|
expected = invalid
|
|
end if
|
|
if (not (RBS_CMN_IsString(expected) and expected = m.ignoreValue) and not m.eqValues(value, expected))
|
|
if (expected = invalid)
|
|
expected = "[INVALID]"
|
|
end if
|
|
m.MockFail(methodName, "on Invocation #" + stri(invocationIndex).trim() + ", expected arg #" + stri(i).trim() + " to be '" + RBS_CMN_AsString(expected) + "' got '" + RBS_CMN_AsString(value) + "')")
|
|
m.CleanMocks()
|
|
return
|
|
end if
|
|
end for
|
|
end for
|
|
end if
|
|
end for
|
|
m.CleanMocks()
|
|
end function
|
|
function RBS_BTS_CleanMocks() as void
|
|
if m.mocks = invalid return
|
|
for each id in m.mocks
|
|
mock = m.mocks[id]
|
|
mock.target.__mocks = invalid
|
|
end for
|
|
m.mocks = invalid
|
|
end function
|
|
function RBS_BTS_CleanStubs() as void
|
|
if m.stubs = invalid return
|
|
for each id in m.stubs
|
|
stub = m.stubs[id]
|
|
stub.target.__stubs = invalid
|
|
end for
|
|
m.stubs = invalid
|
|
end function
|
|
function RBS_BTS_MockFail(methodName, message) as dynamic
|
|
if (m.currentResult.isFail) then return m.GetLegacyCompatibleReturnValue(false) ' skip test we already failed
|
|
m.currentResult.AddResult("mock failure on '" + methodName + "' : " + message)
|
|
return m.GetLegacyCompatibleReturnValue(false)
|
|
end function
|
|
function RBS_BTS_StubCallback0(arg1=invalid, arg2=invalid, arg3=invalid, arg4=invalid, arg5=invalid, arg6=invalid, arg7=invalid, arg8=invalid, arg9 =invalid)as dynamic
|
|
fake = m.__Stubs["0"]
|
|
return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
|
end function
|
|
function RBS_BTS_StubCallback1(arg1=invalid, arg2=invalid, arg3=invalid, arg4=invalid, arg5=invalid, arg6=invalid, arg7=invalid, arg8=invalid, arg9 =invalid)as dynamic
|
|
fake = m.__Stubs["1"]
|
|
return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
|
end function
|
|
function RBS_BTS_StubCallback2(arg1=invalid, arg2=invalid, arg3=invalid, arg4=invalid, arg5=invalid, arg6=invalid, arg7=invalid, arg8=invalid, arg9 =invalid)as dynamic
|
|
fake = m.__Stubs["2"]
|
|
return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
|
end function
|
|
function RBS_BTS_StubCallback3(arg1=invalid, arg2=invalid, arg3=invalid, arg4=invalid, arg5=invalid, arg6=invalid, arg7=invalid, arg8=invalid, arg9 =invalid)as dynamic
|
|
fake = m.__Stubs["3"]
|
|
return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
|
end function
|
|
function RBS_BTS_StubCallback4(arg1=invalid, arg2=invalid, arg3=invalid, arg4=invalid, arg5=invalid, arg6=invalid, arg7=invalid, arg8=invalid, arg9 =invalid)as dynamic
|
|
fake = m.__Stubs["4"]
|
|
return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
|
end function
|
|
function RBS_BTS_StubCallback5(arg1=invalid, arg2=invalid, arg3=invalid, arg4=invalid, arg5=invalid, arg6=invalid, arg7=invalid, arg8=invalid, arg9 =invalid)as dynamic
|
|
fake = m.__Stubs["5"]
|
|
return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
|
end function
|
|
function RBS_BTS_MockCallback0(arg1=invalid, arg2=invalid, arg3=invalid, arg4=invalid, arg5=invalid, arg6=invalid, arg7=invalid, arg8=invalid, arg9 =invalid)as dynamic
|
|
fake = m.__mocks["0"]
|
|
return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
|
end function
|
|
function RBS_BTS_MockCallback1(arg1=invalid, arg2=invalid, arg3=invalid, arg4=invalid, arg5=invalid, arg6=invalid, arg7=invalid, arg8=invalid, arg9 =invalid)as dynamic
|
|
fake = m.__mocks["1"]
|
|
return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
|
end function
|
|
function RBS_BTS_MockCallback2(arg1=invalid, arg2=invalid, arg3=invalid, arg4=invalid, arg5=invalid, arg6=invalid, arg7=invalid, arg8=invalid, arg9 =invalid)as dynamic
|
|
fake = m.__mocks["2"]
|
|
return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
|
end function
|
|
function RBS_BTS_MockCallback3(arg1=invalid, arg2=invalid, arg3=invalid, arg4=invalid, arg5=invalid, arg6=invalid, arg7=invalid, arg8=invalid, arg9 =invalid)as dynamic
|
|
fake = m.__mocks["3"]
|
|
return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
|
end function
|
|
function RBS_BTS_MockCallback4(arg1=invalid, arg2=invalid, arg3=invalid, arg4=invalid, arg5=invalid, arg6=invalid, arg7=invalid, arg8=invalid, arg9 =invalid)as dynamic
|
|
fake = m.__mocks["4"]
|
|
return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
|
end function
|
|
function RBS_BTS_MockCallback5(arg1=invalid, arg2=invalid, arg3=invalid, arg4=invalid, arg5=invalid, arg6=invalid, arg7=invalid, arg8=invalid, arg9 =invalid)as dynamic
|
|
fake = m.__mocks["5"]
|
|
return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
|
end function
|
|
function RBS_BTS_rodash_pathsAsArray_(path)
|
|
pathRE = CreateObject("roRegex", "\[([0-9]+)\]", "i")
|
|
segments = []
|
|
if type(path) = "String" or type(path) = "roString"
|
|
dottedPath = pathRE.replaceAll(path, ".\1")
|
|
stringSegments = dottedPath.tokenize(".")
|
|
for each s in stringSegments
|
|
if (Asc(s) >= 48) and (Asc(s) <= 57)
|
|
segments.push(s.toInt())
|
|
else
|
|
segments.push(s)
|
|
end if
|
|
end for
|
|
else if type(path) = "roList" or type(path) = "roArray"
|
|
stringPath = ""
|
|
for each s in path
|
|
stringPath = stringPath + "." + Box(s).toStr()
|
|
end for
|
|
segments = m.pathAsArray_(stringPath)
|
|
else
|
|
segments = invalid
|
|
end if
|
|
return segments
|
|
end function
|
|
function RBS_BTS_rodash_get_(aa, path, default=invalid)
|
|
if type(aa) <> "roAssociativeArray" and type(aa) <> "roArray" and type(aa) <> "roSGNode" then return default
|
|
segments = m.pathAsArray_(path)
|
|
if (Type(path) = "roInt" or Type(path) = "roInteger" or Type(path) = "Integer")
|
|
path = stri(path).trim()
|
|
end if
|
|
if segments = invalid then return default
|
|
result = invalid
|
|
while segments.count() > 0
|
|
key = segments.shift()
|
|
if (type(key) = "roInteger") 'it's a valid index
|
|
if (aa <> invalid and GetInterface(aa, "ifArray") <> invalid)
|
|
value = aa[key]
|
|
else if (aa <> invalid and GetInterface(aa, "ifSGNodeChildren") <> invalid)
|
|
value = aa.getChild(key)
|
|
else if (aa <> invalid and GetInterface(aa, "ifAssociativeArray") <> invalid)
|
|
key = tostr(key)
|
|
if not aa.doesExist(key)
|
|
exit while
|
|
end if
|
|
value = aa.lookup(key)
|
|
else
|
|
value = invalid
|
|
end if
|
|
else
|
|
if not aa.doesExist(key)
|
|
exit while
|
|
end if
|
|
value = aa.lookup(key)
|
|
end if
|
|
if segments.count() = 0
|
|
result = value
|
|
exit while
|
|
end if
|
|
if type(value) <> "roAssociativeArray" and type(value) <> "roArray" and type(value) <> "roSGNode"
|
|
exit while
|
|
end if
|
|
aa = value
|
|
end while
|
|
if result = invalid then return default
|
|
return result
|
|
end function
|
|
function RBS_CMN_IsXmlElement(value ) as boolean
|
|
return RBS_CMN_IsValid(value) and GetInterface(value, "ifXMLElement") <> invalid
|
|
end function
|
|
function RBS_CMN_IsFunction(value ) as boolean
|
|
return RBS_CMN_IsValid(value) and GetInterface(value, "ifFunction") <> invalid
|
|
end function
|
|
function RBS_CMN_GetFunction(filename, functionName) as object
|
|
if (not RBS_CMN_IsNotEmptyString(functionName)) then return invalid
|
|
if (not RBS_CMN_IsNotEmptyString(filename)) then return invalid
|
|
mapFunction = RBSFM_getFunctionsForFile(filename)
|
|
if mapFunction <> invalid
|
|
map = mapFunction()
|
|
if (type(map) ="roAssociativeArray")
|
|
functionPointer = map[functionName]
|
|
return functionPointer
|
|
else
|
|
return invalid
|
|
end if
|
|
end if
|
|
return invalid
|
|
end function
|
|
function RBS_CMN_GetFunctionBruteForce(functionName) as object
|
|
if (not RBS_CMN_IsNotEmptyString(functionName)) then return invalid
|
|
filenames = RBSFM_getFilenames()
|
|
for i = 0 to filenames.count() - 1
|
|
filename = filenames[i]
|
|
mapFunction = RBSFM_getFunctionsForFile(filename)
|
|
if mapFunction <> invalid
|
|
map = mapFunction()
|
|
if (type(map) ="roAssociativeArray")
|
|
functionPointer = map[functionName]
|
|
if functionPointer <> invalid
|
|
return functionPointer
|
|
end if
|
|
end if
|
|
end if
|
|
end for
|
|
return invalid
|
|
end function
|
|
function RBS_CMN_IsBoolean(value ) as boolean
|
|
return RBS_CMN_IsValid(value) and GetInterface(value, "ifBoolean") <> invalid
|
|
end function
|
|
function RBS_CMN_IsInteger(value ) as boolean
|
|
return RBS_CMN_IsValid(value) and GetInterface(value, "ifInt") <> invalid and (Type(value) = "roInt" or Type(value) = "roInteger" or Type(value) = "Integer")
|
|
end function
|
|
function RBS_CMN_IsFloat(value ) as boolean
|
|
return RBS_CMN_IsValid(value) and GetInterface(value, "ifFloat") <> invalid
|
|
end function
|
|
function RBS_CMN_IsDouble(value ) as boolean
|
|
return RBS_CMN_IsValid(value) and GetInterface(value, "ifDouble") <> invalid
|
|
end function
|
|
function RBS_CMN_IsLongInteger(value ) as boolean
|
|
return RBS_CMN_IsValid(value) and GetInterface(value, "ifLongInt") <> invalid
|
|
end function
|
|
function RBS_CMN_IsNumber(value ) as boolean
|
|
return RBS_CMN_IsLongInteger(value) or RBS_CMN_IsDouble(value) or RBS_CMN_IsInteger(value) or RBS_CMN_IsFloat(value)
|
|
end function
|
|
function RBS_CMN_IsList(value ) as boolean
|
|
return RBS_CMN_IsValid(value) and GetInterface(value, "ifList") <> invalid
|
|
end function
|
|
function RBS_CMN_IsArray(value ) as boolean
|
|
return RBS_CMN_IsValid(value) and GetInterface(value, "ifArray") <> invalid
|
|
end function
|
|
function RBS_CMN_IsAssociativeArray(value ) as boolean
|
|
return RBS_CMN_IsValid(value) and GetInterface(value, "ifAssociativeArray") <> invalid
|
|
end function
|
|
function RBS_CMN_IsSGNode(value ) as boolean
|
|
return RBS_CMN_IsValid(value) and GetInterface(value, "ifSGNodeChildren") <> invalid
|
|
end function
|
|
function RBS_CMN_IsString(value ) as boolean
|
|
return RBS_CMN_IsValid(value) and GetInterface(value, "ifString") <> invalid
|
|
end function
|
|
function RBS_CMN_IsNotEmptyString(value ) as boolean
|
|
return RBS_CMN_IsString(value) and len(value) > 0
|
|
end function
|
|
function RBS_CMN_IsDateTime(value ) as boolean
|
|
return RBS_CMN_IsValid(value) and (GetInterface(value, "ifDateTime") <> invalid or Type(value) = "roDateTime")
|
|
end function
|
|
function RBS_CMN_IsValid(value ) as boolean
|
|
return not RBS_CMN_IsUndefined(value) and value <> invalid
|
|
end function
|
|
function RBS_CMN_IsUndefined(value ) as boolean
|
|
return type(value) = "" or Type(value) = "<uninitialized>"
|
|
end function
|
|
function RBS_CMN_ValidStr(obj ) as string
|
|
if obj <> invalid and GetInterface(obj, "ifString") <> invalid
|
|
return obj
|
|
else
|
|
return ""
|
|
end if
|
|
end function
|
|
function RBS_CMN_AsString(input ) as string
|
|
if RBS_CMN_IsValid(input) = false
|
|
return ""
|
|
else if RBS_CMN_IsString(input)
|
|
return input
|
|
else if RBS_CMN_IsInteger(input) or RBS_CMN_IsLongInteger(input) or RBS_CMN_IsBoolean(input)
|
|
return input.ToStr()
|
|
else if RBS_CMN_IsFloat(input) or RBS_CMN_IsDouble(input)
|
|
return Str(input).Trim()
|
|
else if type(input) = "roSGNode"
|
|
return "Node(" + input.subType() +")"
|
|
else if type(input) = "roAssociativeArray"
|
|
isFirst = true
|
|
text = "{"
|
|
if (not isFirst)
|
|
text += ","
|
|
isFirst = false
|
|
end if
|
|
for each key in input
|
|
text += key + ":" + RBS_CMN_AsString(input[key])
|
|
end for
|
|
text += "}"
|
|
return text
|
|
else
|
|
return ""
|
|
end if
|
|
end function
|
|
function RBS_CMN_AsInteger(input ) as integer
|
|
if RBS_CMN_IsValid(input) = false
|
|
return 0
|
|
else if RBS_CMN_IsString(input)
|
|
return input.ToInt()
|
|
else if RBS_CMN_IsInteger(input)
|
|
return input
|
|
else if RBS_CMN_IsFloat(input) or RBS_CMN_IsDouble(input) or RBS_CMN_IsLongInteger(input)
|
|
return Int(input)
|
|
else
|
|
return 0
|
|
end if
|
|
end function
|
|
function RBS_CMN_AsLongInteger(input ) as longinteger
|
|
if RBS_CMN_IsValid(input) = false
|
|
return 0
|
|
else if RBS_CMN_IsString(input)
|
|
return RBS_CMN_AsInteger(input)
|
|
else if RBS_CMN_IsLongInteger(input) or RBS_CMN_IsFloat(input) or RBS_CMN_IsDouble(input) or RBS_CMN_IsInteger(input)
|
|
return input
|
|
else
|
|
return 0
|
|
end if
|
|
end function
|
|
function RBS_CMN_AsFloat(input ) as float
|
|
if RBS_CMN_IsValid(input) = false
|
|
return 0.0
|
|
else if RBS_CMN_IsString(input)
|
|
return input.ToFloat()
|
|
else if RBS_CMN_IsInteger(input)
|
|
return (input / 1)
|
|
else if RBS_CMN_IsFloat(input) or RBS_CMN_IsDouble(input) or RBS_CMN_IsLongInteger(input)
|
|
return input
|
|
else
|
|
return 0.0
|
|
end if
|
|
end function
|
|
function RBS_CMN_AsDouble(input ) as double
|
|
if RBS_CMN_IsValid(input) = false
|
|
return 0.0
|
|
else if RBS_CMN_IsString(input)
|
|
return RBS_CMN_AsFloat(input)
|
|
else if RBS_CMN_IsInteger(input) or RBS_CMN_IsLongInteger(input) or RBS_CMN_IsFloat(input) or RBS_CMN_IsDouble(input)
|
|
return input
|
|
else
|
|
return 0.0
|
|
end if
|
|
end function
|
|
function RBS_CMN_AsBoolean(input ) as boolean
|
|
if RBS_CMN_IsValid(input) = false
|
|
return false
|
|
else if RBS_CMN_IsString(input)
|
|
return LCase(input) = "true"
|
|
else if RBS_CMN_IsInteger(input) or RBS_CMN_IsFloat(input)
|
|
return input <> 0
|
|
else if RBS_CMN_IsBoolean(input)
|
|
return input
|
|
else
|
|
return false
|
|
end if
|
|
end function
|
|
function RBS_CMN_AsArray(value ) as object
|
|
if RBS_CMN_IsValid(value)
|
|
if not RBS_CMN_IsArray(value)
|
|
return [value]
|
|
else
|
|
return value
|
|
end if
|
|
end if
|
|
return []
|
|
end function
|
|
function RBS_CMN_IsNullOrEmpty(value ) as boolean
|
|
if RBS_CMN_IsString(value)
|
|
return Len(value) = 0
|
|
else
|
|
return not RBS_CMN_IsValid(value)
|
|
end if
|
|
end function
|
|
function RBS_CMN_FindElementIndexInArray(array , value , compareAttribute = invalid , caseSensitive = false ) as integer
|
|
if RBS_CMN_IsArray(array)
|
|
for i = 0 to RBS_CMN_AsArray(array).Count() - 1
|
|
compareValue = array[i]
|
|
if compareAttribute <> invalid and RBS_CMN_IsAssociativeArray(compareValue)
|
|
compareValue = compareValue.LookupCI(compareAttribute)
|
|
end if
|
|
if RBS_BTS_EqValues(compareValue, value)
|
|
return i
|
|
end if
|
|
item = array[i]
|
|
next
|
|
end if
|
|
return -1
|
|
end function
|
|
function RBS_CMN_ArrayContains(array , value , compareAttribute = invalid ) as boolean
|
|
return (RBS_CMN_FindElementIndexInArray(array, value, compareAttribute) > -1)
|
|
end function
|
|
function RBS_CMN_FindElementIndexInNode(node , value ) as integer
|
|
if type(node) = "roSGNode"
|
|
for i = 0 to node.getChildCount() - 1
|
|
compareValue = node.getChild(i)
|
|
if type(compareValue) = "roSGNode" and compareValue.isSameNode(value)
|
|
return i
|
|
end if
|
|
next
|
|
end if
|
|
return -1
|
|
end function
|
|
function RBS_CMN_NodeContains(node , value ) as boolean
|
|
return (RBS_CMN_FindElementIndexInNode(node, value) > -1)
|
|
end function
|
|
function RBS_ItG_GetTestCases(group) as object
|
|
if (group.hasSoloTests = true)
|
|
return group.soloTestCases
|
|
else
|
|
return group.testCases
|
|
end if
|
|
end function
|
|
function RBS_ItG_GetRunnableTestSuite(group) as object
|
|
testCases = RBS_ItG_GetTestCases(group)
|
|
runnableSuite = BaseTestSuite()
|
|
runnableSuite.name = group.name
|
|
runnableSuite.isLegacy = group.isLegacy = true
|
|
if group.testCaseLookup = invalid
|
|
group.testCaseLookup = {}
|
|
end if
|
|
for each testCase in testCases
|
|
name = testCase.name
|
|
if (testCase.isSolo = true)
|
|
name += " [SOLO] "
|
|
end if
|
|
testFunction = RBS_CMN_GetFunction(group.filename, testCase.funcName)
|
|
runnableSuite.addTest(name, testFunction, testCase.funcName)
|
|
group.testCaseLookup[name] = testCase
|
|
end for
|
|
runnableSuite.SetUp = RBS_CMN_GetFunction(group.filename, group.setupFunctionName)
|
|
runnableSuite.TearDown = RBS_CMN_GetFunction(group.filename, group.teardownFunctionName)
|
|
runnableSuite.BeforeEach = RBS_CMN_GetFunction(group.filename, group.beforeEachFunctionName)
|
|
runnableSuite.AfterEach = RBS_CMN_GetFunction(group.filename, group.afterEachFunctionName)
|
|
return runnableSuite
|
|
end function
|
|
function ItemGenerator(scheme as object) as object
|
|
this = {}
|
|
this.getItem = RBS_IG_GetItem
|
|
this.getAssocArray = RBS_IG_GetAssocArray
|
|
this.getArray = RBS_IG_GetArray
|
|
this.getSimpleType = RBS_IG_GetSimpleType
|
|
this.getInteger = RBS_IG_GetInteger
|
|
this.getFloat = RBS_IG_GetFloat
|
|
this.getString = RBS_IG_GetString
|
|
this.getBoolean = RBS_IG_GetBoolean
|
|
if not RBS_CMN_IsValid(scheme)
|
|
return invalid
|
|
end if
|
|
return this.getItem(scheme)
|
|
end function
|
|
function RBS_IG_GetItem(scheme as object) as object
|
|
item = invalid
|
|
if RBS_CMN_IsAssociativeArray(scheme)
|
|
item = m.getAssocArray(scheme)
|
|
else if RBS_CMN_IsArray(scheme)
|
|
item = m.getArray(scheme)
|
|
else if RBS_CMN_IsString(scheme)
|
|
item = m.getSimpleType(lCase(scheme))
|
|
end if
|
|
return item
|
|
end function
|
|
function RBS_IG_GetAssocArray(scheme as object) as object
|
|
item = {}
|
|
for each key in scheme
|
|
if not item.DoesExist(key)
|
|
item[key] = m.getItem(scheme[key])
|
|
end if
|
|
end for
|
|
return item
|
|
end function
|
|
function RBS_IG_GetArray(scheme as object) as object
|
|
item = []
|
|
for each key in scheme
|
|
item.Push(m.getItem(key))
|
|
end for
|
|
return item
|
|
end function
|
|
function RBS_IG_GetSimpleType(typeStr as string) as object
|
|
item = invalid
|
|
if typeStr = "integer" or typeStr = "int" or typeStr = "roint"
|
|
item = m.getInteger()
|
|
else if typeStr = "float" or typeStr = "rofloat"
|
|
item = m.getFloat()
|
|
else if typeStr = "string" or typeStr = "rostring"
|
|
item = m.getString(10)
|
|
else if typeStr = "boolean" or typeStr = "roboolean"
|
|
item = m.getBoolean()
|
|
end if
|
|
return item
|
|
end function
|
|
function RBS_IG_GetBoolean() as boolean
|
|
return RBS_CMN_AsBoolean(Rnd(2) \ Rnd(2))
|
|
end function
|
|
function RBS_IG_GetInteger(seed = 100 as integer) as integer
|
|
return Rnd(seed)
|
|
end function
|
|
function RBS_IG_GetFloat() as float
|
|
return Rnd(0)
|
|
end function
|
|
function RBS_IG_GetString(seed as integer) as string
|
|
item = ""
|
|
if seed > 0
|
|
stringLength = Rnd(seed)
|
|
for i = 0 to stringLength
|
|
chType = Rnd(3)
|
|
if chType = 1 'Chr(48-57) - numbers
|
|
chNumber = 47 + Rnd(10)
|
|
else if chType = 2 'Chr(65-90) - Uppercase Letters
|
|
chNumber = 64 + Rnd(26)
|
|
else 'Chr(97-122) - Lowercase Letters
|
|
chNumber = 96 + Rnd(26)
|
|
end if
|
|
item = item + Chr(chNumber)
|
|
end for
|
|
end if
|
|
return item
|
|
end function
|
|
function UnitTestRuntimeConfig()
|
|
this = {}
|
|
this.CreateSuites = RBS_CreateSuites
|
|
this.hasSoloSuites = false
|
|
this.hasSoloGroups = false
|
|
this.hasSoloTests = false
|
|
this.suites = this.CreateSuites()
|
|
return this
|
|
end function
|
|
function RBS_CreateSuites()
|
|
suites = RBSFM_getTestSuitesForProject()
|
|
includedSuites = []
|
|
for i = 0 to suites.count() -1
|
|
suite = suites[i]
|
|
if (suite.valid)
|
|
if (suite.isSolo)
|
|
m.hasSoloSuites = true
|
|
end if
|
|
if (suite.hasSoloTests = true)
|
|
m.hasSoloTests = true
|
|
end if
|
|
if (suite.hasSoloGroups = true)
|
|
m.hasSoloGroups = true
|
|
end if
|
|
includedSuites.Push(suite)
|
|
else
|
|
? "ERROR! suite was not valid - ignoring"
|
|
end if
|
|
end for
|
|
return includedSuites
|
|
end function
|
|
function RBS_STATS_CreateTotalStatistic() as object
|
|
statTotalItem = {
|
|
Suites : []
|
|
Time : 0
|
|
Total : 0
|
|
Correct : 0
|
|
Fail : 0
|
|
Ignored : 0
|
|
Crash : 0
|
|
IgnoredTestNames: []
|
|
}
|
|
return statTotalItem
|
|
end function
|
|
function RBS_STATS_MergeTotalStatistic(stat1, stat2) as void
|
|
for each suite in stat2.Suites
|
|
stat1.Suites.push(suite)
|
|
end for
|
|
stat1.Time += stat2.Time
|
|
stat1.Total += stat2.Total
|
|
stat1.Correct += stat2.Correct
|
|
stat1.Fail += stat2.Fail
|
|
stat1.Crash += stat2.Crash
|
|
stat1.Ignored += stat2.Ignored
|
|
stat1.IgnoredTestNames.append(stat2.IgnoredTestNames)
|
|
end function
|
|
function RBS_STATS_CreateSuiteStatistic(name as string) as object
|
|
statSuiteItem = {
|
|
Name : name
|
|
Tests : []
|
|
Time : 0
|
|
Total : 0
|
|
Correct : 0
|
|
Fail : 0
|
|
Crash : 0
|
|
Ignored : 0
|
|
IgnoredTestNames:[]
|
|
}
|
|
return statSuiteItem
|
|
end function
|
|
function RBS_STATS_CreateTestStatistic(name as string, result = "Success" as string, time = 0 as integer, errorCode = 0 as integer, errorMessage = "" as string) as object
|
|
statTestItem = {
|
|
Name : name
|
|
Result : result
|
|
Time : time
|
|
Error : {
|
|
Code : errorCode
|
|
Message : errorMessage
|
|
}
|
|
}
|
|
return statTestItem
|
|
end function
|
|
sub RBS_STATS_AppendTestStatistic(statSuiteObj as object, statTestObj as object)
|
|
if RBS_CMN_IsAssociativeArray(statSuiteObj) and RBS_CMN_IsAssociativeArray(statTestObj)
|
|
statSuiteObj.Tests.Push(statTestObj)
|
|
if RBS_CMN_IsInteger(statTestObj.time)
|
|
statSuiteObj.Time = statSuiteObj.Time + statTestObj.Time
|
|
end if
|
|
statSuiteObj.Total = statSuiteObj.Total + 1
|
|
if lCase(statTestObj.Result) = "success"
|
|
statSuiteObj.Correct = statSuiteObj.Correct + 1
|
|
else if lCase(statTestObj.result) = "fail"
|
|
statSuiteObj.Fail = statSuiteObj.Fail + 1
|
|
else
|
|
statSuiteObj.crash = statSuiteObj.crash + 1
|
|
end if
|
|
end if
|
|
end sub
|
|
sub RBS_STATS_AppendSuiteStatistic(statTotalObj as object, statSuiteObj as object)
|
|
if RBS_CMN_IsAssociativeArray(statTotalObj) and RBS_CMN_IsAssociativeArray(statSuiteObj)
|
|
statTotalObj.Suites.Push(statSuiteObj)
|
|
statTotalObj.Time = statTotalObj.Time + statSuiteObj.Time
|
|
if RBS_CMN_IsInteger(statSuiteObj.Total)
|
|
statTotalObj.Total = statTotalObj.Total + statSuiteObj.Total
|
|
end if
|
|
if RBS_CMN_IsInteger(statSuiteObj.Correct)
|
|
statTotalObj.Correct = statTotalObj.Correct + statSuiteObj.Correct
|
|
end if
|
|
if RBS_CMN_IsInteger(statSuiteObj.Fail)
|
|
statTotalObj.Fail = statTotalObj.Fail + statSuiteObj.Fail
|
|
end if
|
|
if RBS_CMN_IsInteger(statSuiteObj.Crash)
|
|
statTotalObj.Crash = statTotalObj.Crash + statSuiteObj.Crash
|
|
end if
|
|
end if
|
|
end sub
|
|
function UnitTestCase(name as string, func as dynamic, funcName as string, isSolo as boolean, isIgnored as boolean, lineNumber as integer, params = invalid, paramTestIndex =0, paramLineNumber = 0)
|
|
this = {}
|
|
this.isSolo = isSolo
|
|
this.func = func
|
|
this.funcName = funcName
|
|
this.isIgnored = isIgnored
|
|
this.name = name
|
|
this.lineNumber = lineNumber
|
|
this.paramLineNumber = paramLineNumber
|
|
this.assertIndex = 0
|
|
this.assertLineNumberMap = {}
|
|
this.AddAssertLine = RBS_TC_AddAssertLine
|
|
this.getTestLineIndex = 0
|
|
this.rawParams = params
|
|
this.paramTestIndex = paramTestIndex
|
|
this.isParamTest = false
|
|
this.time = 0
|
|
if (params <> invalid)
|
|
this.name += stri(this.paramTestIndex)
|
|
end if
|
|
return this
|
|
end function
|
|
function RBS_TC_AddAssertLine(lineNumber as integer)
|
|
m.assertLineNumberMap[stri(m.assertIndex).trim()] = lineNumber
|
|
m.assertIndex++
|
|
end function
|
|
function RBS_TC_GetAssertLine(testCase, index)
|
|
if (testCase.assertLineNumberMap.doesExist(stri(index).trim()))
|
|
return testCase.assertLineNumberMap[stri(index).trim()]
|
|
else
|
|
return testCase.lineNumber
|
|
end if
|
|
end function
|
|
function Logger(config) as object
|
|
this = {}
|
|
this.config = config
|
|
this.verbosityLevel = {
|
|
basic : 0
|
|
normal : 1
|
|
verbose : 2
|
|
}
|
|
this.verbosity = this.config.logLevel
|
|
this.PrintStatistic = RBS_LOGGER_PrintStatistic
|
|
this.PrintMetaSuiteStart = RBS_LOGGER_PrintMetaSuiteStart
|
|
this.PrintSuiteStatistic = RBS_LOGGER_PrintSuiteStatistic
|
|
this.PrintTestStatistic = RBS_LOGGER_PrintTestStatistic
|
|
this.PrintStart = RBS_LOGGER_PrintStart
|
|
this.PrintEnd = RBS_LOGGER_PrintEnd
|
|
this.PrintSuiteStart = RBS_LOGGER_PrintSuiteStart
|
|
return this
|
|
end function
|
|
sub RBS_LOGGER_PrintStatistic(statObj as object)
|
|
m.PrintStart()
|
|
previousfile = invalid
|
|
for each testSuite in statObj.Suites
|
|
if (not statObj.testRunHasFailures or ((not m.config.showOnlyFailures) or testSuite.fail > 0 or testSuite.crash > 0))
|
|
if (testSuite.metaTestSuite.filePath <> previousfile)
|
|
m.PrintMetaSuiteStart(testSuite.metaTestSuite)
|
|
previousfile = testSuite.metaTestSuite.filePath
|
|
end if
|
|
m.PrintSuiteStatistic(testSuite, statObj.testRunHasFailures)
|
|
end if
|
|
end for
|
|
? ""
|
|
m.PrintEnd()
|
|
? "Total = "; RBS_CMN_AsString(statObj.Total); " ; Passed = "; statObj.Correct; " ; Failed = "; statObj.Fail; " ; Ignored = "; statObj.Ignored
|
|
? " Time spent: "; statObj.Time; "ms"
|
|
? ""
|
|
? ""
|
|
if (statObj.ignored > 0)
|
|
? "IGNORED TESTS:"
|
|
for each ignoredItemName in statObj.IgnoredTestNames
|
|
print ignoredItemName
|
|
end for
|
|
end if
|
|
if (statObj.Total = statObj.Correct)
|
|
overrallResult = "Success"
|
|
else
|
|
overrallResult = "Fail"
|
|
end if
|
|
? "RESULT: "; overrallResult
|
|
end sub
|
|
sub RBS_LOGGER_PrintSuiteStatistic(statSuiteObj as object, hasFailures)
|
|
m.PrintSuiteStart(statSuiteObj.Name)
|
|
for each testCase in statSuiteObj.Tests
|
|
if (not hasFailures or ((not m.config.showOnlyFailures) or testCase.Result <> "Success"))
|
|
m.PrintTestStatistic(testCase)
|
|
end if
|
|
end for
|
|
? " |"
|
|
end sub
|
|
sub RBS_LOGGER_PrintTestStatistic(testCase as object)
|
|
metaTestCase = testCase.metaTestCase
|
|
if (LCase(testCase.Result) <> "success")
|
|
testChar = "-"
|
|
assertIndex = metaTestCase.testResult.failedAssertIndex
|
|
locationLine = StrI(RBS_TC_GetAssertLine(metaTestCase,assertIndex)).trim()
|
|
else
|
|
testChar = "|"
|
|
locationLine = StrI(metaTestCase.lineNumber).trim()
|
|
end if
|
|
locationText = testCase.filePath.trim() + "(" + locationLine + ")"
|
|
insetText = ""
|
|
if (metaTestcase.isParamTest <> true)
|
|
messageLine = RBS_LOGGER_FillText(" " + testChar + " |--" + metaTestCase.Name + " : ", ".", 80)
|
|
? messageLine ; testCase.Result ; " (" + stri(metaTestCase.time).trim() +"ms)"
|
|
else if ( metaTestcase.paramTestIndex = 0)
|
|
name = metaTestCase.Name
|
|
if (len(name) > 1 and right(name, 1) = "0")
|
|
name = left(name, len(name) - 1)
|
|
end if
|
|
? " " + testChar + " |--" + name+ " : "
|
|
end if
|
|
if (metaTestcase.isParamTest = true)
|
|
insetText = " "
|
|
messageLine = RBS_LOGGER_FillText(" " + testChar + insetText + " |--" + formatJson(metaTestCase.rawParams) + " : ", ".", 80)
|
|
? messageLine ; testCase.Result ; " (" + stri(metaTestCase.time).trim() +"ms)"
|
|
end if
|
|
if LCase(testCase.Result) <> "success"
|
|
? " | "; insettext ;" |--Location: "; locationText
|
|
if (metaTestcase.isParamTest = true)
|
|
? " | "; insettext ;" |--Param Line: "; StrI(metaTestCase.paramlineNumber).trim()
|
|
end if
|
|
? " | "; insettext ;" |--Error Message: "; testCase.Error.Message
|
|
end if
|
|
end sub
|
|
function RBS_LOGGER_FillText(text as string, fillChar = " ", numChars = 40) as string
|
|
if (len(text) >= numChars)
|
|
text = left(text, numChars - 5) + "..." + fillChar + fillChar
|
|
else
|
|
numToFill= numChars - len(text) -1
|
|
for i = 0 to numToFill
|
|
text += fillChar
|
|
end for
|
|
end if
|
|
return text
|
|
end function
|
|
sub RBS_LOGGER_PrintStart()
|
|
? ""
|
|
? "[START TEST REPORT]"
|
|
? ""
|
|
end sub
|
|
sub RBS_LOGGER_PrintEnd()
|
|
? ""
|
|
? "[END TEST REPORT]"
|
|
? ""
|
|
end sub
|
|
sub RBS_LOGGER_PrintSuiteSetUp(sName as string)
|
|
if m.verbosity = m.verbosityLevel.verbose
|
|
? "================================================================="
|
|
? "=== SetUp "; sName; " suite."
|
|
? "================================================================="
|
|
end if
|
|
end sub
|
|
sub RBS_LOGGER_PrintMetaSuiteStart(metaTestSuite)
|
|
? metaTestSuite.name; " (" ; metaTestSuite.filePath + "(1))"
|
|
end sub
|
|
sub RBS_LOGGER_PrintSuiteStart(sName as string)
|
|
? " |-" ; sName
|
|
end sub
|
|
sub RBS_LOGGER_PrintSuiteTearDown(sName as string)
|
|
if m.verbosity = m.verbosityLevel.verbose
|
|
? "================================================================="
|
|
? "=== TearDown "; sName; " suite."
|
|
? "================================================================="
|
|
end if
|
|
end sub
|
|
sub RBS_LOGGER_PrintTestSetUp(tName as string)
|
|
if m.verbosity = m.verbosityLevel.verbose
|
|
? "----------------------------------------------------------------"
|
|
? "--- SetUp "; tName; " test."
|
|
? "----------------------------------------------------------------"
|
|
end if
|
|
end sub
|
|
sub RBS_LOGGER_PrintTestTearDown(tName as string)
|
|
if m.verbosity = m.verbosityLevel.verbose
|
|
? "----------------------------------------------------------------"
|
|
? "--- TearDown "; tName; " test."
|
|
? "----------------------------------------------------------------"
|
|
end if
|
|
end sub
|
|
function UnitTestResult() as object
|
|
this = {}
|
|
this.messages = CreateObject("roArray", 0, true)
|
|
this.isFail = false
|
|
this.currentAssertIndex = 0
|
|
this.failedAssertIndex = 0
|
|
this.Reset = RBS_TRes_Reset
|
|
this.AddResult = RBS_TRes_AddResult
|
|
this.GetResult = RBS_TRes_GetResult
|
|
return this
|
|
end function
|
|
function RBS_TRes_Reset() as void
|
|
m.isFail = false
|
|
m.messages = CreateObject("roArray", 0, true)
|
|
end function
|
|
function RBS_TRes_AddResult(message as string) as string
|
|
if (message <> "")
|
|
m.messages.push(message)
|
|
if (not m.isFail)
|
|
m.failedAssertIndex = m.currentAssertIndex
|
|
end if
|
|
m.isFail = true
|
|
end if
|
|
m.currentAssertIndex++
|
|
return message
|
|
end function
|
|
function RBS_TRes_GetResult() as string
|
|
if (m.isFail)
|
|
msg = m.messages.peek()
|
|
if (msg <> invalid)
|
|
return msg
|
|
else
|
|
return "unknown test failure"
|
|
end if
|
|
else
|
|
return ""
|
|
end if
|
|
end function
|
|
function RBS_TR_TestRunner(args = {}) as object
|
|
this = {}
|
|
this.testScene = args.testScene
|
|
this.nodeContext = args.nodeContext
|
|
fs = CreateObject("roFileSystem")
|
|
defaultConfig = {
|
|
logLevel : 1,
|
|
testsDirectory: "pkg:/source/Tests",
|
|
testFilePrefix: "Test__",
|
|
failFast: false,
|
|
showOnlyFailures: false,
|
|
maxLinesWithoutSuiteDirective: 100
|
|
}
|
|
rawConfig = invalid
|
|
config = invalid
|
|
if (args.testConfigPath <> invalid and fs.Exists(args.testConfigPath))
|
|
? "Loading test config from " ; args.testConfigPath
|
|
rawConfig = ReadAsciiFile(args.testConfigPath)
|
|
else if (fs.Exists("pkg:/source/tests/testconfig.json"))
|
|
? "Loading test config from default location : pkg:/source/tests/testconfig.json"
|
|
rawConfig = ReadAsciiFile("pkg:/source/tests/testconfig.json")
|
|
else
|
|
? "None of the testConfig.json locations existed"
|
|
end if
|
|
if (rawConfig <> invalid)
|
|
config = ParseJson(rawConfig)
|
|
end if
|
|
if (config = invalid or not RBS_CMN_IsAssociativeArray(config) or RBS_CMN_IsNotEmptyString(config.rawtestsDirectory))
|
|
? "WARNING : specified config is invalid - using default"
|
|
config = defaultConfig
|
|
end if
|
|
if (args.showOnlyFailures <> invalid)
|
|
config.showOnlyFailures = args.showOnlyFailures = "true"
|
|
end if
|
|
if (args.failFast <> invalid)
|
|
config.failFast = args.failFast = "true"
|
|
end if
|
|
this.testUtilsDecoratorMethodName = args.testUtilsDecoratorMethodName
|
|
this.config = config
|
|
this.config.testsDirectory = config.testsDirectory
|
|
this.logger = Logger(this.config)
|
|
this.global = args.global
|
|
this.Run = RBS_TR_Run
|
|
return this
|
|
end function
|
|
sub RBS_TR_Run()
|
|
if type(RBSFM_getTestSuitesForProject) <> "Function"
|
|
? " ERROR! RBSFM_getTestSuitesForProject is not found! That looks like you didn't run the preprocessor as part of your test process. Please refer to the docs."
|
|
return
|
|
end if
|
|
totalStatObj = RBS_STATS_CreateTotalStatistic()
|
|
m.runtimeConfig = UnitTestRuntimeConfig()
|
|
m.runtimeConfig.global = m.global
|
|
totalStatObj.testRunHasFailures = false
|
|
for each metaTestSuite in m.runtimeConfig.suites
|
|
if (m.runtimeConfig.hasSoloTests = true)
|
|
if (metaTestSuite.hasSoloTests <> true)
|
|
if (m.config.logLevel = 2)
|
|
? "TestSuite " ; metaTestSuite.name ; " Is filtered because it has no solo tests"
|
|
end if
|
|
goto skipSuite
|
|
end if
|
|
else if (m.runtimeConfig.hasSoloSuites)
|
|
if (metaTestSuite.isSolo <> true)
|
|
if (m.config.logLevel = 2)
|
|
? "TestSuite " ; metaTestSuite.name ; " Is filtered due to solo flag"
|
|
end if
|
|
goto skipSuite
|
|
end if
|
|
end if
|
|
if (metaTestSuite.isIgnored = true)
|
|
if (m.config.logLevel = 2)
|
|
? "Ignoring TestSuite " ; metaTestSuite.name ; " Due to Ignore flag"
|
|
end if
|
|
totalstatobj.ignored ++
|
|
totalStatObj.IgnoredTestNames.push("|-" + metaTestSuite.name + " [WHOLE SUITE]")
|
|
goto skipSuite
|
|
end if
|
|
if (metaTestSuite.isNodeTest = true and metaTestSuite.nodeTestFileName <> "")
|
|
? " +++++RUNNING NODE TEST"
|
|
nodeType = metaTestSuite.nodeTestFileName
|
|
? " node type is " ; nodeType
|
|
node = m.testScene.CallFunc("Rooibos_CreateTestNode", nodeType)
|
|
if (type(node) = "roSGNode" and node.subType() = nodeType)
|
|
args = {
|
|
"metaTestSuite": metaTestSuite
|
|
"testUtilsDecoratorMethodName": m.testUtilsDecoratorMethodName
|
|
"config": m.config
|
|
"runtimeConfig": m.runtimeConfig
|
|
}
|
|
nodeStatResults = node.callFunc("Rooibos_RunNodeTests", args)
|
|
RBS_STATS_MergeTotalStatistic(totalStatObj, nodeStatResults)
|
|
m.testScene.RemoveChild(node)
|
|
else
|
|
? " ERROR!! - could not create node required to execute tests for " ; metaTestSuite.name
|
|
? " Node of type " ; nodeType ; " was not found/could not be instantiated"
|
|
end if
|
|
else
|
|
if (metaTestSuite.hasIgnoredTests)
|
|
totalStatObj.IgnoredTestNames.push("|-" + metaTestSuite.name)
|
|
end if
|
|
RBS_RT_RunItGroups(metaTestSuite, totalStatObj, m.testUtilsDecoratorMethodName, m.config, m.runtimeConfig, m.nodeContext)
|
|
end if
|
|
skipSuite:
|
|
end for
|
|
m.logger.PrintStatistic(totalStatObj)
|
|
RBS_TR_SendHomeKeypress()
|
|
end sub
|
|
sub RBS_RT_RunItGroups(metaTestSuite, totalStatObj, testUtilsDecoratorMethodName, config, runtimeConfig, nodeContext = invalid)
|
|
if (testUtilsDecoratorMethodName <> invalid)
|
|
testUtilsDecorator = RBS_CMN_GetFunctionBruteForce(testUtilsDecoratorMethodName)
|
|
if (not RBS_CMN_IsFunction(testUtilsDecorator))
|
|
? "[ERROR] Test utils decorator method `" ; testUtilsDecoratorMethodName ;"` was not in scope! for testSuite: " + metaTestSuite.name
|
|
end if
|
|
end if
|
|
for each itGroup in metaTestSuite.itGroups
|
|
testSuite = RBS_ItG_GetRunnableTestSuite(itGroup)
|
|
if (nodeContext <> invalid)
|
|
testSuite.node = nodeContext
|
|
testSuite.global = nodeContext.global
|
|
testSuite.top = nodeContext.top
|
|
end if
|
|
if (RBS_CMN_IsFunction(testUtilsDecorator))
|
|
testUtilsDecorator(testSuite)
|
|
end if
|
|
totalStatObj.Ignored += itGroup.ignoredTestCases.count()
|
|
if (itGroup.isIgnored = true)
|
|
if (config.logLevel = 2)
|
|
? "Ignoring itGroup " ; itGroup.name ; " Due to Ignore flag"
|
|
end if
|
|
totalStatObj.ignored += itGroup.testCases.count()
|
|
totalStatObj.IgnoredTestNames.push(" |-" + itGroup.name + " [WHOLE GROUP]")
|
|
goto skipItGroup
|
|
else
|
|
if (itGroup.ignoredTestCases.count() > 0)
|
|
totalStatObj.IgnoredTestNames.push(" |-" + itGroup.name)
|
|
totalStatObj.ignored += itGroup.ignoredTestCases.count()
|
|
for each testCase in itGroup.ignoredTestCases
|
|
if (testcase.isParamTest <> true)
|
|
totalStatObj.IgnoredTestNames.push(" | |--" + testCase.name)
|
|
else if (testcase.paramTestIndex = 0)
|
|
testCaseName = testCase.Name
|
|
if (len(testCaseName) > 1 and right(testCaseName, 1) = "0")
|
|
testCaseName = left(testCaseName, len(testCaseName) - 1)
|
|
end if
|
|
totalStatObj.IgnoredTestNames.push(" | |--" + testCaseName)
|
|
end if
|
|
end for
|
|
end if
|
|
end if
|
|
if (runtimeConfig.hasSoloTests)
|
|
if (itGroup.hasSoloTests <> true)
|
|
if (config.logLevel = 2)
|
|
? "Ignoring itGroup " ; itGroup.name ; " Because it has no solo tests"
|
|
end if
|
|
goto skipItGroup
|
|
end if
|
|
else if (runtimeConfig.hasSoloGroups)
|
|
if (itGroup.isSolo <> true)
|
|
goto skipItGroup
|
|
end if
|
|
end if
|
|
if (testSuite.testCases.Count() = 0)
|
|
if (config.logLevel = 2)
|
|
? "Ignoring TestSuite " ; itGroup.name ; " - NO TEST CASES"
|
|
end if
|
|
goto skipItGroup
|
|
end if
|
|
if RBS_CMN_IsFunction(testSuite.SetUp)
|
|
testSuite.SetUp()
|
|
end if
|
|
RBS_RT_RunTestCases(metaTestSuite, itGroup, testSuite, totalStatObj, config, runtimeConfig)
|
|
if RBS_CMN_IsFunction(testSuite.TearDown)
|
|
testSuite.TearDown()
|
|
end if
|
|
if (totalStatObj.testRunHasFailures = true and config.failFast = true)
|
|
exit for
|
|
end if
|
|
skipItGroup:
|
|
end for
|
|
end sub
|
|
sub RBS_RT_RunTestCases(metaTestSuite, itGroup, testSuite, totalStatObj, config, runtimeConfig)
|
|
suiteStatObj = RBS_STATS_CreateSuiteStatistic(itGroup.Name)
|
|
testSuite.global = runtimeConfig.global
|
|
for each testCase in testSuite.testCases
|
|
metaTestCase = itGroup.testCaseLookup[testCase.Name]
|
|
if (runtimeConfig.hasSoloTests and not metaTestCase.isSolo)
|
|
goto skipTestCase
|
|
end if
|
|
if RBS_CMN_IsFunction(testSuite.beforeEach)
|
|
testSuite.beforeEach()
|
|
end if
|
|
testTimer = CreateObject("roTimespan")
|
|
testCaseTimer = CreateObject("roTimespan")
|
|
testStatObj = RBS_STATS_CreateTestStatistic(testCase.Name)
|
|
testSuite.testCase = testCase.Func
|
|
testStatObj.filePath = metaTestSuite.filePath
|
|
testStatObj.metaTestCase = metaTestCase
|
|
testSuite.currentResult = UnitTestResult()
|
|
testStatObj.metaTestCase.testResult = testSuite.currentResult
|
|
if (metaTestCase.isParamsValid)
|
|
if (metaTestCase.isParamTest)
|
|
testCaseParams = []
|
|
for paramIndex = 0 to metaTestCase.rawParams.count()
|
|
paramValue = metaTestCase.rawParams[paramIndex]
|
|
if type(paramValue) = "roString" and len(paramValue) >= 8 and left(paramValue, 8) = "#RBSNode"
|
|
nodeType = "ContentNode"
|
|
paramDirectiveArgs = paramValue.split("|")
|
|
if paramDirectiveArgs.count() > 1
|
|
nodeType = paramDirectiveArgs[1]
|
|
end if
|
|
paramValue = createObject("roSGNode", nodeType)
|
|
end if
|
|
testCaseParams.push(paramValue)
|
|
end for
|
|
testCaseTimer.mark()
|
|
if (metaTestCase.expectedNumberOfParams = 1)
|
|
testSuite.testCase(testCaseParams[0])
|
|
else if (metaTestCase.expectedNumberOfParams = 2)
|
|
testSuite.testCase(testCaseParams[0], testCaseParams[1])
|
|
else if (metaTestCase.expectedNumberOfParams = 3)
|
|
testSuite.testCase(testCaseParams[0], testCaseParams[1], testCaseParams[2])
|
|
else if (metaTestCase.expectedNumberOfParams = 4)
|
|
testSuite.testCase(testCaseParams[0], testCaseParams[1], testCaseParams[2], testCaseParams[3])
|
|
else if (metaTestCase.expectedNumberOfParams = 5)
|
|
testSuite.testCase(testCaseParams[0], testCaseParams[1], testCaseParams[2], testCaseParams[3], testCaseParams[4])
|
|
else if (metaTestCase.expectedNumberOfParams = 6)
|
|
testSuite.testCase(testCaseParams[0], testCaseParams[1], testCaseParams[2], testCaseParams[3], testCaseParams[4], testCaseParams[5])
|
|
end if
|
|
metaTestCase.time = testCaseTimer.totalMilliseconds()
|
|
else
|
|
testCaseTimer.mark()
|
|
testSuite.testCase()
|
|
metaTestCase.time = testCaseTimer.totalMilliseconds()
|
|
end if
|
|
else
|
|
testSuite.Fail("Could not parse args for test ")
|
|
end if
|
|
if testSuite.isAutoAssertingMocks = true
|
|
testSuite.AssertMocks()
|
|
testSuite.CleanMocks()
|
|
testSuite.CleanStubs()
|
|
end if
|
|
runResult = testSuite.currentResult.GetResult()
|
|
if runResult <> ""
|
|
testStatObj.Result = "Fail"
|
|
testStatObj.Error.Code = 1
|
|
testStatObj.Error.Message = runResult
|
|
else
|
|
testStatObj.Result = "Success"
|
|
end if
|
|
testStatObj.Time = testTimer.TotalMilliseconds()
|
|
RBS_STATS_AppendTestStatistic(suiteStatObj, testStatObj)
|
|
if RBS_CMN_IsFunction(testSuite.afterEach)
|
|
testSuite.afterEach()
|
|
end if
|
|
if testStatObj.Result <> "Success"
|
|
totalStatObj.testRunHasFailures = true
|
|
end if
|
|
if testStatObj.Result = "Fail" and config.failFast = true
|
|
exit for
|
|
end if
|
|
skipTestCase:
|
|
end for
|
|
suiteStatObj.metaTestSuite = metaTestSuite
|
|
RBS_STATS_AppendSuiteStatistic(totalStatObj, suiteStatObj)
|
|
end sub
|
|
sub RBS_TR_SendHomeKeypress()
|
|
ut = CreateObject("roUrlTransfer")
|
|
ut.SetUrl("http://localhost:8060/keypress/Home")
|
|
ut.PostFromString("")
|
|
end sub
|
|
function Rooibos_RunNodeTests(args) as object
|
|
? " RUNNING NODE TESTS"
|
|
totalStatObj = RBS_STATS_CreateTotalStatistic()
|
|
RBS_RT_RunItGroups(args.metaTestSuite, totalStatObj, args.testUtilsDecoratorMethodName, args.config, args.runtimeConfig, m)
|
|
return totalStatObj
|
|
end function
|
|
function Rooibos_CreateTestNode(nodeType) as object
|
|
node = createObject("roSGNode", nodeType)
|
|
if (type(node) = "roSGNode" and node.subType() = nodeType)
|
|
m.top.AppendChild(node)
|
|
return node
|
|
else
|
|
? " Error creating test node of type " ; nodeType
|
|
return invalid
|
|
end if
|
|
end function |