Created
May 4, 2013 07:48
-
-
Save luislee818/5516702 to your computer and use it in GitHub Desktop.
Simple command line interface in Node.js for Evernote's code challenges on InterviewStreet, below is an example for the CircularBuffer challenge. For some reason it does not work on InterviewStreet, not sure why.
This file contains hidden or 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
var CommandInterpreter, | |
AppendCommand; | |
CommandInterpreter = function () { | |
}; | |
CommandInterpreter.prototype.reset = function () { | |
}; | |
CommandInterpreter.prototype.parse = function (input) { | |
var regex = /([ARQL])\s?(\d*)/, | |
matchResult, | |
action, | |
argument, | |
command; | |
if (this.pendingCommand !== undefined) { | |
this.pendingCommand.addArgument(input); | |
return this.pendingCommand; | |
} | |
matchResult = input.toString().match(regex); | |
if (matchResult === null) { | |
// create SaveCapacityCommand | |
command = { | |
canExecute: true | |
}; | |
} | |
else { | |
action = matchResult[1]; | |
argument = matchResult[2]; | |
if (action === 'A') { | |
// create AppendCommand | |
command = new AppendCommand(parseInt(argument, 10)); | |
} | |
if (action === 'R') { | |
// create RemoveCommand | |
command = { | |
canExecute: true, | |
argument: parseInt(argument, 10) | |
}; | |
} | |
if (action === 'L') { | |
// create ListCommand | |
command = { | |
canExecute: true | |
}; | |
} | |
if (action === 'Q') { | |
// create QuitCommand | |
command = { | |
canExecute: true | |
}; | |
} | |
} | |
return command; | |
}; | |
CommandInterpreter.prototype.execute = function (command) { | |
if (command.canExecute) { | |
command.execute(); | |
delete this.pendingCommand; | |
} | |
else { | |
this.pendingCommand = command; | |
} | |
}; | |
// note: commands not fully implemented | |
AppendCommand = function (pendingArguments) { | |
this.pendingArguments = pendingArguments; | |
this.canExecute = false; | |
this.args = []; | |
}; | |
AppendCommand.prototype.addArgument = function (argument) { | |
this.args.push(argument); | |
this.pendingArguments -= 1; | |
this.canExecute = (this.pendingArguments === 0); | |
}; | |
module.exports = { | |
CommandInterpreter: CommandInterpreter, | |
AppendCommand: AppendCommand | |
}; |
This file contains hidden or 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
var CommandInterpreter = require('./command_interpreter').CommandInterpreter, | |
AppendCommand = require('./command_interpreter').AppendCommand; | |
describe("CommandInterpreter", function () { | |
var interpreter; | |
beforeEach(function () { | |
interpreter = new CommandInterpreter(); | |
}); | |
describe("parse", function () { | |
beforeEach(function () { | |
interpreter.reset(); | |
}); | |
describe("no pending command", function () { | |
// SaveCapacityCommand | |
describe("passed in an integer", function () { | |
var command; | |
beforeEach(function () { | |
command = interpreter.parse(10); | |
}); | |
it("command should have canExecute return true", function () { | |
expect(command.canExecute).toBeTruthy(); | |
}); | |
}); | |
// AppendCommand | |
describe("passed in A [Integer]", function () { | |
var command; | |
beforeEach(function () { | |
command = interpreter.parse('A 3'); | |
}); | |
it("should return a command has canExecute be false", function () { | |
expect(command.canExecute).toBeFalsy(); | |
}); | |
it("should return a command has pending arguments be the Integer passed in", function () { | |
expect(command.pendingArguments).toEqual(3); | |
}); | |
}); | |
// RemoveCommand | |
describe("passed in R [Integer]", function () { | |
var command; | |
beforeEach(function () { | |
command = interpreter.parse('R 3'); | |
}); | |
it("should return a command has canExecute be true", function () { | |
expect(command.canExecute).toBeTruthy(); | |
}); | |
it("should return a command has pending arguments be the Integer passed in", function () { | |
expect(command.argument).toEqual(3); | |
}); | |
}); | |
// ListCommand | |
describe("passed in L", function () { | |
var command; | |
beforeEach(function () { | |
command = interpreter.parse('L'); | |
}); | |
it("should return a command has canExecute be true", function () { | |
expect(command.canExecute).toBeTruthy(); | |
}); | |
}); | |
// QuitCommand | |
describe("passed in Q", function () { | |
var command; | |
beforeEach(function () { | |
command = interpreter.parse('Q'); | |
}); | |
it("should return a command has canExecute be true", function () { | |
expect(command.canExecute).toBeTruthy(); | |
}); | |
}); | |
}); | |
describe("with pending command", function () { | |
describe("passed in input", function () { | |
var command; | |
beforeEach(function () { | |
interpreter.pendingCommand = { | |
addArgument: function () {} | |
}; | |
spyOn(interpreter.pendingCommand, "addArgument"); | |
command = interpreter.parse('foo bar'); | |
}); | |
it("should invoke addArgument on pending command", function () { | |
expect(interpreter.pendingCommand.addArgument).toHaveBeenCalledWith('foo bar'); | |
}); | |
it("should return the command same as pending command", function() { | |
expect(command).toEqual(interpreter.pendingCommand); | |
}); | |
}); | |
}); | |
}); | |
describe("execute", function () { | |
describe("when command can be executed", function () { | |
var command; | |
beforeEach(function () { | |
command = { | |
canExecute: true, | |
execute: function () {} | |
}; | |
spyOn(command, "execute"); | |
interpreter.pendingCommand = {}; | |
interpreter.execute(command); | |
}); | |
it("should invoke execute on the command", function () { | |
expect(command.execute).toHaveBeenCalled(); | |
}); | |
it("should clear pending command", function () { | |
expect(interpreter.pendingCommand).not.toBeDefined(); | |
}); | |
}); | |
describe("when command cannot be executed", function () { | |
var command; | |
beforeEach(function () { | |
command = { | |
canExecute: false, | |
execute: function () {} | |
}; | |
spyOn(command, "execute"); | |
interpreter.execute(command); | |
}); | |
it("should not invoke execute on the command", function () { | |
expect(command.execute).not.toHaveBeenCalled(); | |
}); | |
it("should add command as pending command", function() { | |
expect(interpreter.pendingCommand).toEqual(command); | |
}); | |
}); | |
}); | |
describe("AppendCommand", function () { | |
var command; | |
describe("when initialized", function () { | |
beforeEach(function () { | |
command = new AppendCommand(3); | |
}); | |
it("should set canExecute to false", function () { | |
expect(command.canExecute).toBeFalsy(); | |
}); | |
it("should set pendingArguments to the number passed in", function() { | |
}); | |
}); | |
describe("when arguments had been added but not complete", function () { | |
beforeEach(function () { | |
command = new AppendCommand(3); | |
command.addArgument('foo'); | |
command.addArgument('bar'); | |
}); | |
it("should return canExecute as false", function () { | |
expect(command.canExecute).toBeFalsy(); | |
}); | |
it("should descrease pendingArguments", function() { | |
expect(command.pendingArguments).toEqual(1); | |
}); | |
}); | |
describe("when all arguments had been added", function () { | |
beforeEach(function () { | |
command = new AppendCommand(3); | |
command.addArgument('foo'); | |
command.addArgument('bar'); | |
command.addArgument('baz'); | |
}); | |
it("should return canExecute as true", function () { | |
expect(command.canExecute).toBeTruthy(); | |
}); | |
}); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment