UNPKG

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