test.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*!
  2. * async.js
  3. * Copyright(c) 2010 Fabian Jakobs <fabian.jakobs@web.de>
  4. * MIT Licensed
  5. */
  6. define(function(require, exports, module) {
  7. var oop = require("ace/lib/oop")
  8. var async = require("asyncjs/async")
  9. require("asyncjs/utils")
  10. exports.TestGenerator = function(source) {
  11. async.Generator.call(this, source)
  12. }
  13. oop.inherits(exports.TestGenerator, async.Generator)
  14. ;(function() {
  15. this.exec = function() {
  16. this.run().report().summary(function(err, passed) {
  17. console.log("DONE")
  18. })
  19. }
  20. this.run = function() {
  21. return this.setupTest()
  22. .each(function(test, next) {
  23. if (test.setUpSuite)
  24. test.setUpSuite(next)
  25. else
  26. next()
  27. })
  28. .each(function(test, next) {
  29. test.test(function(err, passed) {
  30. test.err = err
  31. test.passed = passed
  32. next()
  33. })
  34. })
  35. .each(function(test, next) {
  36. if (test.tearDownSuite)
  37. test.tearDownSuite(next)
  38. else
  39. next()
  40. })
  41. }
  42. this.report = function() {
  43. return this.each(function(test, next) {
  44. var color = test.passed ? "\x1b[32m" : "\x1b[31m"
  45. var name = test.name
  46. if (test.suiteName)
  47. name = test.suiteName + ": " + test.name
  48. console.log(color + "[" + test.count + "/" + test.index + "] " + name + " " + (test.passed ? "OK" : "FAIL") + "\x1b[0m")
  49. if (!test.passed)
  50. if (test.err.stack)
  51. console.log(test.err.stack)
  52. else
  53. console.log(test.err)
  54. next()
  55. })
  56. }
  57. this.summary = function(callback) {
  58. var passed = 0
  59. var failed = 0
  60. this.each(function(test) {
  61. if (test.passed)
  62. passed += 1
  63. else
  64. failed += 1
  65. }).end(function() {
  66. console.log("")
  67. console.log("Summary:")
  68. console.log("")
  69. console.log( "Total number of tests: " + (passed + failed))
  70. passed && console.log("\x1b[32mPassed tests: " + passed + "\x1b[0m")
  71. failed && console.log("\x1b[31mFailed tests: " + failed + "\x1b[0m")
  72. console.log("")
  73. callback(null, failed == 0)
  74. })
  75. }
  76. this.setupTest = function() {
  77. return this.each(function(test, next) {
  78. var empty = function(next) { next() }
  79. var context = test.context || this
  80. if (test.setUp)
  81. var setUp = async.makeAsync(0, test.setUp, context)
  82. else
  83. setUp = empty
  84. tearDownCalled = false
  85. if (test.tearDown)
  86. var tearDownInner = async.makeAsync(0, test.tearDown, context)
  87. else
  88. tearDownInner = empty
  89. function tearDown(next) {
  90. tearDownCalled = true
  91. tearDownInner.call(test.context, next)
  92. }
  93. var testFn = async.makeAsync(0, test.fn, context)
  94. test.test = function(callback) {
  95. var called
  96. function errorListener(e) {
  97. if (called)
  98. return
  99. called = true
  100. //process.removeListener('uncaughtException', errorListener)
  101. if (!tearDownCalled) {
  102. async.list([tearDown])
  103. .call()
  104. .timeout(test.timeout)
  105. .end(function() {
  106. callback(e, false)
  107. }) }
  108. else
  109. callback(e, false)
  110. }
  111. //process.addListener('uncaughtException', errorListener)
  112. async.list([setUp, testFn, tearDown])
  113. .delay(0)
  114. .call(context)
  115. .timeout(test.timeout)
  116. .toArray(false, function(errors, values) {
  117. if (called)
  118. return
  119. called = true
  120. var err = errors[1]
  121. //process.removeListener('uncaughtException', errorListener)
  122. callback(err, !err)
  123. })
  124. }
  125. next()
  126. })
  127. }
  128. }).call(exports.TestGenerator.prototype)
  129. exports.testcase = function(testcase, suiteName, timeout) {
  130. var methods = []
  131. for (var method in testcase)
  132. methods.push(method)
  133. var setUp = testcase.setUp || null
  134. var tearDown = testcase.tearDown || null
  135. var single
  136. methods.forEach(function(name) {
  137. if (name.charAt(0) == '>')
  138. single = name
  139. })
  140. if (single)
  141. methods = [single]
  142. var testNames = methods.filter(function(method) {
  143. return method.match(/^>?test/) && typeof(testcase[method]) == "function"
  144. })
  145. var count = testNames.length
  146. var i=1
  147. tests = testNames.map(function(name) {
  148. return {
  149. suiteName: suiteName || testcase.name || "",
  150. name: name,
  151. setUp: setUp,
  152. tearDown: tearDown,
  153. context: testcase,
  154. timeout: timeout === undefined ? 3000 : timeout,
  155. fn: testcase[name],
  156. count: count,
  157. index: i++
  158. }
  159. })
  160. if (testcase.setUpSuite) {
  161. tests[0].setUpSuite = async.makeAsync(0, testcase.setUpSuite, testcase)
  162. }
  163. if (testcase.tearDownSuite) {
  164. tests[tests.length-1].tearDownSuite = async.makeAsync(0, testcase.tearDownSuite, testcase)
  165. }
  166. return async.list(tests, exports.TestGenerator)
  167. }
  168. })