Skip to content

Commit 3d896f5

Browse files
Add jest for unit testing
1 parent 0eaa449 commit 3d896f5

File tree

13 files changed

+5781
-149
lines changed

13 files changed

+5781
-149
lines changed

.eslintrc.js

+26-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
module.exports = {
22
"env": {
33
"node": true,
4-
"es6": true
4+
"es6": true,
5+
"jest": true
56
},
67
"plugins": ["lodash"],
78
"extends": ["airbnb-base", "plugin:lodash/recommended"],
@@ -22,5 +23,29 @@ module.exports = {
2223
"lodash/prefer-noop": [0],
2324
"max-len": ["error", { "code": 110 }],
2425
"operator-linebreak": ["error", "before"],
26+
// override airbnb-base dev dependencies, latest version does not white list __mocks__
27+
'import/no-extraneous-dependencies': ['error', {
28+
devDependencies: [
29+
'test/**', // tape, common npm pattern
30+
'tests/**', // also common npm pattern
31+
'spec/**', // mocha, rspec-like pattern
32+
'**/__tests__/**', // jest pattern
33+
'**/__mocks__/**', // jest pattern
34+
'test.{js,jsx}', // repos with a single test file
35+
'test-*.{js,jsx}', // repos with multiple top-level test files
36+
'**/*.{test,spec}.{js,jsx}', // tests where the extension denotes that it is a test
37+
'**/jest.config.js', // jest config
38+
'**/webpack.config.js', // webpack config
39+
'**/webpack.config.*.js', // webpack config
40+
'**/rollup.config.js', // rollup config
41+
'**/rollup.config.*.js', // rollup config
42+
'**/gulpfile.js', // gulp config
43+
'**/gulpfile.*.js', // gulp config
44+
'**/Gruntfile{,.js}', // grunt config
45+
'**/protractor.conf.js', // protractor config
46+
'**/protractor.conf.*.js', // protractor config
47+
],
48+
optionalDependencies: false,
49+
}],
2550
}
2651
};

__mocks__/fs-extra-promise.js

