Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
var chokidar = require('chokidar');
var fs = require('fs')
var path = require('path')
var testFileExtension = 'spec.js'
var ignorefile = [/[\/\\]\./, 'package.json', 'node_modules', 'watcher.js'];
/**
* @getTemplate A function to get Tempate content for new test file
* @filename It just take on argument that is file
* @returns : string
**/
function getModuleTemplate(filename) {
return `var assert = require('chai').assert;
describe('${filename} modules', function() {
});`
}
/**
* @param { String } functionName name of the function for Tempate
* @returns { String } Tempate String
**/
function getTestTemplate(filename) {
return `
describe('${filename} function', function() {
});`
}
/**
* @createTestFile A function that create the test file with Tempate string
* @filepath : first argument for file path
* @callback : It's callback that call after file created
**/
function createTestFile(filepath = '', callback) {
let basename = path.basename(filepath, '.js')
filepath = getTestFilePath(filepath)
if (!fs.existsSync(filepath)) {
fs.writeFile(filepath, getModuleTemplate(basename), 'utf8', function (err) {
if (err) {
callback(err, null)
}
callback(null, filepath)
});
}
}
/**
* @function : isTestFile function for check filepath is test file path or a simple js file path
* @filepath : Simple file path
* @returns : boolean
**/
function isTestFile(filepath = '') {
let index = path.basename(filepath).indexOf(testFileExtension) !== -1 ? true : false;
return index
}
/**
* @function : isTestFile function for check filepath is js file path or not
* @filepath : Simple file path
* @returns : boolean
**/
function isJsFile(filepath = '') {
let extension = path.extname(filepath)
return ('.js' === extension)
}
/**
* @function : isAbsolutePath function for check filepath is absolute file path or not
* @filepath : Simple file path
* @returns : boolean
**/
function isAbsolutePath(filepath = '') {
return path.isAbsolute(filepath)
}
/**
* @function : getWatcher function that returns object of file and directory watcher
* @ignorefile : array => Array of file and folder name that we wish to ignored from watch
* @returns : object
**/
function getWatcher(ignorefile) {
return chokidar.watch('.', {
ignored: ignorefile,
persistent: true
});
}
/**
* @param {String} filepath is name of the file
* @returns {String} Name of the test file name
**/
function getTestFilePath(filepath = '') {
let dirname = path.dirname(filepath) !== '.' ? '/' + path.dirname(filepath) + '/' : '/'
let basename = path.basename(filepath, '.js')
filepath = __dirname + dirname + basename + testFileExtension
return filepath
}
/**
* @param {buffer} Buffer from where need to get function name List
* @returns {Array} Array of function names
**/
function getFunNames(fileBuffer) {
var bufferLength = fileBuffer.length
var funNameArray = []
var ifFunction = ''
var functionName = ''
var word = 'function'
for (let i = 0; i < bufferLength; i++) {
if (word.indexOf(ifFunction) == -1 || fileBuffer[i] == 10) {
ifFunction = ''
}
else if (word == ifFunction) {
if (fileBuffer[i] != 8 && fileBuffer[i] != 9 && fileBuffer[i] != 10 && fileBuffer[i] != 11 && fileBuffer[i] != 32 && fileBuffer[i] != 40) {
functionName = functionName + String.fromCharCode(fileBuffer[i])
}
else if (fileBuffer[i] == 40) {
funNameArray.push(functionName);
functionName = ''
ifFunction = ''
}
}
else {
ifFunction = ifFunction + String.fromCharCode(fileBuffer[i])
}
}
return funNameArray
}
/**
* function Descption : Just insert the test Tempate for function
* @param { String } testFilePath File path to which we need to insert Tempate
* @param { String } functionName Name of the function for Tempate
**/
function insertTestTemplate(testFilePath = '', functionName = '') {
testFilePath = getTestFilePath(testFilePath)
let fileContent = fs.readFileSync(testFilePath, 'utf8')
let index = fileContent.indexOf('{');
let firstpart = fileContent.slice(0, index + 1)
let lastpart = fileContent.slice(index + 1)
let newContent = firstpart + getTestTemplate(functionName) + lastpart
fs.writeFileSync(testFilePath, newContent, 'utf-8');
}
/**
* function Descption : Just insert the test Tempate for function
* @param { String } testFilePath File path to which we need to insert Tempate
* @param { String } content to be written to the file
**/
function insertTestCases(testFilePath = '', content) {
testFilePath = getTestFilePath(testFilePath)
let fileContent = fs.readFileSync(testFilePath, 'utf8')
let index = fileContent.indexOf('{');
let firstpart = fileContent.slice(0, index + 1)
let lastpart = fileContent.slice(index + 1)
let newContent = firstpart + content + lastpart
fs.writeFileSync(testFilePath, newContent, 'utf-8');
}
/**
* @param { String } testFilePath File path to which we need to insert Tempate
* @param { String } functionName Name of the function for Tempate
* @returns { boolean } true if exist false if not
**/
function isTestExistFor(testFilePath = '', functionName = '') {
testFilePath = getTestFilePath(testFilePath)
let fileContent = fs.readFileSync(testFilePath, 'utf8')
let templateToSearch = `describe('${functionName} function', function() {`
let index = fileContent.indexOf(templateToSearch) == -1 ? false : true;
return index
}
/**
* @call : call getWatcher function
**/
watcher = getWatcher(ignorefile);
/**
* Add Lister to the wath object
**/
watcher
.on('add', path => {
let created;
if (isJsFile(path) && !isTestFile(path)) {
createTestFile(path, (err, path) => {
if (err) {
console.log("sorry we cought an error" + err)
}
console.log("File :" + path + " created")
})
}
})
.on('change', (path, stats) => {
if (isJsFile(path) && !isTestFile(path)) {
var funcNameList = [];
var myReadStream = fs.createReadStream(path)
myReadStream.on('data', fileBuffer => {
var names = getFunNames(fileBuffer)
names.forEach(name => {
if (funcNameList.indexOf(name) == -1)
funcNameList.push(name)
})
})
myReadStream.on('close', () => {
funcNameList.forEach(names => {
if (!isTestExistFor(path, names))
insertTestTemplate(path, names)
})
})
}
})
.on('unlink', path => {
console.log(`File ${path} has been removed`)
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.