BaseTestSuite.brs

  1. ' /**
  2. ' * @module BaseTestSuite
  3. ' * @description All brs files that include `'@TestSuite` annotations automatically extend the BaseTestSuite.
  4. ' * The base test suite contains all of the assertions, and utility methods required to writey our tests, as well as being responsible for tracking the state of the tests and groups.
  5. ' */
  6. function __Rooibos_BaseTestSuite_builder()
  7. instance = {}
  8. instance.new = sub()
  9. m.name = "BaseTestSuite"
  10. m.invalidValue = "#ROIBOS#INVALID_VALUE"
  11. m.ignoreValue = "#ROIBOS#IGNORE_VALUE"
  12. m.anyStringMatcher = {
  13. "matcher": Rooibos_Matcher_anyString
  14. }
  15. m.anyBoolMatcher = {
  16. "matcher": Rooibos_Matcher_anyBool
  17. }
  18. m.anyNumberMatcher = {
  19. "matcher": Rooibos_Matcher_anyNumber
  20. }
  21. m.anyAAMatcher = {
  22. "matcher": Rooibos_Matcher_anyAA
  23. }
  24. m.anyArrayMatcher = {
  25. "matcher": Rooibos_Matcher_anyArray
  26. }
  27. m.anyNodeMatcher = {
  28. "matcher": Rooibos_Matcher_anyNode
  29. }
  30. m.allowNonExistingMethodsOnMocks = true
  31. m.isAutoAssertingMocks = true
  32. m.testCases = []
  33. end sub
  34. ' special value used in mock arguments
  35. ' special value used in mock arguments
  36. 'built in any matchers
  37. 'Test Cases methods
  38. ' /**
  39. ' * @memberof module:BaseTestSuite
  40. ' * @name addTest
  41. ' * @function
  42. ' * @instance
  43. ' * @description Add a test to a suite's test cases array. Used internally.
  44. ' * @param {Dynamic} name - A test name.
  45. ' * @param {Dynamic} func - A test function name.
  46. ' */
  47. instance.addTest = function(name, func, funcName, setup = invalid, teardown = invalid)
  48. m.testCases.Push(m.createTest(name, func, setup, teardown))
  49. end function
  50. ' /**
  51. ' * @memberof module:BaseTestSuite
  52. ' * @name createTest
  53. ' * @function
  54. ' * @instance
  55. ' * @description Create a test object. Used internally
  56. ' * @param {Dynamic} name - A test name.
  57. ' * @param {Dynamic} func - A test function name.
  58. ' */
  59. instance.createTest = function(name, func, funcName, setup = invalid, teardown = invalid) as object
  60. if (func = invalid) then
  61. print " ASKED TO CREATE TEST WITH INVALID FUNCITON POINTER FOR FUNCTION " ; funcName
  62. end if
  63. return {
  64. name: name,
  65. func: func,
  66. funcName: funcName,
  67. setUp: setup,
  68. tearDown: teardown
  69. }
  70. end function
  71. ' /**
  72. ' * @memberof module:BaseTestSuite
  73. ' * @name fail
  74. ' * @function
  75. ' * @instance
  76. ' * @description Fail immediately, with the given message
  77. ' * @param {Dynamic} [msg=""] - message to display in the test report
  78. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  79. ' */
  80. instance.fail = function(msg = "Error") as dynamic
  81. if m.currentResult.isFail then
  82. return m.getLegacyCompatibleReturnValue(false)
  83. end if
  84. m.currentResult.addResult(msg)
  85. return m.getLegacyCompatibleReturnValue(false)
  86. end function
  87. '*************************************************************
  88. '** GetLegacyCompatibleReturnValue
  89. '** will return the correct type of return value for a new-style/legacy test
  90. '*************************************************************
  91. instance.getLegacyCompatibleReturnValue = function(value) as object
  92. if (value = true) then
  93. if (m.isLegacy = true) then
  94. return ""
  95. else
  96. return true
  97. end if
  98. else
  99. if (m.isLegacy = true) then
  100. return "ERROR"
  101. else
  102. return false
  103. end if
  104. end if
  105. end function
  106. ' /**
  107. ' * @memberof module:BaseTestSuite
  108. ' * @name assertFalse
  109. ' * @function
  110. ' * @instance
  111. ' * @description Fail the test if the expression is true.
  112. ' * @param {Dynamic} expr - An expression to evaluate.
  113. ' * @param {Dynamic} [msg=""] - alternate error message
  114. ' Default value: "Expression evaluates to true"' * @returns {boolean} - true if the assert was satisfied, false otherwise
  115. ' */
  116. instance.assertFalse = function(expr, msg = "Expression evaluates to true") as dynamic
  117. if m.currentResult.isFail then
  118. return m.getLegacyCompatibleReturnValue(false)
  119. end if
  120. if not Rooibos_Common_isBoolean(expr) or expr then
  121. return m.fail(msg)
  122. end if
  123. m.currentResult.addResult("")
  124. return m.getLegacyCompatibleReturnValue(true)
  125. end function
  126. ' /**
  127. ' * @memberof module:BaseTestSuite
  128. ' * @name assertTrue
  129. ' * @function
  130. ' * @instance
  131. ' * @description Fail the test unless the expression is true.
  132. ' * @param {Dynamic} expr - An expression to evaluate.
  133. ' * @param {Dynamic} [msg=""] - alternate error message
  134. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  135. ' */
  136. instance.assertTrue = function(expr, msg = "Expression evaluates to false")
  137. if m.currentResult.isFail then
  138. return m.getLegacyCompatibleReturnValue(false)
  139. end if
  140. if not Rooibos_Common_isBoolean(expr) or not expr then
  141. m.currentResult.addResult(msg)
  142. return m.getLegacyCompatibleReturnValue(false)
  143. end if
  144. m.currentResult.addResult("")
  145. return m.getLegacyCompatibleReturnValue(true)
  146. end function
  147. ' /**
  148. ' * @memberof module:BaseTestSuite
  149. ' * @name assertEqual
  150. ' * @function
  151. ' * @instance
  152. ' * @description Fail if the two objects are unequal as determined by the '<>' operator.
  153. ' * @param {Dynamic} first - first object to compare
  154. ' * @param {Dynamic} second - second object to compare
  155. ' * @param {Dynamic} [msg=""] - alternate error message
  156. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  157. ' */
  158. instance.assertEqual = function(first, second, msg = "") as dynamic
  159. if m.currentResult.isFail then
  160. return m.getLegacyCompatibleReturnValue(false)
  161. end if
  162. if not Rooibos_Common_eqValues(first, second) then
  163. if msg = "" then
  164. first_as_string = Rooibos_Common_asString(first)
  165. second_as_string = Rooibos_Common_asString(second)
  166. msg = first_as_string + " != " + second_as_string
  167. end if
  168. m.currentResult.addResult(msg)
  169. return m.getLegacyCompatibleReturnValue(false)
  170. end if
  171. m.currentResult.addResult("")
  172. return m.getLegacyCompatibleReturnValue(true)
  173. end function
  174. ' /**
  175. ' * @memberof module:BaseTestSuite
  176. ' * @name assertLike
  177. ' * @function
  178. ' * @instance
  179. ' * @description does a fuzzy comparison
  180. ' * @param {Dynamic} first - first object to compare
  181. ' * @param {Dynamic} second - second object to compare
  182. ' * @param {Dynamic} [msg=""] - alternate error message
  183. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  184. ' */
  185. instance.assertLike = function(first, second, msg = "") as dynamic
  186. if m.currentResult.isFail then
  187. return m.getLegacyCompatibleReturnValue(false)
  188. end if
  189. if first <> second then
  190. if msg = "" then
  191. first_as_string = Rooibos_Common_asString(first)
  192. second_as_string = Rooibos_Common_asString(second)
  193. msg = first_as_string + " != " + second_as_string
  194. end if
  195. m.currentResult.addResult(msg)
  196. return m.getLegacyCompatibleReturnValue(false)
  197. end if
  198. m.currentResult.addResult("")
  199. return m.getLegacyCompatibleReturnValue(true)
  200. end function
  201. ' /**
  202. ' * @memberof module:BaseTestSuite
  203. ' * @name assertNotEqual
  204. ' * @function
  205. ' * @instance
  206. ' * @description Fail if the two objects are equal as determined by the '=' operator.
  207. ' * @param {Dynamic} first - first object to compare
  208. ' * @param {Dynamic} second - second object to compare
  209. ' * @param {Dynamic} [msg=""] - alternate error message
  210. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  211. ' */
  212. instance.assertNotEqual = function(first, second, msg = "") as dynamic
  213. if m.currentResult.isFail then
  214. return m.getLegacyCompatibleReturnValue(false)
  215. end if
  216. if Rooibos_Common_eqValues(first, second) then
  217. if msg = "" then
  218. first_as_string = Rooibos_Common_asString(first)
  219. second_as_string = Rooibos_Common_asString(second)
  220. msg = first_as_string + " == " + second_as_string
  221. end if
  222. m.currentResult.addResult(msg)
  223. return m.getLegacyCompatibleReturnValue(false)
  224. end if
  225. m.currentResult.addResult("")
  226. return m.getLegacyCompatibleReturnValue(true)
  227. end function
  228. ' /**
  229. ' * @memberof module:BaseTestSuite
  230. ' * @name assertInvalid
  231. ' * @function
  232. ' * @instance
  233. ' * @description Fail if the value is not invalid.
  234. ' * @param {Dynamic} value - value to check - value to check for
  235. ' * @param {Dynamic} [msg=""] - alternate error message
  236. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  237. ' */
  238. instance.assertInvalid = function(value, msg = "") as dynamic
  239. if m.currentResult.isFail then
  240. return m.getLegacyCompatibleReturnValue(false)
  241. end if
  242. if value <> invalid then
  243. if msg = "" then
  244. expr_as_string = Rooibos_Common_asString(value)
  245. msg = expr_as_string + " <> Invalid"
  246. end if
  247. m.currentResult.addResult(msg)
  248. return m.getLegacyCompatibleReturnValue(false)
  249. end if
  250. m.currentResult.addResult("")
  251. return m.getLegacyCompatibleReturnValue(true)
  252. end function
  253. ' /**
  254. ' * @memberof module:BaseTestSuite
  255. ' * @name assertNotInvalid
  256. ' * @function
  257. ' * @instance
  258. ' * @description Fail if the value is invalid.
  259. ' * @param {Dynamic} value - value to check - value to check for
  260. ' * @param {Dynamic} [msg=""] - alternate error message
  261. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  262. ' */
  263. instance.assertNotInvalid = function(value, msg = "") as dynamic
  264. if m.currentResult.isFail then
  265. return m.getLegacyCompatibleReturnValue(false)
  266. end if
  267. if value = invalid then
  268. if msg = "" then
  269. expr_as_string = Rooibos_Common_asString(value)
  270. msg = expr_as_string + " = Invalid"
  271. end if
  272. m.currentResult.addResult(msg)
  273. return m.getLegacyCompatibleReturnValue(false)
  274. end if
  275. m.currentResult.addResult("")
  276. return m.getLegacyCompatibleReturnValue(true)
  277. end function
  278. ' /**
  279. ' * @memberof module:BaseTestSuite
  280. ' * @name assertAAHasKey
  281. ' * @function
  282. ' * @instance
  283. ' * @description Fail if the array doesn't have the key.
  284. ' * @param {Dynamic} array - target array
  285. ' * @param {Dynamic} key - key name
  286. ' * @param {Dynamic} [msg=""] - alternate error message
  287. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  288. ' */
  289. instance.assertAAHasKey = function(array, key, msg = "") as dynamic
  290. if m.currentResult.isFail then
  291. return m.getLegacyCompatibleReturnValue(false)
  292. end if
  293. if Rooibos_Common_isAssociativeArray(array) then
  294. if not array.DoesExist(key) then
  295. if msg = "" then
  296. msg = "Array doesn't have the '" + key + "' key."
  297. end if
  298. m.currentResult.addResult(msg)
  299. return m.getLegacyCompatibleReturnValue(false)
  300. end if
  301. else
  302. msg = "Input value is not an Associative Array."
  303. m.currentResult.addResult(msg)
  304. return m.getLegacyCompatibleReturnValue(false)
  305. end if
  306. m.currentResult.addResult("")
  307. return m.getLegacyCompatibleReturnValue(true)
  308. end function
  309. ' /**
  310. ' * @memberof module:BaseTestSuite
  311. ' * @name assertAANotHasKey
  312. ' * @function
  313. ' * @instance
  314. ' * @description Fail if the array has the key.
  315. ' * @param {Dynamic} array - target array
  316. ' * @param {Dynamic} key - key name
  317. ' * @param {Dynamic} [msg=""] - alternate error message
  318. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  319. ' */
  320. instance.assertAANotHasKey = function(array, key, msg = "") as dynamic
  321. if m.currentResult.isFail then
  322. return m.getLegacyCompatibleReturnValue(false)
  323. end if
  324. if Rooibos_Common_isAssociativeArray(array) then
  325. if array.DoesExist(key) then
  326. if msg = "" then
  327. msg = "Array has the '" + key + "' key."
  328. end if
  329. m.currentResult.addResult(msg)
  330. return m.getLegacyCompatibleReturnValue(false)
  331. end if
  332. else
  333. msg = "Input value is not an Associative Array."
  334. m.currentResult.addResult(msg)
  335. return m.getLegacyCompatibleReturnValue(false)
  336. end if
  337. m.currentResult.addResult("")
  338. return m.getLegacyCompatibleReturnValue(true)
  339. end function
  340. ' /**
  341. ' * @memberof module:BaseTestSuite
  342. ' * @name assertAAHasKeys
  343. ' * @function
  344. ' * @instance
  345. ' * @description Fail if the array doesn't have the keys list.
  346. ' * @param {Dynamic} array - A target associative array.
  347. ' * @param {Dynamic} keys - Array of key names.
  348. ' * @param {Dynamic} [msg=""] - alternate error message
  349. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  350. ' */
  351. instance.assertAAHasKeys = function(array, keys, msg = "") as dynamic
  352. if m.currentResult.isFail then
  353. return m.getLegacyCompatibleReturnValue(false)
  354. end if
  355. if Rooibos_Common_isAssociativeArray(array) and Rooibos_Common_isArray(keys) then
  356. for each key in keys
  357. if not array.DoesExist(key) then
  358. if msg = "" then
  359. msg = "Array doesn't have the '" + key + "' key."
  360. end if
  361. m.currentResult.addResult(msg)
  362. return m.getLegacyCompatibleReturnValue(false)
  363. end if
  364. end for
  365. else
  366. msg = "Input value is not an Associative Array."
  367. m.currentResult.addResult(msg)
  368. return m.getLegacyCompatibleReturnValue(false)
  369. end if
  370. m.currentResult.addResult("")
  371. return m.getLegacyCompatibleReturnValue(true)
  372. end function
  373. ' /**
  374. ' * @memberof module:BaseTestSuite
  375. ' * @name assertAANotHasKeys
  376. ' * @function
  377. ' * @instance
  378. ' * @description Fail if the array has the keys list.
  379. ' * @param {Dynamic} array - A target associative array.
  380. ' * @param {Dynamic} keys - Array of key names.
  381. ' * @param {Dynamic} [msg=""] - alternate error message
  382. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  383. ' */
  384. instance.assertAANotHasKeys = function(array, keys, msg = "") as dynamic
  385. if m.currentResult.isFail then
  386. return m.getLegacyCompatibleReturnValue(false)
  387. end if
  388. if Rooibos_Common_isAssociativeArray(array) and Rooibos_Common_isArray(keys) then
  389. for each key in keys
  390. if array.DoesExist(key) then
  391. if msg = "" then
  392. msg = "Array has the '" + key + "' key."
  393. end if
  394. m.currentResult.addResult(msg)
  395. return m.getLegacyCompatibleReturnValue(false)
  396. end if
  397. end for
  398. else
  399. msg = "Input value is not an Associative Array."
  400. m.currentResult.addResult(msg)
  401. return m.getLegacyCompatibleReturnValue(false)
  402. end if
  403. m.currentResult.addResult("")
  404. return m.getLegacyCompatibleReturnValue(true)
  405. end function
  406. ' /**
  407. ' * @memberof module:BaseTestSuite
  408. ' * @name assertArrayContains
  409. ' * @function
  410. ' * @instance
  411. ' * @description Fail if the array doesn't have the item.
  412. ' * @param {Dynamic} array - target array
  413. ' * @param {Dynamic} value - value to check - value to check for
  414. ' * @param {Dynamic} key - key name in associative array
  415. ' * @param {Dynamic} [msg=""] - alternate error message
  416. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  417. ' */
  418. instance.assertArrayContains = function(array, value, key = invalid, msg = "") as dynamic
  419. if m.currentResult.isFail then
  420. return m.getLegacyCompatibleReturnValue(false)
  421. end if
  422. if Rooibos_Common_isAssociativeArray(array) or Rooibos_Common_isArray(array) then
  423. if not Rooibos_Common_arrayContains(array, value, key) then
  424. msg = "Array doesn't have the '" + Rooibos_Common_asString(value) + "' value."
  425. m.currentResult.addResult(msg)
  426. return m.getLegacyCompatibleReturnValue(false)
  427. end if
  428. else
  429. msg = "Input value is not an Array."
  430. m.currentResult.addResult(msg)
  431. return m.getLegacyCompatibleReturnValue(false)
  432. end if
  433. m.currentResult.addResult("")
  434. return m.getLegacyCompatibleReturnValue(true)
  435. end function
  436. ' /**
  437. ' * @memberof module:BaseTestSuite
  438. ' * @name assertArrayContainsAAs
  439. ' * @function
  440. ' * @instance
  441. ' * @description Fail if the array does not contain all of the aa's in the values array.
  442. ' * @param {Dynamic} array - target array
  443. ' * @param {Dynamic} values - array of aas to look for in target array
  444. ' * @param {Dynamic} [msg=""] - alternate error message
  445. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  446. ' */
  447. instance.assertArrayContainsAAs = function(array, values, msg = "") as dynamic
  448. if m.currentResult.isFail then
  449. return m.getLegacyCompatibleReturnValue(false)
  450. end if
  451. if not Rooibos_Common_isArray(values) then
  452. msg = "values to search for are not an Array."
  453. m.currentResult.addResult(msg)
  454. return m.getLegacyCompatibleReturnValue(false)
  455. end if
  456. if Rooibos_Common_isArray(array) then
  457. for each value in values
  458. isMatched = false
  459. if not Rooibos_Common_isAssociativeArray(value) then
  460. msg = "Value to search for was not associativeArray " + Rooibos_Common_asString(value)
  461. m.currentResult.addResult(msg)
  462. return m.getLegacyCompatibleReturnValue(false)
  463. end if
  464. for each item in array
  465. if (Rooibos_Common_IsAssociativeArray(item)) then
  466. isValueMatched = true
  467. for each key in value
  468. fieldValue = value[key]
  469. itemValue = item[key]
  470. if (not Rooibos_Common_eqValues(fieldValue, itemValue)) then
  471. isValueMatched = false
  472. exit for
  473. end if
  474. end for
  475. if (isValueMatched) then
  476. isMatched = true
  477. exit for
  478. end if
  479. end if
  480. end for ' items in array
  481. if not isMatched then
  482. msg = "array missing value: " + Rooibos_Common_asString(value)
  483. m.currentResult.addResult(msg)
  484. return m.getLegacyCompatibleReturnValue(false)
  485. end if
  486. end for 'values to match
  487. else
  488. msg = "Input value is not an Array."
  489. m.currentResult.addResult(msg)
  490. return m.getLegacyCompatibleReturnValue(false)
  491. end if
  492. m.currentResult.addResult("")
  493. return m.getLegacyCompatibleReturnValue(true)
  494. end function
  495. ' /**
  496. ' * @memberof module:BaseTestSuite
  497. ' * @name assertArrayNotContains
  498. ' * @function
  499. ' * @instance
  500. ' * @description Fail if the array has the item.
  501. ' * @param {Dynamic} array - target array
  502. ' * @param {Dynamic} array - target array
  503. ' * @param {Dynamic} value - value to check - Value to check for
  504. ' * @param {Dynamic} key - A key name for associative array.
  505. ' * @param {Dynamic} [msg=""] - alternate error message
  506. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  507. ' */
  508. instance.assertArrayNotContains = function(array, value, key = invalid, msg = "") as dynamic
  509. if m.currentResult.isFail then
  510. return m.getLegacyCompatibleReturnValue(false)
  511. end if
  512. if Rooibos_Common_isAssociativeArray(array) or Rooibos_Common_isArray(array) then
  513. if Rooibos_Common_arrayContains(array, value, key) then
  514. msg = "Array has the '" + Rooibos_Common_asString(value) + "' value."
  515. m.currentResult.addResult(msg)
  516. return m.getLegacyCompatibleReturnValue(false)
  517. end if
  518. else
  519. msg = "Input value is not an Array."
  520. m.currentResult.addResult(msg)
  521. return m.getLegacyCompatibleReturnValue(false)
  522. end if
  523. m.currentResult.addResult("")
  524. return m.getLegacyCompatibleReturnValue(true)
  525. end function
  526. ' /**
  527. ' * @memberof module:BaseTestSuite
  528. ' * @name assertArrayContainsSubset
  529. ' * @function
  530. ' * @instance
  531. ' * @description Fail if the array doesn't have the item subset.
  532. ' * @param {Dynamic} array - target array
  533. ' * @param {Dynamic} subset - items to check presnece of
  534. ' * @param {Dynamic} [msg=""] - alternate error message
  535. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  536. ' */
  537. instance.assertArrayContainsSubset = function(array, subset, msg = "") as dynamic
  538. if m.currentResult.isFail then
  539. return m.getLegacyCompatibleReturnValue(false)
  540. end if
  541. if (Rooibos_Common_isAssociativeArray(array) and Rooibos_Common_isAssociativeArray(subset)) or (Rooibos_Common_isArray(array) and Rooibos_Common_isArray(subset)) then
  542. isAA = Rooibos_Common_isAssociativeArray(subset)
  543. for each item in subset
  544. key = invalid
  545. value = item
  546. if isAA then
  547. key = item
  548. value = subset[key]
  549. end if
  550. if not Rooibos_Common_arrayContains(array, value, key) then
  551. msg = "Array doesn't have the '" + Rooibos_Common_asString(value) + "' value."
  552. m.currentResult.addResult(msg)
  553. return m.getLegacyCompatibleReturnValue(false)
  554. end if
  555. end for
  556. else
  557. msg = "Input value is not an Array."
  558. m.currentResult.addResult(msg)
  559. return m.getLegacyCompatibleReturnValue(false)
  560. end if
  561. m.currentResult.addResult("")
  562. return m.getLegacyCompatibleReturnValue(true)
  563. end function
  564. ' /**
  565. ' * @memberof module:BaseTestSuite
  566. ' * @name assertArrayNotContainsSubset
  567. ' * @function
  568. ' * @instance
  569. ' * @description Fail if the array have the item from subset.
  570. ' * @param {Dynamic} array - target array
  571. ' * @param {Dynamic} subset - items to check presnece of
  572. ' * @param {Dynamic} [msg=""] - alternate error message
  573. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  574. ' */
  575. instance.assertArrayNotContainsSubset = function(array, subset, msg = "") as dynamic
  576. if m.currentResult.isFail then
  577. return m.getLegacyCompatibleReturnValue(false)
  578. end if
  579. if (Rooibos_Common_isAssociativeArray(array) and Rooibos_Common_isAssociativeArray(subset)) or (Rooibos_Common_isArray(array) and Rooibos_Common_isArray(subset)) then
  580. isAA = Rooibos_Common_isAssociativeArray(subset)
  581. for each item in subset
  582. key = invalid
  583. value = item
  584. if isAA then
  585. key = item
  586. value = item[key]
  587. end if
  588. if Rooibos_Common_arrayContains(array, value, key) then
  589. msg = "Array has the '" + Rooibos_Common_asString(value) + "' value."
  590. m.currentResult.addResult(msg)
  591. return m.getLegacyCompatibleReturnValue(false)
  592. end if
  593. end for
  594. else
  595. msg = "Input value is not an Array."
  596. m.currentResult.addResult(msg)
  597. return m.getLegacyCompatibleReturnValue(false)
  598. end if
  599. m.currentResult.addResult("")
  600. return m.getLegacyCompatibleReturnValue(true)
  601. end function
  602. ' /**
  603. ' * @memberof module:BaseTestSuite
  604. ' * @name assertArrayCount
  605. ' * @function
  606. ' * @instance
  607. ' * @description Fail if the array items count <> expected count
  608. ' * @param {Dynamic} array - target array
  609. ' * @param {Dynamic} count - An expected array items count
  610. ' * @param {Dynamic} [msg=""] - alternate error message
  611. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  612. ' */
  613. instance.assertArrayCount = function(array, count, msg = "") as dynamic
  614. if m.currentResult.isFail then
  615. return m.getLegacyCompatibleReturnValue(false)
  616. end if
  617. if Rooibos_Common_isAssociativeArray(array) or Rooibos_Common_isArray(array) then
  618. if array.Count() <> count then
  619. msg = "Array items count " + Rooibos_Common_asString(array.Count()) + " <> " + Rooibos_Common_asString(count) + "."
  620. m.currentResult.addResult(msg)
  621. return m.getLegacyCompatibleReturnValue(false)
  622. end if
  623. else
  624. msg = "Input value is not an Array."
  625. m.currentResult.addResult(msg)
  626. return m.getLegacyCompatibleReturnValue(false)
  627. end if
  628. m.currentResult.addResult("")
  629. return m.getLegacyCompatibleReturnValue(true)
  630. end function
  631. ' /**
  632. ' * @memberof module:BaseTestSuite
  633. ' * @name assertArrayNotCount
  634. ' * @function
  635. ' * @instance
  636. ' * @description Fail if the array items count = expected count.
  637. ' * @param {Dynamic} array - target array
  638. ' * @param {Dynamic} count - An expected array items count.
  639. ' * @param {Dynamic} [msg=""] - alternate error message
  640. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  641. ' */
  642. instance.assertArrayNotCount = function(array, count, msg = "") as dynamic
  643. if m.currentResult.isFail then
  644. return m.getLegacyCompatibleReturnValue(false)
  645. end if
  646. if Rooibos_Common_isAssociativeArray(array) or Rooibos_Common_isArray(array) then
  647. if array.Count() = count then
  648. msg = "Array items count = " + Rooibos_Common_asString(count) + "."
  649. m.currentResult.addResult(msg)
  650. return m.getLegacyCompatibleReturnValue(false)
  651. end if
  652. else
  653. msg = "Input value is not an Array."
  654. m.currentResult.addResult(msg)
  655. return m.getLegacyCompatibleReturnValue(false)
  656. end if
  657. m.currentResult.addResult("")
  658. return m.getLegacyCompatibleReturnValue(true)
  659. end function
  660. ' /**
  661. ' * @memberof module:BaseTestSuite
  662. ' * @name assertEmpty
  663. ' * @function
  664. ' * @instance
  665. ' * @description Fail if the item is not empty array or string.
  666. ' * @param {Dynamic} item - item to check
  667. ' * @param {Dynamic} [msg=""] - alternate error message
  668. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  669. ' */
  670. instance.assertEmpty = function(item, msg = "") as dynamic
  671. if m.currentResult.isFail then
  672. return m.getLegacyCompatibleReturnValue(false)
  673. end if
  674. if Rooibos_Common_isAssociativeArray(item) or Rooibos_Common_isArray(item) then
  675. if item.count() > 0 then
  676. msg = "Array is not empty."
  677. m.currentResult.addResult(msg)
  678. return m.getLegacyCompatibleReturnValue(false)
  679. end if
  680. else if (Rooibos_Common_isString(item)) then
  681. if (Rooibos_Common_asString(item) <> "") then
  682. msg = "Input value is not empty."
  683. m.currentResult.addResult(msg)
  684. return m.getLegacyCompatibleReturnValue(false)
  685. end if
  686. else
  687. msg = "AssertEmpty: Input value was not an array or a string"
  688. m.currentResult.addResult(msg)
  689. return m.getLegacyCompatibleReturnValue(false)
  690. end if
  691. m.currentResult.addResult("")
  692. return m.getLegacyCompatibleReturnValue(true)
  693. end function
  694. ' /**
  695. ' * @memberof module:BaseTestSuite
  696. ' * @name assertNotEmpty
  697. ' * @function
  698. ' * @instance
  699. ' * @description Fail if the item is empty array or string.
  700. ' * @param {Dynamic} item - item to check
  701. ' * @param {Dynamic} [msg=""] - alternate error message
  702. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  703. ' */
  704. instance.assertNotEmpty = function(item, msg = "") as dynamic
  705. if m.currentResult.isFail then
  706. return m.getLegacyCompatibleReturnValue(false)
  707. end if
  708. if Rooibos_Common_isAssociativeArray(item) or Rooibos_Common_isArray(item) then
  709. if item.count() = 0 then
  710. msg = "Array is empty."
  711. m.currentResult.addResult(msg)
  712. return m.getLegacyCompatibleReturnValue(false)
  713. end if
  714. else if Rooibos_Common_isString(item) then
  715. if (item = "") then
  716. msg = "Input value is empty."
  717. m.currentResult.addResult(msg)
  718. return m.getLegacyCompatibleReturnValue(false)
  719. end if
  720. else
  721. msg = "Input value is not a string or array."
  722. m.currentResult.addResult(msg)
  723. return m.getLegacyCompatibleReturnValue(false)
  724. end if
  725. m.currentResult.addResult("")
  726. return m.getLegacyCompatibleReturnValue(true)
  727. end function
  728. ' /**
  729. ' * @memberof module:BaseTestSuite
  730. ' * @name assertArrayContainsOnlyValuesOfType
  731. ' * @function
  732. ' * @instance
  733. ' * @description Fail if the array doesn't contains items of specific type only.
  734. ' * @param {Dynamic} array - target array
  735. ' * @param {Dynamic} typeStr - type name - must be String, Array, Boolean, or AssociativeArray
  736. ' * @param {Dynamic} [msg=""] - alternate error message
  737. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  738. ' */
  739. instance.assertArrayContainsOnlyValuesOfType = function(array, typeStr, msg = "") as dynamic
  740. if m.currentResult.isFail then
  741. return m.getLegacyCompatibleReturnValue(false)
  742. end if
  743. if typeStr <> "String" and typeStr <> "Integer" and typeStr <> "Boolean" and typeStr <> "Array" and typeStr <> "AssociativeArray" then
  744. msg = "Type must be Boolean, String, Array, Integer, or AssociativeArray"
  745. m.currentResult.addResult(msg)
  746. return m.getLegacyCompatibleReturnValue(false)
  747. end if
  748. if Rooibos_Common_isAssociativeArray(array) or Rooibos_Common_isArray(array) then
  749. methodName = "Rooibos_Common_Is" + typeStr
  750. typeCheckFunction = m.getIsTypeFunction(methodName)
  751. if (typeCheckFunction <> invalid) then
  752. for each item in array
  753. if not typeCheckFunction(item) then
  754. msg = Rooibos_Common_asString(item) + "is not a '" + typeStr + "' type."
  755. m.currentResult.addResult(msg)
  756. return m.getLegacyCompatibleReturnValue(false)
  757. end if
  758. end for
  759. else
  760. msg = "could not find comparator for type '" + typeStr + "' type."
  761. m.currentResult.addResult(msg)
  762. return m.getLegacyCompatibleReturnValue(false)
  763. end if
  764. else
  765. msg = "Input value is not an Array."
  766. m.currentResult.addResult(msg)
  767. return m.getLegacyCompatibleReturnValue(false)
  768. end if
  769. m.currentResult.addResult("")
  770. return m.getLegacyCompatibleReturnValue(true)
  771. end function
  772. instance.getIsTypeFunction = function(name)
  773. if name = "Rooibos_Common_IsFunction" then
  774. return Rooibos_Common_isFunction
  775. else if name = "Rooibos_Common_IsXmlElement" then
  776. return Rooibos_Common_isXmlElement
  777. else if name = "Rooibos_Common_IsInteger" then
  778. return Rooibos_Common_isInteger
  779. else if name = "Rooibos_Common_IsBoolean" then
  780. return Rooibos_Common_isBoolean
  781. else if name = "Rooibos_Common_IsFloat" then
  782. return Rooibos_Common_isFloat
  783. else if name = "Rooibos_Common_IsDouble" then
  784. return Rooibos_Common_isDouble
  785. else if name = "Rooibos_Common_IsLongInteger" then
  786. return Rooibos_Common_isLongInteger
  787. else if name = "Rooibos_Common_IsNumber" then
  788. return Rooibos_Common_isNumber
  789. else if name = "Rooibos_Common_IsList" then
  790. return Rooibos_Common_isList
  791. else if name = "Rooibos_Common_IsArray" then
  792. return Rooibos_Common_isArray
  793. else if name = "Rooibos_Common_IsAssociativeArray" then
  794. return Rooibos_Common_isAssociativeArray
  795. else if name = "Rooibos_Common_IsSGNode" then
  796. return Rooibos_Common_isSGNode
  797. else if name = "Rooibos_Common_IsString" then
  798. return Rooibos_Common_isString
  799. else if name = "Rooibos_Common_IsDateTime" then
  800. return Rooibos_Common_isDateTime
  801. else if name = "Rooibos_Common_IsUndefined" then
  802. return Rooibos_Common_isUndefined
  803. else
  804. return invalid
  805. end if
  806. end function
  807. ' /**
  808. ' * @memberof module:BaseTestSuite
  809. ' * @name assertType
  810. ' * @function
  811. ' * @instance
  812. ' * @description Asserts that the value is a node of designated type
  813. ' * @param {Dynamic} value - value to check - target node
  814. ' * @param {Dynamic} typeStr - type name
  815. ' * @param {Dynamic} [msg=""] - alternate error message
  816. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  817. ' */
  818. instance.assertType = function(value, typeStr, msg = "") as dynamic
  819. if m.currentResult.isFail then
  820. return m.getLegacyCompatibleReturnValue(false)
  821. end if
  822. if type(value) <> typeStr then
  823. if msg = "" then
  824. expr_as_string = Rooibos_Common_asString(value)
  825. msg = expr_as_string + " was not expected type " + typeStr
  826. end if
  827. m.currentResult.addResult(msg)
  828. return m.getLegacyCompatibleReturnValue(false)
  829. end if
  830. m.currentResult.addResult("")
  831. return m.getLegacyCompatibleReturnValue(true)
  832. end function
  833. ' /**
  834. ' * @memberof module:BaseTestSuite
  835. ' * @name assertSubType
  836. ' * @function
  837. ' * @instance
  838. ' * @description Asserts that the value is a node of designated subtype
  839. ' * @param {Dynamic} value - value to check - target node
  840. ' * @param {Dynamic} typeStr - type name
  841. ' * @param {Dynamic} [msg=""] - alternate error message
  842. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  843. ' */
  844. instance.assertSubType = function(value, typeStr, msg = "") as dynamic
  845. if m.currentResult.isFail then
  846. return m.getLegacyCompatibleReturnValue(false)
  847. end if
  848. if type(value) <> "roSGNode" then
  849. if msg = "" then
  850. expr_as_string = Rooibos_Common_asString(value)
  851. msg = expr_as_string + " was not a node, so could not match subtype " + typeStr
  852. end if
  853. m.currentResult.addResult(msg)
  854. return m.getLegacyCompatibleReturnValue(false)
  855. else if (value.subType() <> typeStr) then
  856. if msg = "" then
  857. expr_as_string = Rooibos_Common_asString(value)
  858. msg = expr_as_string + "( type : " + value.subType() + ") was not of subType " + typeStr
  859. end if
  860. m.currentResult.addResult(msg)
  861. return m.getLegacyCompatibleReturnValue(false)
  862. end if
  863. m.currentResult.addResult("")
  864. return m.getLegacyCompatibleReturnValue(true)
  865. end function
  866. '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  867. '++ NEW NODE ASSERTS
  868. '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  869. ' /**
  870. ' * @memberof module:BaseTestSuite
  871. ' * @name assertNodeCount
  872. ' * @function
  873. ' * @instance
  874. ' * @description Asserts that the node contains the desginated number of children
  875. ' * @param {Dynamic} node - target node
  876. ' * @param {Dynamic} count - expected number of child items
  877. ' * @param {Dynamic} [msg=""] - alternate error message
  878. ' * @returns {boolean} - true if the assert w, false otherwise
  879. ' */
  880. instance.assertNodeCount = function(node, count, msg = "") as dynamic
  881. if m.currentResult.isFail then
  882. return m.getLegacyCompatibleReturnValue(false)
  883. end if
  884. if type(node) = "roSGNode" then
  885. if node.getChildCount() <> count then
  886. msg = "node items count <> " + Rooibos_Common_asString(count) + ". Received " + Rooibos_Common_asString(node.getChildCount())
  887. m.currentResult.addResult(msg)
  888. return m.getLegacyCompatibleReturnValue(false)
  889. end if
  890. else
  891. msg = "Input value is not an node."
  892. m.currentResult.addResult(msg)
  893. return m.getLegacyCompatibleReturnValue(false)
  894. end if
  895. m.currentResult.addResult("")
  896. return m.getLegacyCompatibleReturnValue(true)
  897. end function
  898. ' /**
  899. ' * @memberof module:BaseTestSuite
  900. ' * @name assertNodeNotCount
  901. ' * @function
  902. ' * @instance
  903. ' * @description Fail if the node items count = expected count.
  904. ' * @param {Dynamic} node - A target node
  905. ' * @param {Dynamic} count - Expected item count
  906. ' * @param {Dynamic} [msg=""] - alternate error message
  907. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  908. ' */
  909. instance.assertNodeNotCount = function(node, count, msg = "") as dynamic
  910. if m.currentResult.isFail then
  911. return m.getLegacyCompatibleReturnValue(false)
  912. end if
  913. if type(node) = "roSGNode" then
  914. if node.getChildCount() = count then
  915. msg = "node items count = " + Rooibos_Common_asString(count) + "."
  916. m.currentResult.addResult(msg)
  917. return m.getLegacyCompatibleReturnValue(false)
  918. end if
  919. else
  920. msg = "Input value is not an node."
  921. m.currentResult.addResult(msg)
  922. return m.getLegacyCompatibleReturnValue(false)
  923. end if
  924. m.currentResult.addResult("")
  925. return m.getLegacyCompatibleReturnValue(true)
  926. end function
  927. ' /**
  928. ' * @memberof module:BaseTestSuite
  929. ' * @name assertNodeEmpty
  930. ' * @function
  931. ' * @instance
  932. ' * @description Asserts the node has no children
  933. ' * @param {Dynamic} node - a node to check
  934. ' * @param {Dynamic} [msg=""] - alternate error message
  935. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  936. ' */
  937. instance.assertNodeEmpty = function(node, msg = "") as dynamic
  938. if m.currentResult.isFail then
  939. return m.getLegacyCompatibleReturnValue(false)
  940. end if
  941. if type(node) = "roSGNode" then
  942. if node.getChildCount() > 0 then
  943. msg = "node is not empty."
  944. m.currentResult.addResult(msg)
  945. return m.getLegacyCompatibleReturnValue(false)
  946. end if
  947. end if
  948. m.currentResult.addResult("")
  949. return m.getLegacyCompatibleReturnValue(true)
  950. end function
  951. ' /**
  952. ' * @memberof module:BaseTestSuite
  953. ' * @name assertNodeNotEmpty
  954. ' * @function
  955. ' * @instance
  956. ' * @description Asserts the node has children
  957. ' * @param {Dynamic} node - a node to check
  958. ' * @param {Dynamic} [msg=""] - alternate error message
  959. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  960. ' */
  961. instance.assertNodeNotEmpty = function(node, msg = "") as dynamic
  962. if m.currentResult.isFail then
  963. return m.getLegacyCompatibleReturnValue(false)
  964. end if
  965. if type(node) = "roSGNode" then
  966. if node.Count() = 0 then
  967. msg = "Array is empty."
  968. m.currentResult.addResult(msg)
  969. return m.getLegacyCompatibleReturnValue(false)
  970. end if
  971. end if
  972. m.currentResult.addResult("")
  973. return m.getLegacyCompatibleReturnValue(true)
  974. end function
  975. ' /**
  976. ' * @memberof module:BaseTestSuite
  977. ' * @name assertNodeContains
  978. ' * @function
  979. ' * @instance
  980. ' * @description Asserts the node contains the child _value_
  981. ' * @param {Dynamic} node - a node to check
  982. ' * @param {Dynamic} value - value to check - value to look for
  983. ' * @param {Dynamic} [msg=""] - alternate error message
  984. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  985. ' */
  986. instance.assertNodeContains = function(node, value, msg = "") as dynamic
  987. if m.currentResult.isFail then
  988. return m.getLegacyCompatibleReturnValue(false)
  989. end if
  990. if type(node) = "roSGNode" then
  991. if not Rooibos_Common_nodeContains(node, value) then
  992. msg = "Node doesn't have the '" + Rooibos_Common_asString(value) + "' value."
  993. m.currentResult.addResult(msg)
  994. return m.getLegacyCompatibleReturnValue(false)
  995. end if
  996. else
  997. msg = "Input value is not an Node."
  998. m.currentResult.addResult(msg)
  999. return m.getLegacyCompatibleReturnValue(false)
  1000. end if
  1001. m.currentResult.addResult("")
  1002. return m.getLegacyCompatibleReturnValue(true)
  1003. end function
  1004. ' /**
  1005. ' * @memberof module:BaseTestSuite
  1006. ' * @name assertNodeContainsOnly
  1007. ' * @function
  1008. ' * @instance
  1009. ' * @description Asserts the node contains only the child _value_
  1010. ' * @param {Dynamic} node - a node to check
  1011. ' * @param {Dynamic} value - value to check - value to look for
  1012. ' * @param {Dynamic} [msg=""] - alternate error message
  1013. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  1014. ' */
  1015. instance.assertNodeContainsOnly = function(node, value, msg = "") as dynamic
  1016. if m.currentResult.isFail then
  1017. return m.getLegacyCompatibleReturnValue(false)
  1018. end if
  1019. if type(node) = "roSGNode" then
  1020. if not Rooibos_Common_nodeContains(node, value) then
  1021. msg = "Node doesn't have the '" + Rooibos_Common_asString(value) + "' value."
  1022. m.currentResult.addResult(msg)
  1023. return m.getLegacyCompatibleReturnValue(false)
  1024. else if node.getChildCount() <> 1 then
  1025. msg = "Node Contains speicified value; but other values as well"
  1026. m.currentResult.addResult(msg)
  1027. return m.getLegacyCompatibleReturnValue(false)
  1028. end if
  1029. else
  1030. msg = "Input value is not an Node."
  1031. m.currentResult.addResult(msg)
  1032. return m.getLegacyCompatibleReturnValue(false)
  1033. end if
  1034. m.currentResult.addResult("")
  1035. return m.getLegacyCompatibleReturnValue(true)
  1036. end function
  1037. ' /**
  1038. ' * @memberof module:BaseTestSuite
  1039. ' * @name assertNodeNotContains
  1040. ' * @function
  1041. ' * @instance
  1042. ' * @description Fail if the node h item.
  1043. ' * @param {Dynamic} node - A target node
  1044. ' * @param {Dynamic} value - value to check - a node child
  1045. ' * @param {Dynamic} [msg=""] - alternate error message
  1046. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  1047. ' */
  1048. instance.assertNodeNotContains = function(node, value, msg = "") as dynamic
  1049. if m.currentResult.isFail then
  1050. return m.getLegacyCompatibleReturnValue(false)
  1051. end if
  1052. if type(node) = "roSGNode" then
  1053. if Rooibos_Common_nodeContains(node, value) then
  1054. msg = "Node has the '" + Rooibos_Common_asString(value) + "' value."
  1055. m.currentResult.addResult(msg)
  1056. return m.getLegacyCompatibleReturnValue(false)
  1057. end if
  1058. else
  1059. msg = "Input value is not an Node."
  1060. m.currentResult.addResult(msg)
  1061. return m.getLegacyCompatibleReturnValue(false)
  1062. end if
  1063. m.currentResult.addResult("")
  1064. return m.getLegacyCompatibleReturnValue(true)
  1065. end function
  1066. ' /**
  1067. ' * @memberof module:BaseTestSuite
  1068. ' * @name assertNodeContainsFields
  1069. ' * @function
  1070. ' * @instance
  1071. ' * @description Fail if the node doesn't have the item subset.
  1072. ' * @param {Dynamic} node - A target node
  1073. ' * @param {Dynamic} subset - items to check
  1074. ' * @param {Dynamic} [msg=""] - alternate error message
  1075. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  1076. ' */
  1077. instance.assertNodeContainsFields = function(node, subset, ignoredFields = invalid, msg = "") as dynamic
  1078. if m.currentResult.isFail then
  1079. return m.getLegacyCompatibleReturnValue(false)
  1080. end if
  1081. if (type(node) = "roSGNode" and Rooibos_Common_isAssociativeArray(subset)) or (type(node) = "roSGNode" and Rooibos_Common_isArray(subset)) then
  1082. isAA = Rooibos_Common_isAssociativeArray(subset)
  1083. isIgnoredFields = Rooibos_Common_isArray(ignoredFields)
  1084. for each key in subset
  1085. if (key <> "") then
  1086. if (not isIgnoredFields or not Rooibos_Common_arrayContains(ignoredFields, key)) then
  1087. subsetValue = subset[key]
  1088. nodeValue = node[key]
  1089. if not Rooibos_Common_eqValues(nodeValue, subsetValue) then
  1090. msg = key + ": Expected '" + Rooibos_Common_asString(subsetValue) + "', got '" + Rooibos_Common_asString(nodeValue) + "'"
  1091. m.currentResult.addResult(msg)
  1092. return m.getLegacyCompatibleReturnValue(false)
  1093. end if
  1094. end if
  1095. else
  1096. print "Found empty key!"
  1097. end if
  1098. end for
  1099. else
  1100. msg = "Input value is not an Node."
  1101. m.currentResult.addResult(msg)
  1102. return m.getLegacyCompatibleReturnValue(false)
  1103. end if
  1104. m.currentResult.addResult("")
  1105. return m.getLegacyCompatibleReturnValue(true)
  1106. end function
  1107. ' /**
  1108. ' * @memberof module:BaseTestSuite
  1109. ' * @name assertNodeNotContainsFields
  1110. ' * @function
  1111. ' * @instance
  1112. ' * @description Fail if the node have the item from subset.
  1113. ' * @param {Dynamic} node - A target node
  1114. ' * @param {Dynamic} subset - the items to check for
  1115. ' * @param {Dynamic} [msg=""] - alternate error message
  1116. ' * @returns {boolean} - true if the assert w, false otherwise
  1117. ' */
  1118. instance.assertNodeNotContainsFields = function(node, subset, msg = "") as dynamic
  1119. if m.currentResult.isFail then
  1120. return m.getLegacyCompatibleReturnValue(false)
  1121. end if
  1122. if (type(node) = "roSGNode" and Rooibos_Common_isAssociativeArray(subset)) or (type(node) = "roSGNode" and Rooibos_Common_isArray(subset)) then
  1123. isAA = Rooibos_Common_isAssociativeArray(subset)
  1124. for each item in subset
  1125. key = invalid
  1126. value = item
  1127. if isAA then
  1128. key = item
  1129. value = item[key]
  1130. end if
  1131. if Rooibos_Common_nodeContains(node, value) then
  1132. msg = "Node has the '" + Rooibos_Common_asString(value) + "' value."
  1133. m.currentResult.addResult(msg)
  1134. return m.getLegacyCompatibleReturnValue(false)
  1135. end if
  1136. end for
  1137. else
  1138. msg = "Input value is not an Node."
  1139. m.currentResult.addResult(msg)
  1140. return m.getLegacyCompatibleReturnValue(false)
  1141. end if
  1142. m.currentResult.addResult("")
  1143. return m.getLegacyCompatibleReturnValue(true)
  1144. end function
  1145. '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1146. '++ END NODE ASSERTS
  1147. '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1148. ' /**
  1149. ' * @memberof module:BaseTestSuite
  1150. ' * @name assertAAContainsSubset
  1151. ' * @function
  1152. ' * @instance
  1153. ' * @description Asserts the associative array contains the fields contained in subset; while ignoring the fields in the ignoredFields array
  1154. ' * @param {Dynamic} array - associative array to check
  1155. ' * @param {Dynamic} subset - associative array of values to check for
  1156. ' * @param {Dynamic} ignoredFields - array of fieldnames to ignore while comparing
  1157. ' * @param {Dynamic} [msg=""] - alternate error message
  1158. ' * @returns {boolean} - true if the assert was satisfied, false otherwise
  1159. ' */
  1160. instance.assertAAContainsSubset = function(array, subset, ignoredFields = invalid, msg = "") as dynamic
  1161. if m.currentResult.isFail then
  1162. return m.getLegacyCompatibleReturnValue(false)
  1163. end if
  1164. if (Rooibos_Common_isAssociativeArray(array) and Rooibos_Common_isAssociativeArray(subset)) then
  1165. isAA = Rooibos_Common_isAssociativeArray(subset)
  1166. isIgnoredFields = Rooibos_Common_isArray(ignoredFields)
  1167. for each key in subset
  1168. if (key <> "") then
  1169. if (not isIgnoredFields or not Rooibos_Common_arrayContains(ignoredFields, key)) then
  1170. subsetValue = subset[key]
  1171. arrayValue = array[key]
  1172. if not Rooibos_Common_eqValues(arrayValue, subsetValue) then
  1173. msg = key + ": Expected '" + Rooibos_Common_asString(subsetValue) + "', got '" + Rooibos_Common_asString(arrayValue) + "'"
  1174. m.currentResult.addResult(msg)
  1175. return m.getLegacyCompatibleReturnValue(false)
  1176. end if
  1177. end if
  1178. else
  1179. print "Found empty key!"
  1180. end if
  1181. end for
  1182. else
  1183. msg = "Input values are not an Associative Array."
  1184. return m.getLegacyCompatibleReturnValue(false)
  1185. end if
  1186. m.currentResult.addResult("")
  1187. return m.getLegacyCompatibleReturnValue(true)
  1188. end function
  1189. '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1190. '++ Stubbing helpers
  1191. '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1192. ' /**
  1193. ' * @memberof module:BaseTestSuite
  1194. ' * @name stub
  1195. ' * @function
  1196. ' * @instance
  1197. ' * @description Creates a stub to replace a real method with
  1198. ' * @param {Dynamic} target - object on which the method to be stubbed is found
  1199. ' * @param {Dynamic} methodName - name of method to stub
  1200. ' * @param {Dynamic} [returnValue=invalid] - value that the stub method will return when invoked
  1201. ' * @param {boolean} [allowNonExistingMethods=false] - if true, then rooibos will only warn if the method did not exist prior to faking
  1202. ' * @returns {Object} - stub that was wired into the real method
  1203. ' */
  1204. instance.stub = function(target, methodName, returnValue = invalid, allowNonExistingMethods = false) as object
  1205. if (type(target) <> "roAssociativeArray") then
  1206. m.fail("could not create Stub provided target was null")
  1207. return {}
  1208. end if
  1209. if (m.stubs = invalid) then
  1210. m.__stubId = - 1
  1211. m.stubs = {}
  1212. end if
  1213. m.__stubId++
  1214. if (m.__stubId > 5) then
  1215. print "ERROR ONLY 6 STUBS PER TEST ARE SUPPORTED!!"
  1216. return invalid
  1217. end if
  1218. id = stri(m.__stubId).trim()
  1219. fake = m.createFake(id, target, methodName, 1, invalid, returnValue)
  1220. m.stubs[id] = fake
  1221. allowNonExisting = m.allowNonExistingMethodsOnMocks = true or allowNonExistingMethods
  1222. isMethodPresent = type(target[methodName]) = "Function" or type(target[methodName]) = "roFunction"
  1223. if (isMethodPresent or allowNonExisting) then
  1224. target[methodName] = m["StubCallback" + id]
  1225. target.__stubs = m.stubs
  1226. if (not isMethodPresent) then
  1227. print "WARNING - stubbing call " ; methodName ; " which did not exist on target object"
  1228. end if
  1229. else
  1230. print "ERROR - could not create Stub : method not found " ; target ; "." ; methodName
  1231. end if
  1232. return fake
  1233. end function
  1234. ' /**
  1235. ' * @memberof module:BaseTestSuite
  1236. ' * @name expectOnce
  1237. ' * @function
  1238. ' * @instance
  1239. ' * @description Creates a stub to replace a real method with, which the framework will track. If it was invoked the wrong number of times, or with wrong arguments, it will result in test failure
  1240. ' * @param {Dynamic} target - object on which the method to be stubbed is found
  1241. ' * @param {Dynamic} methodName - name of method to stub
  1242. ' * @param {Dynamic} [expectedArgs=invalid] - array containing the arguments we expect the method to be invoked with
  1243. ' * @param {Dynamic} [returnValue=invalid] - value that the stub method will return when invoked
  1244. ' * @param {boolean} [allowNonExistingMethods=false] - if true, then rooibos will only warn if the method did not exist prior to faking
  1245. ' * @returns {Object} - mock that was wired into the real method
  1246. ' */
  1247. instance.expectOnce = function(target, methodName, expectedArgs = invalid, returnValue = invalid, allowNonExistingMethods = false) as object
  1248. return m.mock(target, methodName, 1, expectedArgs, returnValue, allowNonExistingMethods)
  1249. end function
  1250. instance.expectOnceWLN = function(lineNumber, target, methodName, expectedArgs = invalid, returnValue = invalid, allowNonExistingMethods = false) as object
  1251. return m.mock(target, methodName, 1, expectedArgs, returnValue, allowNonExistingMethods, lineNumber)
  1252. end function
  1253. ' /**
  1254. ' * @memberof module:BaseTestSuite
  1255. ' * @name expectOnceOrNone
  1256. ' * @function
  1257. ' * @instance
  1258. ' * @description Toggles between expectOnce and expectNone, to allow for easy paremeterized expect behaviour
  1259. ' * @param {Dynamic} target - object on which the method to be stubbed is found
  1260. ' * @param {Dynamic} methodName - name of method to stub
  1261. ' * @param {Dynamic} isExpected - if true, then this is the same as expectOnce, if false, then this is the same as expectNone
  1262. ' * @param {Dynamic} [expectedArgs=invalid] - array containing the arguments we expect the method to be invoked with
  1263. ' * @param {Dynamic} [returnValue=invalid] - value that the stub method will return when invoked
  1264. ' * @param {boolean} [allowNonExistingMethods=false] - if true, then rooibos will only warn if the method did not exist prior to faking
  1265. ' * @returns {Object} - mock that was wired into the real method
  1266. ' */
  1267. instance.expectOnceOrNone = function(target, methodName, isExpected, expectedArgs = invalid, returnValue = invalid, allowNonExistingMethods = false) as object
  1268. if isExpected then
  1269. return m.expectOnce(target, methodName, expectedArgs, returnValue, allowNonExistingMethods)
  1270. else
  1271. return m.expectNone(target, methodName, allowNonExistingMethods)
  1272. end if
  1273. end function
  1274. instance.expectOnceOrNoneWLN = function(lineNumber, target, methodName, isExpected, expectedArgs = invalid, returnValue = invalid, allowNonExistingMethods = false) as object
  1275. if isExpected then
  1276. return m.expectOnceWLN(lineNumber, target, methodName, expectedArgs, returnValue, allowNonExistingMethods)
  1277. else
  1278. return m.expectNoneWLN(lineNumber, target, methodName, allowNonExistingMethods)
  1279. end if
  1280. end function
  1281. ' /**
  1282. ' * @memberof module:BaseTestSuite
  1283. ' * @name expectNone
  1284. ' * @function
  1285. ' * @instance
  1286. ' * @description Creates a stub to replace a real method with, which the framework will track. If it was invoked, it will result in test failure
  1287. ' * @param {Dynamic} target - object on which the method to be stubbed is found
  1288. ' * @param {Dynamic} methodName - name of method to stub
  1289. ' * @param {boolean} [allowNonExistingMethods=false] - if true, then rooibos will only warn if the method did not exist prior to faking
  1290. ' * @returns {Object} - mock that was wired into the real method
  1291. ' */
  1292. instance.expectNone = function(target, methodName, allowNonExistingMethods = false) as object
  1293. return m.mock(target, methodName, 0, invalid, invalid, allowNonExistingMethods)
  1294. end function
  1295. instance.expectNoneWLN = function(lineNumber, target, methodName, allowNonExistingMethods = false) as object
  1296. return m.mock(target, methodName, 0, invalid, invalid, allowNonExistingMethods, lineNumber)
  1297. end function
  1298. ' /**
  1299. ' * @memberof module:BaseTestSuite
  1300. ' * @name expect
  1301. ' * @function
  1302. ' * @instance
  1303. ' * @description Creates a stub to replace a real method with, which the framework will track. If it was invoked the wrong number of times, or with wrong arguments, it will result in test failure
  1304. ' * @param {Dynamic} target - object on which the method to be stubbed is found
  1305. ' * @param {Dynamic} methodName - name of method to stub
  1306. ' * @param {Dynamic} [expectedInvocations=1] - number of invocations we expect
  1307. ' * @param {Dynamic} [expectedArgs=invalid] - array containing the arguments we expect the method to be invoked with
  1308. ' * @param {Dynamic} [returnValue=invalid] - value that the stub method will return when invoked
  1309. ' * @param {boolean} [allowNonExistingMethods=false] - if true, then rooibos will only warn if the method did not exist prior to faking
  1310. ' * @returns {Object} - mock that was wired into the real method
  1311. ' */
  1312. instance.expect = function(target, methodName, expectedInvocations = 1, expectedArgs = invalid, returnValue = invalid, allowNonExistingMethods = false) as object
  1313. return m.mock(target, methodName, expectedInvocations, expectedArgs, returnValue, allowNonExistingMethods)
  1314. end function
  1315. instance.expectWLN = function(lineNumber, target, methodName, expectedInvocations = 1, expectedArgs = invalid, returnValue = invalid, allowNonExistingMethods = false) as object
  1316. return m.mock(target, methodName, expectedInvocations, expectedArgs, returnValue, allowNonExistingMethods, lineNumber)
  1317. end function
  1318. ' /**
  1319. ' * @memberof module:BaseTestSuite
  1320. ' * @name mock
  1321. ' * @function
  1322. ' * @instance
  1323. ' * @description Creates a stub to replace a real method with, which the framework will track. If it was invoked the wrong number of times, or with wrong arguments, it will result in test failure
  1324. ' * @param {Dynamic} target - object on which the method to be stubbed is found
  1325. ' * @param {Dynamic} methodName - name of method to stub
  1326. ' * @param {Dynamic} expectedInvocations - number of invocations we expect
  1327. ' * @param {Dynamic} [expectedArgs=invalid] - array containing the arguments we expect the method to be invoked with
  1328. ' * @param {Dynamic} [returnValue=invalid] - value that the stub method will return when invoked
  1329. ' * @param {boolean} [allowNonExistingMethods=false] - if true, then rooibos will only warn if the method did not exist prior to faking
  1330. ' * @returns {Object} - mock that was wired into the real method
  1331. ' */
  1332. instance.mock = function(target, methodName, expectedInvocations = 1, expectedArgs = invalid, returnValue = invalid, allowNonExistingMethods = false, lineNumber = - 1) as object
  1333. 'check params
  1334. if not Rooibos_Common_isAssociativeArray(target) then
  1335. methodName = ""
  1336. m.mockFail(lineNumber, "", "mock args: target was not an AA")
  1337. else if not Rooibos_Common_isString(methodName) then
  1338. methodName = ""
  1339. m.mockFail(lineNumber, "", "mock args: methodName was not a string")
  1340. else if not Rooibos_Common_isNumber(expectedInvocations) then
  1341. m.mockFail(lineNumber, methodName, "mock args: expectedInvocations was not an int")
  1342. else if not Rooibos_Common_isArray(expectedArgs) and Rooibos_Common_isValid(expectedArgs) then
  1343. m.mockFail(lineNumber, methodName, "mock args: expectedArgs was not invalid or an array of args")
  1344. else if Rooibos_Common_isUndefined(expectedArgs) then
  1345. m.mockFail(lineNumber, methodName, "mock args: expectedArgs undefined")
  1346. else if Rooibos_Common_isUndefined(returnValue) then
  1347. m.mockFail(lineNumber, methodName, "mock args: returnValue undefined")
  1348. end if
  1349. if m.currentResult.isFail then
  1350. print "ERROR! Cannot create MOCK. method " ; methodName ; " " ; str(lineNumber) ; " " ; m.currentResult.messages.peek()
  1351. return {}
  1352. end if
  1353. if (m.mocks = invalid) then
  1354. m.__mockId = - 1
  1355. m.__mockTargetId = - 1
  1356. m.mocks = {}
  1357. end if
  1358. fake = invalid
  1359. if not target.doesExist("__rooibosTargetId") then
  1360. m.__mockTargetId++
  1361. target["__rooibosTargetId"] = m.__mockTargetId
  1362. end if
  1363. 'ascertain if mock already exists
  1364. for i = 0 to m.__mockId
  1365. id = stri(i).trim()
  1366. mock = m.mocks[id]
  1367. if mock <> invalid and mock.methodName = methodName and mock.target.__rooibosTargetId = target.__rooibosTargetId then
  1368. fake = mock
  1369. fake.lineNumbers.push(lineNumber)
  1370. exit for
  1371. end if
  1372. end for
  1373. if fake = invalid then
  1374. m.__mockId++
  1375. id = stri(m.__mockId).trim()
  1376. if (m.__mockId > 25) then
  1377. print "ERROR ONLY 25 MOCKS PER TEST ARE SUPPORTED!! you're on # " ; m.__mockId
  1378. print " Method was " ; methodName
  1379. return invalid
  1380. end if
  1381. fake = m.createFake(id, target, methodName, expectedInvocations, expectedArgs, returnValue, lineNumber)
  1382. m.mocks[id] = fake 'this will bind it to m
  1383. allowNonExisting = m.allowNonExistingMethodsOnMocks = true or allowNonExistingMethods
  1384. isMethodPresent = type(target[methodName]) = "Function" or type(target[methodName]) = "roFunction"
  1385. if (isMethodPresent or allowNonExisting) then
  1386. target[methodName] = m["MockCallback" + id]
  1387. target.__mocks = m.mocks
  1388. if (not isMethodPresent) then
  1389. print "WARNING - mocking call " ; methodName ; " which did not exist on target object"
  1390. end if
  1391. else
  1392. print "ERROR - could not create Mock : method not found " ; target ; "." ; methodName
  1393. end if
  1394. else
  1395. m.combineFakes(fake, m.createFake(id, target, methodName, expectedInvocations, expectedArgs, returnValue, lineNumber))
  1396. end if
  1397. return fake
  1398. end function
  1399. ' /**
  1400. ' * @memberof module:BaseTestSuite
  1401. ' * @name createFake
  1402. ' * @function
  1403. ' * @instance
  1404. ' * @description Creates a stub to replace a real method with. This is used internally.
  1405. ' * @param {Dynamic} target - object on which the method to be stubbed is found
  1406. ' * @param {Dynamic} methodName - name of method to stub
  1407. ' * @param {Dynamic} [expectedInvocations=1] - number of invocations we expect
  1408. ' * @param {Dynamic} [expectedArgs=invalid] - array containing the arguments we expect the method to be invoked with
  1409. ' * @param {Dynamic} [returnValue=invalid] - value that the stub method will return when invoked
  1410. ' * @returns {Object} - stub that was wired into the real method
  1411. ' */
  1412. instance.createFake = function(id, target, methodName, expectedInvocations = 1, expectedArgs = invalid, returnValue = invalid, lineNumber = - 1) as object
  1413. expectedArgsValues = []
  1414. hasArgs = Rooibos_Common_isArray(expectedArgs)
  1415. if (hasArgs) then
  1416. defaultValue = m.invalidValue
  1417. else
  1418. defaultValue = m.ignoreValue
  1419. expectedArgs = []
  1420. end if
  1421. lineNumbers = [
  1422. lineNumber
  1423. ]
  1424. for i = 0 to 9
  1425. if (hasArgs and expectedArgs.count() > i) then
  1426. 'guard against bad values
  1427. value = expectedArgs[i]
  1428. if not Rooibos_Common_isUndefined(value) then
  1429. if Rooibos_Common_isAssociativeArray(value) and Rooibos_Common_isValid(value.matcher) then
  1430. if not Rooibos_Common_isFunction(value.matcher) then
  1431. print "[ERROR] you have specified a matching function; but it is not in scope!"
  1432. expectedArgsValues.push("#ERR-OUT_OF_SCOPE_MATCHER!")
  1433. else
  1434. expectedArgsValues.push(expectedArgs[i])
  1435. end if
  1436. else
  1437. expectedArgsValues.push(expectedArgs[i])
  1438. end if
  1439. else
  1440. expectedArgsValues.push("#ERR-UNDEFINED!")
  1441. end if
  1442. else
  1443. expectedArgsValues.push(defaultValue)
  1444. end if
  1445. end for
  1446. fake = {
  1447. id: id,
  1448. target: target,
  1449. methodName: methodName,
  1450. returnValue: returnValue,
  1451. lineNumbers: lineNumbers,
  1452. isCalled: false,
  1453. invocations: 0,
  1454. invokedArgs: [
  1455. invalid,
  1456. invalid,
  1457. invalid,
  1458. invalid,
  1459. invalid,
  1460. invalid,
  1461. invalid,
  1462. invalid,
  1463. invalid
  1464. ],
  1465. expectedArgs: expectedArgsValues,
  1466. expectedInvocations: expectedInvocations,
  1467. callback: function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1468. ' ? "FAKE CALLBACK CALLED FOR " ; m.methodName
  1469. if (m.allInvokedArgs = invalid) then
  1470. m.allInvokedArgs = []
  1471. end if
  1472. m.invokedArgs = [
  1473. arg1,
  1474. arg2,
  1475. arg3,
  1476. arg4,
  1477. arg5,
  1478. arg6,
  1479. arg7,
  1480. arg8,
  1481. arg9
  1482. ]
  1483. m.allInvokedArgs.push([
  1484. arg1,
  1485. arg2,
  1486. arg3,
  1487. arg4,
  1488. arg5,
  1489. arg6,
  1490. arg7,
  1491. arg8,
  1492. arg9
  1493. ])
  1494. m.isCalled = true
  1495. m.invocations++
  1496. if (type(m.returnValue) = "roAssociativeArray" and m.returnValue.doesExist("multiResult")) then
  1497. returnValues = m.returnValue["multiResult"]
  1498. returnIndex = m.invocations - 1
  1499. if (type(returnValues) = "roArray" and returnValues.count() > 0) then
  1500. if returnValues.count() <= m.invocations then
  1501. returnIndex = returnValues.count() - 1
  1502. print "Multi return values all used up - repeating last value"
  1503. end if
  1504. return returnValues[returnIndex]
  1505. else
  1506. print "Multi return value was specified; but no array of results were found"
  1507. return invalid
  1508. end if
  1509. else
  1510. return m.returnValue
  1511. end if
  1512. end function
  1513. }
  1514. return fake
  1515. end function
  1516. instance.combineFakes = function(fake, otherFake)
  1517. 'add on the expected invoked args
  1518. if type(fake.expectedArgs) <> "roAssociativeArray" or not fake.expectedArgs.doesExist("multiInvoke") then
  1519. currentExpectedArgsArgs = fake.expectedArgs
  1520. fake.expectedArgs = {
  1521. "multiInvoke": [
  1522. currentExpectedArgsArgs
  1523. ]
  1524. }
  1525. end if
  1526. fake.expectedArgs.multiInvoke.push(otherFake.expectedArgs)
  1527. 'add on the expected return values
  1528. if type(fake.returnValue) <> "roAssociativeArray" or not fake.returnValue.doesExist("multiResult") then
  1529. currentReturnValue = fake.returnValue
  1530. fake.returnValue = {
  1531. "multiResult": [
  1532. currentReturnValue
  1533. ]
  1534. }
  1535. end if
  1536. fake.returnValue.multiResult.push(otherFake.returnValue)
  1537. fake.lineNumbers.push(lineNumber)
  1538. fake.expectedInvocations++
  1539. end function
  1540. ' /**
  1541. ' * @memberof module:BaseTestSuite
  1542. ' * @name assertMocks
  1543. ' * @function
  1544. ' * @instance
  1545. ' * @description Will check all mocks that have been created to ensure they were invoked the expected amount of times, with the expected args.
  1546. ' */
  1547. instance.assertMocks = function() as void
  1548. if (m.__mockId = invalid or not Rooibos_Common_isAssociativeArray(m.mocks)) then
  1549. return
  1550. end if
  1551. lastId = int(m.__mockId)
  1552. for each id in m.mocks
  1553. mock = m.mocks[id]
  1554. methodName = mock.methodName
  1555. if (mock.expectedInvocations <> mock.invocations) then
  1556. m.mockFail(mock.lineNumbers[0], methodName, "Wrong number of calls. (" + stri(mock.invocations).trim() + " / " + stri(mock.expectedInvocations).trim() + ")")
  1557. m.cleanMocks()
  1558. return
  1559. else if mock.expectedInvocations > 0 and (Rooibos_Common_isArray(mock.expectedArgs) or (type(mock.expectedArgs) = "roAssociativeArray" and Rooibos_Common_isArray(mock.expectedArgs.multiInvoke))) then
  1560. isMultiArgsSupported = type(mock.expectedArgs) = "roAssociativeArray" and Rooibos_Common_isArray(mock.expectedArgs.multiInvoke)
  1561. for invocationIndex = 0 to mock.invocations - 1
  1562. invokedArgs = mock.allInvokedArgs[invocationIndex]
  1563. if isMultiArgsSupported then
  1564. expectedArgs = mock.expectedArgs.multiInvoke[invocationIndex]
  1565. else
  1566. expectedArgs = mock.expectedArgs
  1567. end if
  1568. for i = 0 to expectedArgs.count() - 1
  1569. value = invokedArgs[i]
  1570. expected = expectedArgs[i]
  1571. didNotExpectArg = Rooibos_Common_isString(expected) and expected = m.invalidValue
  1572. if (didNotExpectArg) then
  1573. expected = invalid
  1574. end if
  1575. isUsingMatcher = Rooibos_Common_isAssociativeArray(expected) and Rooibos_Common_isFunction(expected.matcher)
  1576. if isUsingMatcher then
  1577. if not expected.matcher(value) then
  1578. m.mockFail(mock.lineNumbers[invocationIndex], methodName, "on Invocation #" + stri(invocationIndex).trim() + ", expected arg #" + stri(i).trim() + " to match matching function '" + Rooibos_Common_asString(expected.matcher) + "' got '" + Rooibos_Common_asString(value) + "')")
  1579. m.cleanMocks()
  1580. end if
  1581. else
  1582. if (not (Rooibos_Common_isString(expected) and expected = m.ignoreValue) and not Rooibos_Common_eqValues(value, expected)) then
  1583. if (expected = invalid) then
  1584. expected = "[INVALID]"
  1585. end if
  1586. m.mockFail(mock.lineNumbers[invocationIndex], methodName, "on Invocation #" + stri(invocationIndex).trim() + ", expected arg #" + stri(i).trim() + " to be '" + Rooibos_Common_asString(expected) + "' got '" + Rooibos_Common_asString(value) + "')")
  1587. m.cleanMocks()
  1588. return
  1589. end if
  1590. end if
  1591. end for
  1592. end for
  1593. end if
  1594. end for
  1595. m.cleanMocks()
  1596. end function
  1597. ' /**
  1598. ' * @memberof module:BaseTestSuite
  1599. ' * @name cleanMocks
  1600. ' * @function
  1601. ' * @instance
  1602. ' * @description Cleans up all tracking data associated with mocks
  1603. ' */
  1604. instance.cleanMocks = function() as void
  1605. if m.mocks = invalid then
  1606. return
  1607. end if
  1608. for each id in m.mocks
  1609. mock = m.mocks[id]
  1610. mock.target.__mocks = invalid
  1611. end for
  1612. m.mocks = invalid
  1613. end function
  1614. ' /**
  1615. ' * @memberof module:BaseTestSuite
  1616. ' * @name cleanStubs
  1617. ' * @function
  1618. ' * @instance
  1619. ' * @description Cleans up all tracking data associated with stubs
  1620. ' */
  1621. instance.cleanStubs = function() as void
  1622. if m.stubs = invalid then
  1623. return
  1624. end if
  1625. for each id in m.stubs
  1626. stub = m.stubs[id]
  1627. stub.target.__stubs = invalid
  1628. end for
  1629. m.stubs = invalid
  1630. end function
  1631. instance.mockFail = function(lineNumber, methodName, message) as dynamic
  1632. if m.currentResult.isFail then
  1633. return m.getLegacyCompatibleReturnValue(false)
  1634. end if
  1635. m.currentResult.addMockResult(lineNumber, "mock failure on '" + methodName + "' : " + message)
  1636. return m.getLegacyCompatibleReturnValue(false)
  1637. end function
  1638. '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1639. '++ Fake Stub callback functions - this is required to get scope
  1640. '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1641. instance.stubCallback0 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1642. fake = m.__Stubs["0"]
  1643. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1644. end function
  1645. instance.stubCallback1 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1646. fake = m.__Stubs["1"]
  1647. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1648. end function
  1649. instance.stubCallback2 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1650. fake = m.__Stubs["2"]
  1651. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1652. end function
  1653. instance.stubCallback3 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1654. fake = m.__Stubs["3"]
  1655. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1656. end function
  1657. instance.stubCallback4 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1658. fake = m.__Stubs["4"]
  1659. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1660. end function
  1661. instance.stubCallback5 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1662. fake = m.__Stubs["5"]
  1663. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1664. end function
  1665. '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1666. '++ Fake Mock callback functions - this is required to get scope
  1667. '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1668. instance.mockCallback0 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1669. fake = m.__mocks["0"]
  1670. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1671. end function
  1672. instance.mockCallback1 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1673. fake = m.__mocks["1"]
  1674. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1675. end function
  1676. instance.mockCallback2 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1677. fake = m.__mocks["2"]
  1678. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1679. end function
  1680. instance.mockCallback3 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1681. fake = m.__mocks["3"]
  1682. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1683. end function
  1684. instance.mockCallback4 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1685. fake = m.__mocks["4"]
  1686. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1687. end function
  1688. instance.mockCallback5 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1689. fake = m.__mocks["5"]
  1690. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1691. end function
  1692. instance.mockCallback6 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1693. fake = m.__mocks["6"]
  1694. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1695. end function
  1696. instance.mockCallback7 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1697. fake = m.__mocks["7"]
  1698. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1699. end function
  1700. instance.mockCallback8 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1701. fake = m.__mocks["8"]
  1702. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1703. end function
  1704. instance.mockCallback9 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1705. fake = m.__mocks["9"]
  1706. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1707. end function
  1708. instance.mockCallback10 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1709. fake = m.__mocks["10"]
  1710. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1711. end function
  1712. instance.mockCallback11 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1713. fake = m.__mocks["11"]
  1714. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1715. end function
  1716. instance.mockCallback12 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1717. fake = m.__mocks["12"]
  1718. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1719. end function
  1720. instance.mockCallback13 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1721. fake = m.__mocks["13"]
  1722. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1723. end function
  1724. instance.mockCallback14 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1725. fake = m.__mocks["14"]
  1726. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1727. end function
  1728. instance.mockCallback15 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1729. fake = m.__mocks["15"]
  1730. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1731. end function
  1732. instance.mockCallback16 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1733. fake = m.__mocks["16"]
  1734. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1735. end function
  1736. instance.mockCallback17 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1737. fake = m.__mocks["17"]
  1738. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1739. end function
  1740. instance.mockCallback18 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1741. fake = m.__mocks["18"]
  1742. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1743. end function
  1744. instance.mockCallback19 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1745. fake = m.__mocks["19"]
  1746. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1747. end function
  1748. instance.mockCallback20 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1749. fake = m.__mocks["20"]
  1750. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1751. end function
  1752. instance.mockCallback21 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1753. fake = m.__mocks["21"]
  1754. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1755. end function
  1756. instance.mockCallback22 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1757. fake = m.__mocks["22"]
  1758. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1759. end function
  1760. instance.mockCallback23 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1761. fake = m.__mocks["23"]
  1762. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1763. end function
  1764. instance.mockCallback24 = function(arg1 = invalid, arg2 = invalid, arg3 = invalid, arg4 = invalid, arg5 = invalid, arg6 = invalid, arg7 = invalid, arg8 = invalid, arg9 = invalid) as dynamic
  1765. fake = m.__mocks["24"]
  1766. return fake.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  1767. end function
  1768. '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1769. '++ Utility functions!
  1770. '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1771. '*************************************************************
  1772. '** ripped and adapted from rodash - thanks @veeta!
  1773. '** used by get method - consider thsis private
  1774. '*************************************************************
  1775. instance.pathAsArray_ = function(path)
  1776. pathRE = CreateObject("roRegex", "\[([0-9]+)\]", "i")
  1777. segments = []
  1778. if type(path) = "String" or type(path) = "roString" then
  1779. dottedPath = pathRE.replaceAll(path, ".\1")
  1780. stringSegments = dottedPath.tokenize(".")
  1781. for each s in stringSegments
  1782. if (Asc(s) >= 48) and (Asc(s) <= 57) then
  1783. segments.push(s.toInt())
  1784. else
  1785. segments.push(s)
  1786. end if
  1787. end for
  1788. else if type(path) = "roList" or type(path) = "roArray" then
  1789. stringPath = ""
  1790. for each s in path
  1791. stringPath = stringPath + "." + Box(s).toStr()
  1792. end for
  1793. segments = m.pathAsArray_(stringPath)
  1794. else
  1795. segments = invalid
  1796. end if
  1797. return segments
  1798. end function
  1799. ' /**
  1800. ' * @memberof module:BaseTestSuite
  1801. ' * @name g
  1802. ' * @function
  1803. ' * @instance
  1804. ' * @description ripped and adapted from rodash - thanks @veeta!
  1805. ' * use this method to safely get anything. useful for when unit testing a collection
  1806. ' * or something and you're not sure if it's gonna crash!
  1807. ' * @param {Dynamic} aa - node, array or assoArray
  1808. ' * @param {Dynamic} subset - the items to check for
  1809. ' * @param {Dynamic} path -as string path to target field. Can use .0. or [0] index notation e.g. "children.0.title" or "children[0].title"
  1810. ' * @returns {dynamic} - matched item, on aa at path
  1811. ' */
  1812. instance.g = function(aa, path, default = invalid)
  1813. if type(aa) <> "roAssociativeArray" and type(aa) <> "roArray" and type(aa) <> "roSGNode" then
  1814. return default
  1815. end if
  1816. segments = m.pathAsArray_(path)
  1817. if (Type(path) = "roInt" or Type(path) = "roInteger" or Type(path) = "Integer") then
  1818. path = stri(path).trim()
  1819. end if
  1820. if segments = invalid then
  1821. return default
  1822. end if
  1823. result = invalid
  1824. while segments.count() > 0
  1825. key = segments.shift()
  1826. if (type(key) = "roInteger") then 'it's a valid index
  1827. if (aa <> invalid and GetInterface(aa, "ifArray") <> invalid) then
  1828. value = aa[key]
  1829. else if (aa <> invalid and GetInterface(aa, "ifSGNodeChildren") <> invalid) then
  1830. value = aa.getChild(key)
  1831. else if (aa <> invalid and GetInterface(aa, "ifAssociativeArray") <> invalid) then
  1832. key = str(key)
  1833. if not aa.doesExist(key) then
  1834. exit while
  1835. end if
  1836. value = aa.lookup(key)
  1837. else
  1838. value = invalid
  1839. end if
  1840. else
  1841. if not aa.doesExist(key) then
  1842. exit while
  1843. end if
  1844. value = aa.lookup(key)
  1845. end if
  1846. if segments.count() = 0 then
  1847. result = value
  1848. exit while
  1849. end if
  1850. if type(value) <> "roAssociativeArray" and type(value) <> "roArray" and type(value) <> "roSGNode" then
  1851. exit while
  1852. end if
  1853. aa = value
  1854. end while
  1855. if result = invalid then
  1856. return default
  1857. end if
  1858. return result
  1859. end function
  1860. '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1861. '++ crude async support
  1862. '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1863. ' /**
  1864. ' * @member waitForField
  1865. ' * @memberof module:TestUtils
  1866. ' * @instance
  1867. ' * @function
  1868. ' * @description observeField doesn't work in regular unit tests, so we have to wait for the result. We can use this to wait for a network task, foe example, and pass the result directly to a handler. Note - we wait for the value TO CHANGE - so make sure that will be the case, or you'll get stuck forever :)
  1869. ' * @param {any} target to observe
  1870. ' * @param {string} field to observe
  1871. ' * @param {int} delay for each wait
  1872. ' * @param {int} max attempts
  1873. ' */
  1874. instance.waitForField = function(target, fieldName, delay = 500, maxAttempts = 10)
  1875. attempts = 0
  1876. if target = invalid then
  1877. return false
  1878. end if
  1879. initialValue = target[fieldName]
  1880. while target[fieldName] = initialValue
  1881. port = CreateObject("roMessagePort")
  1882. wait(delay, port)
  1883. attempts++
  1884. if attempts = maxAttempts then
  1885. return false
  1886. end if
  1887. print "waiting for signal field '" ; fieldName ; "' - " ; attempts
  1888. end while
  1889. return true
  1890. end function
  1891. instance.assertAsyncField = function(target, fieldName, delay = 500, maxAttempts = 10)
  1892. if m.currentResult.isFail then
  1893. return m.getLegacyCompatibleReturnValue(false)
  1894. end if
  1895. if target = invalid then
  1896. m.fail("Target was invalid")
  1897. end if
  1898. result = m.waitForField(target, fieldName, delay, maxAttempts)
  1899. if not result then
  1900. return m.fail("Timeout waiting for targetField " + fieldName + " to be set on target")
  1901. end if
  1902. m.currentResult.addResult("")
  1903. return m.getLegacyCompatibleReturnValue(true)
  1904. end function
  1905. return instance
  1906. end function
  1907. function Rooibos_BaseTestSuite()
  1908. instance = __Rooibos_BaseTestSuite_builder()
  1909. instance.new()
  1910. return instance
  1911. end function