+220
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
// Mock specific functions of fs-extra-promise module
2+
const path = require('path');
3+
const { fs, vol } = require('memfs');
4+
5+
/**
6+
* Utils
7+
*/
8+
9+
/**
10+
* Remove directory recursively
11+
* @param {string} dirPath
12+
* @see https://stackoverflow.com/a/42505874/3027390
13+
*/
14+
function rimraf(dirPath) {
15+
if (fs.existsSync(dirPath)) {
16+
fs.readdirSync(dirPath).forEach((entry) => {
17+
const entryPath = path.join(dirPath, entry);
18+
if (fs.lstatSync(entryPath).isDirectory()) {
19+
rimraf(entryPath);
20+
} else {
21+
fs.unlinkSync(entryPath);
22+
}
23+
});
24+
fs.rmdirSync(dirPath);
25+
}
26+
}
27+
28+
/**
29+
* Iterativelts creates directories to the file or directory
30+
* @param pathArg
31+
*/
32+
function createDir(pathArg) {
33+
const { dir, ext } = path.parse(pathArg);
34+
const dirNames = (ext === '')
35+
? pathArg.split(path.sep)
36+
: dir.split(pathArg.sep);
37+
38+
dirNames.reduce((accumDir, currentdir) => {
39+
const jointDir = path.join(accumDir, currentdir);
40+
if (!fs.existsSync(jointDir)) {
41+
fs.mkdirSync(jointDir);
42+
}
43+
return jointDir;
44+
}, '');
45+
}
46+
47+
/**
48+
* Mocking fs#copyFileSync (not implemented in memfs)
49+
*/
50+
function copyFileSync(src, dest) {
51+
if (!fs.lstatSync(src).isFile()) {
52+
throw new Error(`copyFileSync expected file but got: ${src}`);
53+
}
54+
fs.writeFileSync(dest, fs.readFileSync(src));
55+
}
56+
57+
/**
58+
* Utility function to copy a directory to a destination recursively
59+
*/
60+
function copyDirSync(src, dest) {
61+
if (fs.lstatSync(src).isDirectory()) {
62+
const files = fs.readdirSync(src);
63+
files.forEach((file) => {
64+
const curSource = path.join(src, file);
65+
const curDest = path.join(dest, file);
66+
if (fs.lstatSync(curSource).isDirectory()) {
67+
if (!fs.existsSync(curDest)) {
68+
createDir(curDest);
69+
}
70+
copyDirSync(curSource, curDest);
71+
} else {
72+
copyFileSync(curSource, curDest);
73+
}
74+
});
75+
}
76+
}
77+
78+
/**
79+
* Mocks
80+
*/
81+
82+
/**
83+
* Mocking fs-extra#outputFileSync
84+
*/
85+
fs.outputFileSync = (file, data) => {
86+
createDir(file);
87+
fs.writeFileSync(file, data);
88+
};
89+
90+
/**
91+
* Mocking fs-extra#emptydirSync
92+
*/
93+
fs.emptydirSync = (dir) => {
94+
if (!fs.existsSync(dir)) {
95+
createDir(dir);
96+
} else {
97+
rimraf(dir);
98+
}
99+
};
100+
101+
/**
102+
* Mocking fs-extra#copySync
103+
*/
104+
fs.copySync = (src, dest) => {
105+
if (fs.lstatSync(src).isDirectory()) {
106+
copyDirSync(src, dest);
107+
} else {
108+
copyFileSync(src, dest);
109+
}
110+
};
111+
112+
/**
113+
* Mocking fs-extra#readJsonSync
114+
*/
115+
fs.readJsonSync = filePath => JSON.parse(fs.readFileSync(filePath, 'utf8'));
116+
117+
118+
/**
119+
* Mocking fs-extra#outputJsonSync
120+
*/
121+
fs.outputJsonSync = (file, jsonData) => {
122+
fs.outputFileSync(file, JSON.stringify(jsonData));
123+
};
124+
125+
/**
126+
* Mocking fs-extra-promise#removeAsync
127+
*/
128+
fs.removeAsync = pathArg => new Promise((resolve, reject) => {
129+
try {
130+
if (fs.lstatSync(pathArg).isDirectory()) {
131+
rimraf(pathArg);
132+
} else {
133+
fs.unlinkSync(pathArg);
134+
}
135+
resolve();
136+
} catch (err) {
137+
reject(err);
138+
}
139+
});
140+
141+
/**
142+
* Mocking fs-extra-promise#copyAsync
143+
*/
144+
fs.copyAsync = (src, dest) => new Promise((resolve, reject) => {
145+
try {
146+
fs.copySync(src, dest);
147+
resolve();
148+
} catch (err) {
149+
reject(err);
150+
}
151+
});
152+
153+
/**
154+
* Mocking fs-extra-promise#accessAsync
155+
*/
156+
fs.accessAsync = pathArg => new Promise((resolve, reject) => {
157+
try {
158+
fs.accessSync(pathArg);
159+
resolve();
160+
} catch (err) {
161+
reject(err);
162+
}
163+
});
164+
165+
/**
166+
* Mocking fs-extra-promise#outputFileAsync
167+
*/
168+
fs.outputFileAsync = (file, data) => new Promise((resolve, reject) => {
169+
try {
170+
fs.outputFileSync(file, data);
171+
resolve();
172+
} catch (err) {
173+
reject(err);
174+
}
175+
});
176+
177+
/**
178+
* Mocking fs-extra-promise#mkdirp
179+
*/
180+
fs.mkdirp = dir => new Promise((resolve) => {
181+
createDir(dir);
182+
resolve();
183+
});
184+
185+
/**
186+
* Mocking fs-extra#copySync
187+
*/
188+
fs.copySync = (src, dest) => {
189+
if (fs.lstatSync(src).isDirectory()) {
190+
copyDirSync(src, dest);
191+
} else {
192+
copyFileSync(src, dest);
193+
}
194+
};
195+
196+
/**
197+
* Mocking fs-extra-promise#outputJsonAsync
198+
*/
199+
fs.outputJsonAsync = (file, jsonData) => new Promise((resolve, reject) => {
200+
try {
201+
fs.outputJsonSync(file, jsonData);
202+
resolve();
203+
} catch (err) {
204+
reject(err);
205+
}
206+
});
207+
208+
/**
209+
* Mocking fs-extra-promise#readJsonAsync
210+
*/
211+
fs.readJsonAsync = filePath => new Promise((resolve, reject) => {
212+
try {
213+
resolve(fs.readJsonSync(filePath));
214+
} catch (err) {
215+
reject(err);
216+
}
217+
});
218+
219+
fs.vol = vol;
220+
module.exports = fs;

__mocks__/fs.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('memfs');

__mocks__/gh-pages.js

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// spy on gh-pages
2+
3+
const ghpages = {};
4+
5+
ghpages.publish = (dir, options, callback) => {
6+
// record arguments
7+
ghpages.dir = dir;
8+
ghpages.options = options;
9+
callback();
10+
};
11+
12+
module.exports = ghpages;

0 commit comments

Comments
 (0)