nyan.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /**
  2. * Module dependencies.
  3. */
  4. var Base = require('./base')
  5. , color = Base.color;
  6. /**
  7. * Expose `Dot`.
  8. */
  9. exports = module.exports = NyanCat;
  10. /**
  11. * Initialize a new `Dot` matrix test reporter.
  12. *
  13. * @param {Runner} runner
  14. * @api public
  15. */
  16. function NyanCat(runner) {
  17. Base.call(this, runner);
  18. var self = this
  19. , stats = this.stats
  20. , width = Base.window.width * .75 | 0
  21. , rainbowColors = this.rainbowColors = self.generateColors()
  22. , colorIndex = this.colorIndex = 0
  23. , numerOfLines = this.numberOfLines = 4
  24. , trajectories = this.trajectories = [[], [], [], []]
  25. , nyanCatWidth = this.nyanCatWidth = 11
  26. , trajectoryWidthMax = this.trajectoryWidthMax = (width - nyanCatWidth)
  27. , scoreboardWidth = this.scoreboardWidth = 5
  28. , tick = this.tick = 0
  29. , n = 0;
  30. runner.on('start', function(){
  31. Base.cursor.hide();
  32. self.draw();
  33. });
  34. runner.on('pending', function(test){
  35. self.draw();
  36. });
  37. runner.on('pass', function(test){
  38. self.draw();
  39. });
  40. runner.on('fail', function(test, err){
  41. self.draw();
  42. });
  43. runner.on('end', function(){
  44. Base.cursor.show();
  45. for (var i = 0; i < self.numberOfLines; i++) write('\n');
  46. self.epilogue();
  47. });
  48. }
  49. /**
  50. * Draw the nyan cat
  51. *
  52. * @api private
  53. */
  54. NyanCat.prototype.draw = function(){
  55. this.appendRainbow();
  56. this.drawScoreboard();
  57. this.drawRainbow();
  58. this.drawNyanCat();
  59. this.tick = !this.tick;
  60. };
  61. /**
  62. * Draw the "scoreboard" showing the number
  63. * of passes, failures and pending tests.
  64. *
  65. * @api private
  66. */
  67. NyanCat.prototype.drawScoreboard = function(){
  68. var stats = this.stats;
  69. var colors = Base.colors;
  70. function draw(color, n) {
  71. write(' ');
  72. write('\u001b[' + color + 'm' + n + '\u001b[0m');
  73. write('\n');
  74. }
  75. draw(colors.green, stats.passes);
  76. draw(colors.fail, stats.failures);
  77. draw(colors.pending, stats.pending);
  78. write('\n');
  79. this.cursorUp(this.numberOfLines);
  80. };
  81. /**
  82. * Append the rainbow.
  83. *
  84. * @api private
  85. */
  86. NyanCat.prototype.appendRainbow = function(){
  87. var segment = this.tick ? '_' : '-';
  88. var rainbowified = this.rainbowify(segment);
  89. for (var index = 0; index < this.numberOfLines; index++) {
  90. var trajectory = this.trajectories[index];
  91. if (trajectory.length >= this.trajectoryWidthMax) trajectory.shift();
  92. trajectory.push(rainbowified);
  93. }
  94. };
  95. /**
  96. * Draw the rainbow.
  97. *
  98. * @api private
  99. */
  100. NyanCat.prototype.drawRainbow = function(){
  101. var self = this;
  102. this.trajectories.forEach(function(line, index) {
  103. write('\u001b[' + self.scoreboardWidth + 'C');
  104. write(line.join(''));
  105. write('\n');
  106. });
  107. this.cursorUp(this.numberOfLines);
  108. };
  109. /**
  110. * Draw the nyan cat
  111. *
  112. * @api private
  113. */
  114. NyanCat.prototype.drawNyanCat = function() {
  115. var self = this;
  116. var startWidth = this.scoreboardWidth + this.trajectories[0].length;
  117. var color = '\u001b[' + startWidth + 'C';
  118. var padding = '';
  119. write(color);
  120. write('_,------,');
  121. write('\n');
  122. write(color);
  123. padding = self.tick ? ' ' : ' ';
  124. write('_|' + padding + '/\\_/\\ ');
  125. write('\n');
  126. write(color);
  127. padding = self.tick ? '_' : '__';
  128. var tail = self.tick ? '~' : '^';
  129. var face;
  130. write(tail + '|' + padding + this.face() + ' ');
  131. write('\n');
  132. write(color);
  133. padding = self.tick ? ' ' : ' ';
  134. write(padding + '"" "" ');
  135. write('\n');
  136. this.cursorUp(this.numberOfLines);
  137. };
  138. /**
  139. * Draw nyan cat face.
  140. *
  141. * @return {String}
  142. * @api private
  143. */
  144. NyanCat.prototype.face = function() {
  145. var stats = this.stats;
  146. if (stats.failures) {
  147. return '( x .x)';
  148. } else if (stats.pending) {
  149. return '( o .o)';
  150. } else if(stats.passes) {
  151. return '( ^ .^)';
  152. } else {
  153. return '( - .-)';
  154. }
  155. }
  156. /**
  157. * Move cursor up `n`.
  158. *
  159. * @param {Number} n
  160. * @api private
  161. */
  162. NyanCat.prototype.cursorUp = function(n) {
  163. write('\u001b[' + n + 'A');
  164. };
  165. /**
  166. * Move cursor down `n`.
  167. *
  168. * @param {Number} n
  169. * @api private
  170. */
  171. NyanCat.prototype.cursorDown = function(n) {
  172. write('\u001b[' + n + 'B');
  173. };
  174. /**
  175. * Generate rainbow colors.
  176. *
  177. * @return {Array}
  178. * @api private
  179. */
  180. NyanCat.prototype.generateColors = function(){
  181. var colors = [];
  182. for (var i = 0; i < (6 * 7); i++) {
  183. var pi3 = Math.floor(Math.PI / 3);
  184. var n = (i * (1.0 / 6));
  185. var r = Math.floor(3 * Math.sin(n) + 3);
  186. var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);
  187. var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);
  188. colors.push(36 * r + 6 * g + b + 16);
  189. }
  190. return colors;
  191. };
  192. /**
  193. * Apply rainbow to the given `str`.
  194. *
  195. * @param {String} str
  196. * @return {String}
  197. * @api private
  198. */
  199. NyanCat.prototype.rainbowify = function(str){
  200. var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];
  201. this.colorIndex += 1;
  202. return '\u001b[38;5;' + color + 'm' + str + '\u001b[0m';
  203. };
  204. /**
  205. * Stdout helper.
  206. */
  207. function write(string) {
  208. process.stdout.write(string);
  209. }
  210. /**
  211. * Inherit from `Base.prototype`.
  212. */
  213. NyanCat.prototype.__proto__ = Base.prototype;