Created
September 22, 2015 07:13
-
-
Save gnerkus/fe1d7fc34c5abe694cdd to your computer and use it in GitHub Desktop.
Verify object instance has instance attributes defined using Esprima
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This file is to executed in a Nodejs environment. | |
// `node constructor_check.js` | |
'use strict'; | |
// You'll need to install the 'esprima', 'estraverse' and 'lodash' modules via npm. | |
var esprima = require('esprima'); | |
var estraverse = require('estraverse'); | |
var fs = require('fs'); | |
var path = require('path'); | |
var _ = require('lodash'); | |
// Define a 'solution.js' file in the same directory as this file. | |
var filename = path.resolve() + "/solution.js"; | |
console.log('Processing', filename); | |
var ast = esprima.parse(fs.readFileSync(filename)); | |
// This is the list of parameters that must be defined in the constructor function. | |
var parameterList = ['firstName', 'lastName', 'age', 'profession', 'company']; | |
// Test the constructor defined in 'solution.js' | |
verifyConstructor(ast, 'Person', parameterList); | |
// Verify the variable defined is a Constructor. | |
function verifyConstructor(ast, variableName, parameterList) { | |
// Maintain a count of all the 'Person' functions in the source file. | |
var functionCount = 0; | |
// Look for functions with the identifier 'Person' while traversing the AST. | |
estraverse.traverse(ast, { | |
enter: function (node) { | |
if (isFunctionExpression(node) && isCorrectVariable(node, variableName)) { | |
functionCount += 1; | |
console.log(areParametersAssigned(node.init.body, parameterList)); | |
} | |
} | |
}); | |
if (functionCount === 0) { | |
return 'The `Person` constructor has not been defined yet.'; | |
} | |
} | |
// Verify the node represents a function. | |
function isFunctionExpression (node) { | |
return node.type === 'VariableDeclarator' && node.init.type === 'FunctionExpression'; | |
} | |
// Verify the node has the correct name. | |
function isCorrectVariable (node, variableName) { | |
return node.id.name === variableName; | |
} | |
// Verify a function has all the correct parameters defined. | |
function hasParameters (node, parameterList) { | |
var missingParameters = _.difference(_.pluck(node.init.params, 'name'), parameterList); | |
return _.eq(_.pluck(node.init.params, 'name'), parameterList) || 'You have not defined the parameters ' + missingParameters.join(' ') + 'for the Person constructor.'; | |
} | |
// Verify all parameters in the functioned are assigned to a property. | |
function areParametersAssigned (functionNode, parameterList) { | |
var memberValues = []; | |
var refToThis = 0; | |
_.forEach(functionNode.body, function (expression) { | |
memberValues.push(expression.expression.right.name); | |
if (expression.expression.left.object.type === 'ThisExpression') { | |
refToThis += 1; | |
} | |
}); | |
return _.eq(memberValues, parameterList) && refToThis === parameterList.length; | |
} | |
function getExpressionStatements (functionNode) { | |
return functionNode.init.body.body[1].expression.right; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 'use strict'; | |
var Person = function (firstName, lastName, age, profession, company) { | |
this.firstName = firstName; | |
this.lastName = lastName; | |
this.age = age; | |
this.profession = profession; | |
this.company = company; | |
}; | |
Person.prototype.getFullName = function () { | |
return this.firstName + ' ' + this.lastName + '.'; | |
}; | |
Person.prototype.getOccupation = function () { | |
return this.firstName + ' ' + this.lastName + ' is a ' + this.profession + ' at ' + this.company + '.'; | |
}; | |
Person.prototype.setOccupation = function (newOccupation) { | |
this.occupation = newOccupation; | |
}; | |
Person.prototype.toString = function () { | |
return this.firstName + ' ' + this.lastName + ' is ' + this.age + ' years old and works as a ' + this.profession + ' at ' + this.company + '.'; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment