-
Notifications
You must be signed in to change notification settings - Fork 63
/
Copy pathgenerate.js
executable file
·122 lines (97 loc) · 2.98 KB
/
generate.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
117
118
119
120
121
122
/**
* Script to generate Coderbyte file templates
*
* Example: `node generate.js easy/ab_check`
*
* This will generate easy/ab_check.js and easy/ab_check.test.js as blank
* templates.
*
* Bradley Hanson ([email protected])
*/
'use strict';
const fs = require('fs');
const path = require('path');
const selfName = path.basename(process.argv[1]); // e.g., generate.js
// Usage: node generate.js <file_name>
enforceCommandLineUsage(); // or exit
const fileName = path.basename(process.argv[2]); // e.g., ab_check
const filePath = path.dirname(process.argv[2]);
enforceSnakeCase(); // or exit
let fileNameCamelCase = snakeToCamelCase(fileName);
let codeFileContent = getCodeFileContent();
let testFileContent = getTestFileContent();
let codeFileName = path.join(filePath, fileName) + '.js';
let testFileName = path.join(filePath, fileName) + '.test.js';
checkForExistingFiles(codeFileName, testFileName); // or exit
writeFile(codeFileName, codeFileContent);
writeFile(testFileName, testFileContent);
/**
* Functions below
*/
// Enforce proper command line usage with exactly 1 parameter
function enforceCommandLineUsage() {
if (process.argv.length !== 3) {
console.error('Usage: node %s <file_name>', selfName);
// https://nodejs.org/api/process.html#process_process_exit_code
// https://nodejs.org/api/process.html#process_exit_codes
// A bit better to set exit code and let program exit naturally
process.exit(9);
}
}
// Enforce snake_case
function enforceSnakeCase() {
let snakeCaseRegEx = /^[a-z]+[_a-z0-9]*[a-z0-9]+$/;
if (!snakeCaseRegEx.test(fileName)) {
console.error(
'Usage: node %s <file_name>\n <file_name>: must be in snake_case',
selfName
);
process.exit(9);
}
}
function snakeToCamelCase(str) {
str = String(str);
let camelCase = str.replace(/[_]([a-z])/g, (_, letter) =>
letter.toUpperCase()
);
return camelCase;
}
function getCodeFileContent() {
let content = `/**
*
* @param {type} param
* @return {type}
*/
function ${fileNameCamelCase}(param) {
}
module.exports = ${fileNameCamelCase};`;
return content;
}
function getTestFileContent() {
let content = `const ${fileNameCamelCase} = require('./${fileName}');
describe('${fileNameCamelCase}()', () => {
test('', () => {
expect(${fileNameCamelCase}()).toBe();
});
});`;
return content;
}
function checkForExistingFiles(...files) {
const existingFiles = files.filter(file => fs.existsSync(file));
if (existingFiles.length > 0) {
const fileString = existingFiles.map(str => ' ' + str).join('\n');
console.error(
'Files already exist:\n%s\n\nAborting... nothing modified.',
fileString
);
process.exit(9);
}
}
function writeFile(fileName, fileContent) {
fs.writeFile(fileName, fileContent, error => {
if (error) {
throw error;
}
console.log('Generated %s', fileName);
});
}