forked from OksanaShulha/practice-code-review
-
Notifications
You must be signed in to change notification settings - Fork 0
/
describe-it.js
116 lines (105 loc) · 3.25 KB
/
describe-it.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
'use strict';
/**
* returns conventional describe and it functions for simple unit tests in node
* @param {Function} reporter - a callback used to do something with test results
*/
export const describeIt = (reporter, errors = [], status = {}) => {
let depth = 0;
let indent = ' ';
const testConsole = {
log: (...args) => {
const localIndent = Array(depth).fill(indent).join('');
reporter(localIndent, args, '\n');
},
group: (...args) => {
const localIndent = Array(depth).fill(indent).join('');
reporter(localIndent, args, '\n');
depth++;
},
groupEnd: (...args) => {
depth && depth--;
const localIndent = Array(depth).fill(indent).join('');
reporter(localIndent, args, '\n');
},
error: (...args) => {
status.fail = true;
const localIndent = Array(depth).fill(indent).join('');
reporter(
localIndent,
args.map((entry) => {
if (!entry) {
return entry;
}
if (entry instanceof Error) {
errors.push(entry);
return entry.message.split('\n').join('\n' + localIndent);
}
return entry
.toString()
.split('\n')
.join(localIndent + '\n');
}),
'\n'
);
},
};
return {
describe: (description, testFunction) => {
if (typeof description !== 'string') {
throw new TypeError('first argument must be a string');
}
if (typeof testFunction !== 'function') {
throw new TypeError('second argument must be a function');
}
testConsole.group(`\x1b[1m${description}\x1b[22m`);
try {
testFunction();
} catch (err) {
testConsole.error('\x1b[31mSUITE ERROR\x1b[39m ', err);
}
testConsole.groupEnd();
},
it: (() => {
let itIsCalled = false;
return (description, testFunction) => {
if (itIsCalled) {
throw new Error('can not call it from inside of it');
}
if (typeof description !== 'string') {
throw new TypeError('first argument must be a string');
}
if (typeof testFunction !== 'function') {
throw new TypeError('second argument must be a function');
}
itIsCalled = true;
// prevent user-defined console output for simpler and cleaner reports
// they can always debug single files
const consoleBackup = Object.assign({}, console);
const consoleCalls = [];
for (let key in console) {
if (typeof console[key] === 'function') {
console[key] = (...args) => {
consoleCalls.push({ method: key, args: Array.from(arguments) });
};
}
}
let thrown = null;
try {
testFunction();
} catch (exception) {
thrown = exception;
}
// re-enable console output
Object.assign(console, consoleBackup);
if (thrown) {
testConsole.group(`\x1b[31m✖ FAIL:\x1b[39m ${description}`);
testConsole.error(thrown);
testConsole.groupEnd();
} else {
testConsole.log(`\x1b[32m√ PASS:\x1b[39m ${description}`);
}
itIsCalled = false;
};
})(),
};
};