diff --git a/map/map.spec.js b/map/map.spec.js index a1bb0a3..18386f8 100644 --- a/map/map.spec.js +++ b/map/map.spec.js @@ -19,3 +19,81 @@ function randomString(len) { // DO NOT CHANGE ANYTHING ABOVE THIS LINE // Add your tests below +describe('makeMap structure', function(){ + it('defines a variable makeMap', function(){ + expect(function() { makeMap; }).to.not.throw(Error); + }); + it('actually defines a function', function(){ + expect(makeMap).to.be.a('function'); + }); + +}); + +describe('Your code for makeMap methods', function(){ + var k1,v1,k2,v2,map; + beforeEach(function() { + map = makeMap(); + k1 = randomString(); + k2 = randomString(); + v1 = Math.random(); + v2 = Math.random(); + }); + it('map is empty upon creation & has returns false', function(){ + expect(map.has()).to.be.equal(false); + }); + it('returns an object with methods has, lookup, add, update, remove', function() { + ['has', 'lookup', 'add', 'update', 'remove'].forEach(function(key) { + expect(map[key]).to.be.a('function'); + }); + }); + it('has function returns bool', function() { + expect(map.has()).to.be.a('boolean'); + }); + it('add returns the map & has returns true', function(){ + expect(map.add(k1,v1)).to.equal(map); + expect(map.has(k1)).to.be.equal(true); + }); + it('add returns error when key already exists in the map', function(){ + map.add(k1,v1); + expect(function(){ + map.add(k1,v1); + }).to.throw(Error); + }); + it('lookup returns value, ', function(){ + map.add(k1,v1); + expect(map.lookup(k1)).to.be.equal(v1); + expect(function(){ + map.lookup(k2); + }).to.throw(Error); + }); + it('lookup throws error for missing key', function(){ + map.add(k1,v1); + expect(function(){ + map.lookup(k2); + }).to.throw(Error); + }); + it('lookup throws error for missing key & has returns false after remove', function(){ + map.add(k1,v1); + map.add(k2,v2); + map.remove(k2); + expect(map.has(k2)).to.equal(false); + expect(function(){ + map.lookup(k2); + }).to.throw(Error); + }); + it('remove throws error when given key does not exist', function(){ + expect(function(){ + map.remove(k1); + }).to.throw(Error); + }); + it('update throws error if key is missing', function(){ + expect(function(){ + map.update(v1); + }).to.throw(Error); + }); + it('update changes value of key', function(){ + map.add(k1,v1); + map.update(k1,v2); + expect(map.lookup(k1)).to.equal(v2); + }); +}); diff --git a/map/mapCode.js b/map/mapCode.js index e0867e9..50d440d 100644 --- a/map/mapCode.js +++ b/map/mapCode.js @@ -1,24 +1,73 @@ /* - * Name 1: YourNameHere - * Name 2: YourNameHere + * Name 1: Edwin Nartey + * Name 2: Dakota McCoy */ // Do not change the name of this function var makeMap = function() { // All your code will go inside this function // This object should contain the methods you want to expose: - var o; + var o = { + has : function has(key){ + if (storedPairs.hasOwnProperty(key)) { + return true; + } + return false; + }, + lookup : function lookup(key){ + if(storedPairs.hasOwnProperty(key)){ + return storedPairs[key]; + } else { + throw new Error("Invalid Lookup: " + key +" not in Map"); + } + }, + add : function add(key,value){ + if(o.has(key)){ + throw new Error("Map already contains" + key) + } else { + storedPairs[key] = value; + return o; + } + }, + update : function update(key,value){ + if(storedPairs.hasOwnProperty(key)){ + storedPairs[key] = value; + } else { + throw new Error("Invalid Update: "+ key + "not in Map"); + } + return o; + }, + remove : function remove(key){ + if(storedPairs.hasOwnProperty(key)){ + delete storedPairs[key]; + } else { + throw new Error("Invalid Delete Attempted." + key + " not in Map" ); + } + } + }; + // Use this object to store the key-value pairs: - var storedPairs; + var storedPairs = {}; // Add initialization code here + var hasOwnProperty = Object.prototype.hasOwnProperty;; // Add local functions here - + /* + function isEmpty(storedPairs) { + if (storedPairs == null) return true; + if (storedPairs.length > 0) return false; + if (storedPairs.length === 0) return true; + for (var key in storedPairs) { + if (hasOwnProperty.call(storedPairs, key)) return false; + } + return true; + }; + */ // Prepare the object o before returning it return o; -} +}; // Do NOT change anything below this line. diff --git a/tests.spec.js b/tests.spec.js index deabffb..37d4c7c 100644 --- a/tests.spec.js +++ b/tests.spec.js @@ -8,3 +8,85 @@ try { } catch (e) {} // Do not change anything above this line + +describe('Your code for stacks', function() { + it('defines a variable makeStack', function() { + expect(function() { makeStack; }).to.not.throw(Error); + }); + // Add more "it" sections below + it('actually defines a function makeStack', function() { + expect(makeStack).to.be.a('function'); + }); +}); + +describe('Your makeStack function', function() { + var stack = makeStack(); + it('returns an object', function() { + expect(stack).to.be.a('object'); + }); + it('returns an object with methods push, pop and isEmpty', function() { + ['push', 'pop', 'isEmpty'].forEach(function(key) { + expect(stack[key]).to.be.a('function'); + }); + }); +}); + +describe('Stack methods:', function() { + var stack; + beforeEach(function() { + // This ensures every test sees a fresh empty stack + stack = makeStack(); + }); + it('isEmpty returns true for a new stack', function() { + expect(stack.isEmpty()).to.equal(true); + }); + it('isEmpty returns false if an element is pushed', function() { + stack.push(2); + expect(stack.isEmpty()).to.equal(false); + }); + it('push returns the stack object', function() { + expect(stack.push()).to.equal(stack); + }); + it('pop should error on empty stack', function() { + expect(function() { stack.pop(); }).to.throw(Error); + }); + it('pop should not error on nonempty stack', function() { + stack.push(2); + expect(function() { stack.pop(); }).to.not.throw(Error); + }); + it('a pop following a push should return the pushed element', function() { + // we generate a random number to use as element. + var v = Math.random(); + stack.push(v); + expect(stack.pop()).to.equal(v); + }); + it('consecutive pops return elements in reverse order to the pushes', function() { + var v1 = Math.random(), v2 = Math.random(); + stack.push(v1); + stack.push(v2); + expect(stack.pop()).to.equal(v2); + expect(stack.pop()).to.equal(v1); + }); + it('a randomized set of pushes and pops should behave properly', function() { + var iters = 10, steps = 200, iter, step; + var noItems, randomNum; + for (iter = 0; iter < 10; iter += 1) { + stack = makeStack(); + randomNum = Math.random(); + noItems = 0; + for (step = 0; step < 200; step += 1) { + if (Math.random() > 0.5) { // 50-50 do a push + noItems += 1; + stack.push(noItems + randomNum); + } else { // or do a pop + if (noItems === 0) { + expect(function() { stack.pop(); }).to.throw(Error); + } else { + expect(stack.pop()).to.equal(noItems + randomNum); + noItems -= 1; + } + } + } + } + }); +}); \ No newline at end of file diff --git a/yourCode.js b/yourCode.js index 1499c23..6bda9b8 100644 --- a/yourCode.js +++ b/yourCode.js @@ -1,12 +1,29 @@ /* - * Name 1: YourNameHere - * Name 2: YourNameHere + * Name 1: Edwin + * Name 2: Dakota */ // All your code will go here -var makeStack = function() { - -}; +function makeStack() { + var values = []; + var stack = { + push: function push(el) { + values.push(el); + return stack; + }, + pop: function pop() { + if (stack.isEmpty()) { + throw new Error("Attempt to pop from empty stack"); + } else { + return values.pop(); + } + }, + isEmpty: function isEmpty() { + return values.length === 0; + } + }; + return stack; +} // Do NOT change anything below this line.