From 5bbd68c77a78863253e0754273d612f15975fec8 Mon Sep 17 00:00:00 2001 From: Harvey Sanders Date: Thu, 28 Jun 2018 15:08:52 -0500 Subject: [PATCH 01/36] (chore) Pend non required tests --- SpecRunner.html | 2 +- spec/part1.js | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/SpecRunner.html b/SpecRunner.html index 412a86e39..5a18ca964 100644 --- a/SpecRunner.html +++ b/SpecRunner.html @@ -29,7 +29,7 @@ }); - + diff --git a/spec/part1.js b/spec/part1.js index 72360c485..f2ec9ba33 100755 --- a/spec/part1.js +++ b/spec/part1.js @@ -84,7 +84,7 @@ - describe('3. Sum Integers in Array', function() { + xdescribe('3. Sum Integers in Array', function() { it('should return a number', function() { expect(typeof(arraySum([[1],[2,3],[[4]],5,6]))).to.eql('number'); @@ -402,7 +402,7 @@ - describe('11. Modulo', function() { + xdescribe('11. Modulo', function() { it('should return a number', function() { expect(typeof(modulo(5,2))).to.equal('number'); @@ -476,7 +476,7 @@ - describe('13. Divide', function() { + xdescribe('13. Divide', function() { it('should return a number', function() { expect(typeof(divide(5,2))).to.equal('number'); @@ -512,7 +512,7 @@ - describe('14. Greatest Common Divisor', function() { + xdescribe('14. Greatest Common Divisor', function() { it('should return a number', function() { expect(typeof(gcd(4,36))).to.equal('number'); @@ -726,7 +726,7 @@ - describe('21. Count key in object', function() { + xdescribe('21. Count key in object', function() { var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; it('should return a number', function() { @@ -756,7 +756,7 @@ - describe('22. Count value in object', function() { + xdescribe('22. Count value in object', function() { var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; it('should return a number', function() { @@ -786,7 +786,7 @@ - describe('23. Replace keys in object', function() { + xdescribe('23. Replace keys in object', function() { var tallyKeys = function(obj) { var count = 0; @@ -850,7 +850,7 @@ }); - describe('24. First n Fibonacci', function() { + xdescribe('24. First n Fibonacci', function() { it('should return an array', function() { expect(Array.isArray(fibonacci(5))).to.equal(true); @@ -961,7 +961,7 @@ - describe('28. Sum even numbers in nested objects', function() { + xdescribe('28. Sum even numbers in nested objects', function() { var obj = { a: 2, b: {b: 2, bb: {b: 3, bb: {b: 2}}}, @@ -990,7 +990,7 @@ - describe('29. Flatten nested arrays', function() { + xdescribe('29. Flatten nested arrays', function() { it('should return an array', function() { expect(Array.isArray(flatten([1,[2],[3,[[4]]],5]))).to.equal(true); @@ -1073,7 +1073,7 @@ - describe('32. Augment each element in nested arrays', function() { + xdescribe('32. Augment each element in nested arrays', function() { it('should return an array', function() { expect(Array.isArray(augmentElements([[],[3],[7]], 5))).to.equal(true); @@ -1147,7 +1147,7 @@ - describe('35. Convert numbers to text', function() { + xdescribe('35. Convert numbers to text', function() { it('should return a string', function() { expect(typeof(numToText("I have 5 dogs and 6 ponies"))).to.equal('string'); From 3f131bda6294879d1b8eb2843aa9c7f300690f5f Mon Sep 17 00:00:00 2001 From: Jay Kindell Date: Mon, 10 Sep 2018 12:14:01 -0500 Subject: [PATCH 02/36] adds gitignore & package.json --- .gitignore | 1 + package.json | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 .gitignore create mode 100644 package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..b512c09d4 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 000000000..4e6ef9dbc --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "name": "recursion-prompts", + "version": "1.0.0", + "description": "Recursion Practice", + "main": "index.js", + "directories": { + "lib": "lib", + "test": "test" + }, + "scripts": { + "pretest": "npm install", + "test": "mocha ./test || :" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/OperationSpark/recursion-prompts.git" + }, + "author": "Operation Spark", + "license": "ISC", + "bugs": { + "url": "https://github.com/OperationSpark/recursion-prompts/issues" + }, + "homepage": "https://github.com/OperationSpark/recursion-prompts#readme", + "devDependencies": { + "chai": "^4.1.2", + "mocha": "^5.2.0", + "sinon": "^5.0.10" + } +} From d5c8c056f9d01673b50f1fefe2f4b8a5b733c600 Mon Sep 17 00:00:00 2001 From: Jay Kindell Date: Mon, 10 Sep 2018 12:15:30 -0500 Subject: [PATCH 03/36] reporter - json --- test/mocha.opts | 1 + 1 file changed, 1 insertion(+) create mode 100644 test/mocha.opts diff --git a/test/mocha.opts b/test/mocha.opts new file mode 100644 index 000000000..b512b38b9 --- /dev/null +++ b/test/mocha.opts @@ -0,0 +1 @@ +--reporter json \ No newline at end of file From 9addd59c07b8cb3803a6e8a34b871402a3a2f1d1 Mon Sep 17 00:00:00 2001 From: Jay Kindell Date: Mon, 10 Sep 2018 13:57:59 -0500 Subject: [PATCH 04/36] adds tests in /tests --- test/part1.js | 1182 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1182 insertions(+) create mode 100755 test/part1.js diff --git a/test/part1.js b/test/part1.js new file mode 100755 index 000000000..990645131 --- /dev/null +++ b/test/part1.js @@ -0,0 +1,1182 @@ +const path = require('path'); +const expect = require('chai').expect; +const sinon = require('sinon'); + + + describe('Exercises in Recursion in Recursion in Recursion in...', function() { + + describe('1. Factorial', function() { + + it('should return a number', function() { + expect(typeof(factorial(5))).to.equal('number'); + }); + + it('should return factorial for non-negative integers', function() { + expect(factorial(0)).to.equal(1); + expect(factorial(1)).to.equal(1); + expect(factorial(4)).to.equal(24); + expect(factorial(5)).to.equal(120); + }); + + it('should return null for negative integers', function() { + expect(factorial(-5)).to.equal(null); + }); + + it('should use recursion by calling self', function () { + var originalFactorial = factorial; + factorial = sinon.spy(factorial); + factorial(4); + expect(factorial.callCount).to.be.above(1); + factorial = originalFactorial; + }); + + }); + + + + describe('2. Sum of Integers', function() { + + it('should return a number', function() { + expect(typeof(sum([1,2,3,4,5,6]))).to.eql('number'); + }); + + it('should return the sum of an array of non-negative integers', function() { + expect(sum([1,2,3,4,5,6])).to.eql(21); + expect(sum([12,34,56,78])).to.eql(180); + expect(sum([3,0,34,7,18])).to.eql(62); + }); + + it('should return the sum of an array of negative integers', function() { + expect(sum([-1,-2,-3,-4,-5,-6])).to.eql(-21); + expect(sum([-12,-34,-56,-78])).to.eql(-180); + expect(sum([-3,-0,-34,-7,-18])).to.eql(-62); + }); + + it('should return the sum of an array of mixed non-negative and negative integers', function() { + expect(sum([1,-2,3,-4,5,-6])).to.eql(-3); + expect(sum([-12,34,-56,78])).to.eql(44); + expect(sum([3,0,-34,-7,18])).to.eql(-20); + }); + + it('should return 0 for empty array', function() { + expect(sum([])).to.eql(0); + }); + + it('should accept an array with a single integer', function() { + expect(sum([4])).to.eql(4); + expect(sum([0])).to.eql(0); + expect(sum([-37])).to.eql(-37); + }); + + it('should not mutate the input array', function() { + var input = [1,2,3,4,5]; + var result = sum(input); + expect(input).to.eql([1,2,3,4,5]); + }); + + it('should use recursion by calling self', function () { + var originalSum = sum; + sum = sinon.spy(sum); + sum([1,2,3,4,5,6]); + expect(sum.callCount).to.be.above(1); + sum = originalSum; + }); + + }); + + + + xdescribe('3. Sum Integers in Array', function() { + + it('should return a number', function() { + expect(typeof(arraySum([[1],[2,3],[[4]],5,6]))).to.eql('number'); + }); + + it('should return the sum of an array with nested arrays of non-negative integers', function() { + expect(arraySum([[1],[2,3],[[4]],5,6])).to.eql(21); + expect(arraySum([[12,[[34],[56]],78]])).to.eql(180); + expect(arraySum([3,[0,[34,[7,[18]]]]])).to.eql(62); + }); + + it('should return the sum of an array with nested arrays of negative integers', function() { + expect(arraySum([[-1],[-2,-3],[[-4]],-5,-6])).to.eql(-21); + expect(arraySum([[-12,[[-34],[-56]],-78]])).to.eql(-180); + expect(arraySum([-3,[0,[-34,[-7,[-18]]]]])).to.eql(-62); + }); + + it('should return the sum of an array with nested arrays of mixed non-negative and negative integers', function() { + expect(arraySum([[1],[-2,3],[[-4]],5,-6])).to.eql(-3); + expect(arraySum([[-12,[[34],[-56]],78]])).to.eql(44); + expect(arraySum([3,[0,[-34,[-7,[18]]]]])).to.eql(-20); + }); + + it('should return 0 for empty array', function() { + expect(arraySum([])).to.eql(0); + }); + + it('should accept an array with a single integer', function() { + expect(arraySum([4])).to.eql(4); + expect(arraySum([0])).to.eql(0); + expect(arraySum([-37])).to.eql(-37); + }); + + it('should not mutate the input array', function() { + var input = [[1],[2,3],[[4]],5,6]; + var result = arraySum(input); + expect(input).to.eql([[1],[2,3],[[4]],5,6]); + }); + + it('should use recursion by calling self', function () { + var originalArraySum = arraySum; + arraySum = sinon.spy(arraySum); + arraySum([[1],[2,3],[[4]],5,6]); + expect(arraySum.callCount).to.be.above(1); + arraySum = originalArraySum; + }); + + }); + + + + describe('4. Check if Even', function() { + + it('should return a boolean', function() { + expect(typeof(isEven(5))).to.equal('boolean'); + expect(typeof(isEven(8))).to.equal('boolean'); + expect(typeof(isEven(-4))).to.equal('boolean'); + }); + + it("should not use modulo", function() { + expect(isEven.toString()).to.not.contain('%'); + }); + + it('should return true for even numbers', function() { + expect(isEven(118)).to.equal(true); + expect(isEven(10)).to.equal(true); + expect(isEven(0)).to.equal(true); + expect(isEven(-34)).to.equal(true); + }); + + it('should return false for odd numbers', function() { + expect(isEven(117)).to.equal(false); + expect(isEven(9)).to.equal(false); + expect(isEven(1)).to.equal(false); + expect(isEven(-33)).to.equal(false); + }); + + it('should work with negative integers', function() { + expect(isEven(-14)).to.equal(true); + expect(isEven(-81)).to.equal(false); + }); + + it('should use recursion by calling self', function () { + var originalIsEven = isEven; + isEven = sinon.spy(isEven); + isEven(118); + expect(isEven.callCount).to.be.above(1); + isEven = originalIsEven; + }); + + }); + + + + describe('5. Sum Below', function() { + + it('should return a number', function() { + expect(typeof(sumBelow(10))).to.eql('number'); + }); + + it('should return the sum of non-negative integers below given integer', function() { + expect(sumBelow(0)).to.eql(0); + expect(sumBelow(1)).to.eql(0); + expect(sumBelow(2)).to.eql(1); + expect(sumBelow(7)).to.eql(21); + expect(sumBelow(21)).to.eql(210); + expect(sumBelow(92)).to.eql(4186); + }); + + it('should return the sum of an array of negative integers', function() { + expect(sumBelow(-1)).to.eql(0); + expect(sumBelow(-2)).to.eql(-1); + expect(sumBelow(-6)).to.eql(-15); + expect(sumBelow(-21)).to.eql(-210); + expect(sumBelow(-92)).to.eql(-4186); + }); + + it('should use recursion by calling self', function () { + var originalSumBelow = sumBelow; + sumBelow = sinon.spy(sumBelow); + sumBelow(10); + expect(sumBelow.callCount).to.be.above(1); + sumBelow = originalSumBelow; + }); + + }); + + + + describe('6. Integer Range', function() { + + it('should return an array', function() { + expect(Array.isArray(range(2, 7))).to.equal(true); + }); + + it('should return the integers between two numbers', function() { + expect(range(3,8)).to.eql([4,5,6,7]); + expect(range(127,131)).to.eql([128,129,130]); + }); + + it('should return empty array if no integers in range', function() { + expect(range(5,5)).to.eql([]); + expect(range(2,3)).to.eql([]); + }); + + it('should accept negative integers', function() { + expect(range(-9,-4)).to.eql([-8,-7,-6,-5]); + expect(range(-3,2)).to.eql([-2,-1,0,1]); + expect(range(-3,-2)).to.eql([]); + expect(range(-2,-2)).to.eql([]); + }); + + it('should accept starting integer that\'s larger than ending', function() { + expect(range(7,2)).to.eql([6,5,4,3]); + expect(range(3,-3)).to.eql([2,1,0,-1,-2]); + expect(range(-9,-4)).to.eql([-8,-7,-6,-5]); + }); + + it('should use recursion by calling self', function () { + var originalRange = range; + range = sinon.spy(range); + range(3,8); + expect(range.callCount).to.be.above(1); + range = originalRange; + }); + + }); + + + + describe('7. Compute Exponent', function() { + + it('should return a number', function() { + expect(typeof(exponent(4,3))).to.eql('number'); + }); + + it("should not use complex math", function() { + expect(exponent.toString()).to.not.contain('Math'); + }); + + it('should compute exponent of non-negative integers', function() { + expect(exponent(3,4)).to.equal(81); + expect(exponent(12,5)).to.equal(248832); + expect(exponent(7,2)).to.equal(49); + }); + + it('returns 1 when exponent is 0', function() { + expect(exponent(8,0)).to.equal(1); + expect(exponent(244,0)).to.equal(1); + }); + + it('returns base when exponent is 1', function() { + expect(exponent(9,1)).to.equal(9); + expect(exponent(2300,1)).to.equal(2300); + }); + + // it('BONUS: should accept negative integer for base', function() { + // expect(exponent(-3,4)).to.equal(-81); + // expect(exponent(-12,5)).to.equal(-248832); + // expect(exponent(-7,2)).to.equal(-49); + // expect(exponent(-7,4)).to.equal(-2401); + // }); + + it('should accept negative integer for exponent', function() { + expect(exponent(4,-2)).to.equal(0.0625); + expect(exponent(5,-4)).to.equal(0.0016); + expect(exponent(2,-5)).to.equal(0.03125); + }); + + it('should use recursion by calling self', function () { + var originalExponent = exponent; + exponent = sinon.spy(exponent); + exponent(3,4); + expect(exponent.callCount).to.be.above(1); + exponent = originalExponent; + }); + + }); + + + + describe('8. Power of Two', function() { + + it('should return a boolean', function() { + expect(typeof(powerOfTwo(10))).to.equal('boolean'); + expect(typeof(powerOfTwo(16))).to.equal('boolean'); + }); + + it('should return true for powers of two', function() { + expect(powerOfTwo(0)).to.equal(false); + expect(powerOfTwo(1)).to.equal(true); + expect(powerOfTwo(2)).to.equal(true); + expect(powerOfTwo(10)).to.equal(false); + expect(powerOfTwo(128)).to.equal(true); + expect(powerOfTwo(256)).to.equal(true); + }); + + it('should use recursion by calling self', function () { + var originalPowerOfTwo = powerOfTwo; + powerOfTwo = sinon.spy(powerOfTwo); + powerOfTwo(32); + expect(powerOfTwo.callCount).to.be.above(1); + powerOfTwo = originalPowerOfTwo; + }); + + }); + + + + describe('9. Reverse String', function() { + + it('should return a string', function() { + expect(typeof(reverse('orangutan'))).to.equal('string'); + }); + + it('should return a string in reverse', function() { + var poem = 'Roses are red, violets are blue, all my base are belong to you.'; + + expect(reverse('Racecar')).to.equal('racecaR'); + expect(reverse(poem)).to.equal('.uoy ot gnoleb era esab ym lla ,eulb era steloiv ,der era sesoR'); + }); + + it('should not mutate the input string', function() { + var input = 'orangutan'; + var result = reverse(input); + expect(input).to.eql('orangutan'); + }); + + it('should use recursion by calling self', function () { + var originalReverse = reverse; + reverse = sinon.spy(reverse); + reverse('orangutan'); + expect(reverse.callCount).to.be.above(1); + reverse = originalReverse; + }); + + }); + + + + describe('10. Palindrome', function() { + + it('should return a boolean', function() { + expect(typeof(palindrome('rotor'))).to.equal('boolean'); + expect(typeof(palindrome('motor'))).to.equal('boolean'); + }); + + it('should return true for palindromes', function() { + expect(palindrome('rotor')).to.eql(true); + expect(palindrome('racecar')).to.eql(true); + expect(palindrome('saippuakivikauppias')).to.eql(true); + }); + + it('should return false for non-palindromes', function() { + expect(palindrome('motor')).to.eql(false); + expect(palindrome('orangutan')).to.eql(false); + expect(palindrome('antidisestablishmentarianism')).to.eql(false); + }); + + it('should ignore spaces and capital letters', function() { + expect(palindrome('Rotor')).to.eql(true); + expect(palindrome('race caR')).to.eql(true); + expect(palindrome('sAip puaki v iKaup Pias')).to.eql(true); + }); + + it('should use recursion by calling self', function () { + var originalPalindrome = palindrome; + palindrome = sinon.spy(palindrome); + palindrome('saippuakivikauppias'); + expect(palindrome.callCount).to.be.above(1); + palindrome = originalPalindrome; + }); + + }); + + + + xdescribe('11. Modulo', function() { + + it('should return a number', function() { + expect(typeof(modulo(5,2))).to.equal('number'); + expect(typeof(modulo(8,4))).to.equal('number'); + }); + + it("should not use complex math", function() { + expect(modulo.toString()).to.not.contain('*'); + expect(modulo.toString()).to.not.contain('/'); + expect(modulo.toString()).to.not.contain('%'); + expect(modulo.toString()).to.not.contain('Math'); + }); + + it('should return the remainder of two integers', function() { + expect(modulo(2, 1)).to.equal(2 % 1); + expect(modulo(17, 5)).to.equal(17 % 5); + expect(modulo(78, 453)).to.equal(78 % 453); + expect(modulo(-79, 82)).to.equal(-79 % 82); + expect(modulo(-275, -502)).to.equal(-275 % -502); + expect(modulo(-275, -274)).to.equal(-275 % -274); + expect(modulo(-4, 2)).to.equal(-4 % 2); + expect(modulo(0, 32)).to.equal(0 % 32); + expect(modulo(0, 0).toString()).to.equal('NaN'); + }); + + it('should use recursion by calling self', function () { + var originalModulo = modulo; + modulo = sinon.spy(modulo); + modulo(5,2); + expect(modulo.callCount).to.be.above(1); + modulo = originalModulo; + }); + + }); + + + + describe('12. Multiply', function() { + + it('should return a number', function() { + expect(typeof(multiply(5,2))).to.equal('number'); + expect(typeof(multiply(8,4))).to.equal('number'); + }); + + it("should not use complex math", function() { + expect(multiply.toString()).to.not.contain('*'); + expect(multiply.toString()).to.not.contain('/'); + expect(multiply.toString()).to.not.contain('%'); + expect(multiply.toString()).to.not.contain('Math'); + }); + + it('should return the product of two integers', function() { + expect(multiply(2, 1)).to.equal(2 * 1); + expect(multiply(17, 5)).to.equal(17 * 5); + expect(multiply(78, 453)).to.equal(78 * 453); + expect(multiply(-79, 82)).to.equal(-79 * 82); + expect(multiply(-275, -502)).to.equal(-275 * -502); + expect(multiply(0, 32)).to.equal(0 * 32); + expect(multiply(0, 0)).to.equal(0 * 0); + }); + + it('should use recursion by calling self', function () { + var originalMultiply = multiply; + multiply = sinon.spy(multiply); + multiply(8,4); + expect(multiply.callCount).to.be.above(1); + multiply = originalMultiply; + }); + + }); + + + + xdescribe('13. Divide', function() { + + it('should return a number', function() { + expect(typeof(divide(5,2))).to.equal('number'); + expect(typeof(divide(8,4))).to.equal('number'); + }); + + it("should not use complex math", function() { + expect(divide.toString()).to.not.contain('*'); + expect(divide.toString()).to.not.contain('/'); + expect(divide.toString()).to.not.contain('%'); + expect(divide.toString()).to.not.contain('Math'); + }); + + it('should return the quotient of two integers', function() { + expect(divide(2, 1)).to.equal(~~(2 / 1)); + expect(divide(17, 5)).to.equal(~~(17 / 5)); + expect(divide(78, 453)).to.equal(~~(78 / 453)); + expect(divide(-79, 82)).to.equal(~~(-79 / 82)); + expect(divide(-275, -582)).to.equal(~~(-275 / -582)); + expect(divide(0, 32)).to.equal(~~(0 / 32)); + expect(divide(0, 0).toString()).to.equal('NaN'); + }); + + it('should use recursion by calling self', function () { + var originalDivide = divide; + divide = sinon.spy(divide); + divide(17, 5); + expect(divide.callCount).to.be.above(1); + divide = originalDivide; + }); + + }); + + + + xdescribe('14. Greatest Common Divisor', function() { + + it('should return a number', function() { + expect(typeof(gcd(4,36))).to.equal('number'); + }); + + it('should return greatest common divisor of two positive integers', function() { + expect(gcd(4,36)).to.equal(4); + expect(gcd(24,88)).to.equal(8); + expect(gcd(339,17)).to.equal(1); + expect(gcd(126,900)).to.equal(18); + }); + + it('should return null for negative integers', function() { + expect(gcd(-4, 2)).to.equal(null); + expect(gcd(-5, 5)).to.equal(null); + expect(gcd(5, -5)).to.equal(null); + expect(gcd(7, -36)).to.equal(null); + expect(gcd(-10, -58)).to.equal(null); + expect(gcd(-92, -5)).to.equal(null); + // expect(gcd(0, 0)).to.equal(null); + // expect(gcd(0, 5)).to.equal(null); + // expect(gcd(5, 0)).to.equal(null); + // expect(gcd(-5, 0)).to.equal(null); + // expect(gcd(0, -5)).to.equal(null); + }); + + it('should use recursion by calling self', function () { + var originalGcd = gcd; + gcd = sinon.spy(gcd); + gcd(17, 5); + expect(gcd.callCount).to.be.above(1); + gcd = originalGcd; + }); + + }); + + + + describe('15. Compare Strings', function() { + + it('should return a boolean', function() { + expect(typeof(compareStr('house', 'houses'))).to.equal('boolean'); + expect(typeof(compareStr('', ''))).to.equal('boolean'); + expect(typeof(compareStr('tomato', 'tomato'))).to.equal('boolean'); + }); + + it('should return true for identical strings', function() { + expect(compareStr('house', 'houses')).to.eql(false); + expect(compareStr('', '')).to.eql(true); + expect(compareStr('tomato', 'tomato')).to.eql(true); + expect(compareStr('', 'pop')).to.eql(false); + expect(compareStr('foot', '')).to.eql(false); + expect(compareStr('big dog', 'big dog')).to.eql(true); + }); + + it('should use recursion by calling self', function () { + var originalCompareStr = compareStr; + compareStr = sinon.spy(compareStr); + compareStr('house', 'houses'); + expect(compareStr.callCount).to.be.above(1); + compareStr = originalCompareStr; + }); + + }); + + + + describe('16. Create array from string', function() { + + it('should return an array', function() { + expect(Array.isArray(createArray('hello'))).to.equal(true); + }); + + it('should return an array where each index is a letter of the string', function() { + expect(createArray('hello')).to.eql(['h','e','l','l','o']); + expect(createArray('this is not a pipe')).to.eql(['t','h','i','s',' ','i','s',' ','n','o','t',' ','a',' ','p','i','p','e']); + expect(createArray('hologram')).to.eql(['h','o','l','o','g','r','a','m']); + expect(createArray('i')).to.eql(['i']); + }); + + it('should use recursion by calling self', function () { + var originalCreateArray = createArray; + createArray = sinon.spy(createArray); + createArray('hello'); + expect(createArray.callCount).to.be.above(1); + createArray = originalCreateArray; + }); + + }); + + + + describe('17. Reverse an array', function() { + + it('should return an array', function() { + expect(Array.isArray(reverseArr([5,4,3,2,1]))).to.equal(true); + }); + + it('should return array in reversed order', function() { + expect(reverseArr([1,2,3,4,5])).to.eql([5,4,3,2,1]); + expect(reverseArr([5,4,3,2,1])).to.eql([1,2,3,4,5]); + expect(reverseArr([2,4,6,8])).to.eql([8,6,4,2]); + expect(reverseArr([8,6,4,2])).to.eql([2,4,6,8]); + }); + + it('should use recursion by calling self', function () { + var originalReverseArr = reverseArr; + reverseArr = sinon.spy(reverseArr); + reverseArr([5,4,3,2,1]); + expect(reverseArr.callCount).to.be.above(1); + reverseArr = originalReverseArr; + }); + + }); + + + + describe('18. Build an array with a given value and length', function() { + + it('should return an array', function() { + expect(Array.isArray(buildList(0,5))).to.equal(true); + }); + + it('should return array of given length with given value at each index', function() { + expect(buildList(0, 5)).to.eql([0,0,0,0,0]); + expect(buildList('banana', 3)).to.eql(['banana','banana','banana']); + expect(buildList(NaN, 4)).to.eql([NaN, NaN, NaN, NaN]); + expect(buildList(undefined, 1)).to.eql([undefined]); + expect(buildList([], 2)).to.eql([[],[]]); + expect(buildList({}, 4)).to.eql([{},{},{},{}]); + expect(buildList(true, 3)).to.eql([true,true,true]); + expect(buildList(5+5, 3)).to.eql([10,10,10]); + }); + + it('should use recursion by calling self', function () { + var originalBuildList = buildList; + buildList = sinon.spy(buildList); + buildList(2,7); + expect(buildList.callCount).to.be.above(1); + buildList = originalBuildList; + }); + + }); + + + + describe('19. Count value in array', function() { + + it('should return a number', function() { + expect(typeof(countOccurrence([2,7,4,4,1,4], 4))).to.equal('number'); + expect(typeof(countOccurrence([2,'banana',4,4,1,'banana'], 'banana'))).to.equal('number'); + }); + + it('should return the number of occurrences of the value', function() { + expect(countOccurrence([2,7,4,4,1,4], 4)).to.eql(3); + expect(countOccurrence([2,'banana',4,4,1,'banana'], 'banana')).to.eql(2); + expect(countOccurrence([undefined,7,undefined,4,1,4], undefined)).to.eql(2); + expect(countOccurrence(['',7,null,0,'0',false], 0)).to.eql(1); + expect(countOccurrence(['',7,null,0,'0',false], false)).to.eql(1); + expect(countOccurrence(['',7,null,0,'0',false], null)).to.eql(1); + expect(countOccurrence(['',7,null,0,'0',false], '')).to.eql(1); + // expect(countOccurrence(['',7,null,0,NaN,'0',false], NaN)).to.eql(1); + }); + + it('should use recursion by calling self', function () { + var originalCountOccurrence = countOccurrence; + countOccurrence = sinon.spy(countOccurrence); + countOccurrence([2,7,4,4,1,4], 4); + expect(countOccurrence.callCount).to.be.above(1); + countOccurrence = originalCountOccurrence; + }); + + }); + + + + describe('20. Recursive Map', function() { + + var timesTwo = function(n) { return n * 2; }; + var input3 = [1,2,3,4,5]; + + it('should return an array', function() { + expect(Array.isArray(rMap([1,2,3], timesTwo))).to.equal(true); + }); + + checkForNativeMethods(function() { + rMap([1,2,3,4], timesTwo); + }); + + it('should return new array without mutating the input array', function() { + var input = [1,2,3,4,5]; + var result = rMap(input, function(num) { /* poop */ }); + expect(input).to.eql([1,2,3,4,5]); + expect(result).to.not.equal(input); + }); + + it('should apply a function to every value in an array', function() { + var doubledNumbers = rMap([1,2,3], timesTwo); + expect(doubledNumbers).to.eql([2,4,6]); + }); + + it('should use recursion by calling self', function () { + var originalrMap = rMap; + rMap = sinon.spy(rMap); + rMap([1,2,3,4], timesTwo); + expect(rMap.callCount).to.be.above(1); + rMap = originalrMap; + }); + + }); + + + + xdescribe('21. Count key in object', function() { + var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; + + it('should return a number', function() { + expect(typeof(countKeysInObj(input, 'r'))).to.equal('number'); + expect(typeof(countKeysInObj(input, 'e'))).to.equal('number'); + expect(typeof(countKeysInObj(input, 'p'))).to.equal('number'); + }); + + it('should return the number of occurrences of the property', function() { + expect(countKeysInObj(input, 'e')).to.eql(2); + expect(countKeysInObj(input, 'x')).to.eql(1); + expect(countKeysInObj(input, 'y')).to.eql(2); + expect(countKeysInObj(input, 't')).to.eql(1); + expect(countKeysInObj(input, 'r')).to.eql(1); + expect(countKeysInObj(input, 'p')).to.eql(1); + }); + + it('should use recursion by calling self', function () { + var originalCountKeysInObj = countKeysInObj; + countKeysInObj = sinon.spy(countKeysInObj); + countKeysInObj(input, 'e'); + expect(countKeysInObj.callCount).to.be.above(1); + countKeysInObj = originalCountKeysInObj; + }); + + }); + + + + xdescribe('22. Count value in object', function() { + var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; + + it('should return a number', function() { + expect(typeof(countValuesInObj(input, 'r'))).to.equal('number'); + expect(typeof(countValuesInObj(input, 'e'))).to.equal('number'); + expect(typeof(countValuesInObj(input, 'p'))).to.equal('number'); + }); + + it('should return the count of the occurrences of the property', function() { + expect(countValuesInObj(input, 'e')).to.eql(1); + expect(countValuesInObj(input, 'x')).to.eql(0); + expect(countValuesInObj(input, 'y')).to.eql(1); + expect(countValuesInObj(input, 't')).to.eql(0); + expect(countValuesInObj(input, 'r')).to.eql(2); + expect(countValuesInObj(input, 'p')).to.eql(0); + }); + + it('should use recursion by calling self', function () { + var originalCountValuesInObj = countValuesInObj; + countValuesInObj = sinon.spy(countValuesInObj); + countValuesInObj(input, 'r'); + expect(countValuesInObj.callCount).to.be.above(1); + countValuesInObj = originalCountValuesInObj; + }); + + }); + + + + xdescribe('23. Replace keys in object', function() { + + var tallyKeys = function(obj) { + var count = 0; + for (var k in obj) { + if (typeof obj[k] === 'object') { + count += tallyKeys(obj[k]); + } + count++; + } + return count; + }; + + it('should return an object', function() { + var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; + expect(typeof(replaceKeysInObj(input, 'r', 'a'))).to.equal('object'); + expect(typeof(replaceKeysInObj(input, 'e', 0))).to.equal('object'); + }); + + it('should return object containing renamed keys', function() { + var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}}, 'y':'e'}; + var output = replaceKeysInObj(input, 'e', 'f'); + + expect(output.e).to.equal(undefined); + expect(output.f.x).to.equal('y'); + expect(output.t.r.e).to.equal(undefined); + expect(output.t.r.f).to.equal('r'); + expect(output.t.p.y).to.equal('r'); + expect(output.y).to.equal('e'); + + expect(output.hasOwnProperty('e')).to.equal(false); + expect(output.hasOwnProperty('f')).to.equal(true); + expect(output.hasOwnProperty('t')).to.equal(true); + expect(output.hasOwnProperty('y')).to.equal(true); + + expect(output.t.hasOwnProperty('r')).to.equal(true); + expect(output.t.hasOwnProperty('p')).to.equal(true); + + expect(output.t.r.hasOwnProperty('e')).to.equal(false); + expect(output.t.r.hasOwnProperty('f')).to.equal(true); + expect(output.t.p.hasOwnProperty('y')).to.equal(true); + }); + + it('should return object with same number of keys', function () { + var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}}, 'y':'e'}; + var output1 = replaceKeysInObj(input, 'e', 'f'); + var output2 = replaceKeysInObj(output1, 'e', 'f'); + expect(tallyKeys(input)).to.equal(8); + expect(tallyKeys(output1)).to.equal(8); + expect(tallyKeys(output2)).to.equal(8); + }); + + it('should use recursion by calling self', function () { + var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; + var originalReplaceKeysInObj = replaceKeysInObj; + replaceKeysInObj = sinon.spy(replaceKeysInObj); + replaceKeysInObj(input, 'r', 'a'); + expect(replaceKeysInObj.callCount).to.be.above(1); + replaceKeysInObj = originalReplaceKeysInObj; + }); + + }); + + + xdescribe('24. First n Fibonacci', function() { + + it('should return an array', function() { + expect(Array.isArray(fibonacci(5))).to.equal(true); + }); + + it('should return first n Fibonacci numbers where n starts at index 1', function() { + expect(fibonacci(1)).to.eql([0, 1]); + expect(fibonacci(2)).to.eql([0, 1, 1]); + expect(fibonacci(3)).to.eql([0, 1, 1, 2]); + expect(fibonacci(4)).to.eql([0, 1, 1, 2, 3]); + expect(fibonacci(5)).to.eql([0, 1, 1, 2, 3, 5]); + expect(fibonacci(12)).to.eql([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]); + }); + + it('should return null for zero and negative integers', function() { + expect(fibonacci(0)).to.equal(null); + expect(fibonacci(-7)).to.equal(null); + }); + + it('should use recursion by calling self', function () { + var originalFibonacci = fibonacci; + fibonacci = sinon.spy(fibonacci); + fibonacci(5); + expect(fibonacci.callCount).to.be.above(1); + fibonacci = originalFibonacci; + }); + + }); + + + + describe('25. Return nth Fibonacci', function() { + + it('should return a number', function() { + expect(typeof(nthFibo(5))).to.equal('number'); + }); + + it('should return the nth Fibonacci number', function() { + expect(nthFibo(0)).to.eql(0); + expect(nthFibo(1)).to.eql(1); + expect(nthFibo(2)).to.eql(1); + expect(nthFibo(3)).to.eql(2); + expect(nthFibo(4)).to.eql(3); + expect(nthFibo(5)).to.eql(5); + expect(nthFibo(12)).to.eql(144); + }); + + it('should return null for negative integers', function() { + expect(nthFibo(-5)).to.equal(null); + expect(nthFibo(-7)).to.equal(null); + }); + + it('should use recursion by calling self', function () { + var originalNthFibo = nthFibo; + nthFibo = sinon.spy(nthFibo); + nthFibo(5); + expect(nthFibo.callCount).to.be.above(1); + nthFibo = originalNthFibo; + }); + + }); + + + + describe('26. Capitalize words in array', function() { + + it('should return an array', function() { + expect(Array.isArray(capitalizeWords(['i','am','learning','recursion']))).to.equal(true); + }); + + it('should capitalize all words in array', function() { + expect(capitalizeWords(['i','am','learning','recursion'])).to.eql(['I', 'AM', 'LEARNING', 'RECURSION']); + expect(capitalizeWords(["ceci","n'est","pas","une","pipe"])).to.eql(["CECI", "N'EST", "PAS", "UNE", "PIPE"]); + }); + + it('should use recursion by calling self', function () { + var originalCapitalizeWords = capitalizeWords; + capitalizeWords = sinon.spy(capitalizeWords); + capitalizeWords(["ceci","n'est","pas","une","pipe"]); + expect(capitalizeWords.callCount).to.be.above(1); + capitalizeWords = originalCapitalizeWords; + }); + + }); + + + + describe('27. Capitalize first letter of words in array', function() { + + it('should return an array', function() { + expect(Array.isArray(capitalizeFirst(['i','am','learning','recursion']))).to.equal(true); + }); + + it('should capitalize first letter of each word in array', function() { + expect(capitalizeFirst(['i','am','learning','recursion'])).to.eql(['I', 'Am', 'Learning', 'Recursion']); + expect(capitalizeFirst(["ceci","n'est","pas","une","pipe"])).to.eql(["Ceci", "N'est", "Pas", "Une", "Pipe"]); + }); + + it('should use recursion by calling self', function () { + var originalCapitalizeFirst = capitalizeFirst; + capitalizeFirst = sinon.spy(capitalizeFirst); + capitalizeFirst(["ceci","n'est","pas","une","pipe"]); + expect(capitalizeFirst.callCount).to.be.above(1); + capitalizeFirst = originalCapitalizeFirst; + }); + + }); + + + + xdescribe('28. Sum even numbers in nested objects', function() { + var obj = { + a: 2, + b: {b: 2, bb: {b: 3, bb: {b: 2}}}, + c: {c: {c: 2}, cc: 'ball', ccc: 5}, + d: 1, + e: {e: {e: 2}, ee: 'car'} + }; + + it('should return a number', function() { + expect(typeof(nestedEvenSum(obj))).to.equal('number'); + }); + + it('should sum even numbers', function() { + expect(nestedEvenSum(obj)).to.eql(10); + }); + + it('should use recursion by calling self', function () { + var originalNestedEvenSum = nestedEvenSum; + nestedEvenSum = sinon.spy(nestedEvenSum); + nestedEvenSum(obj); + expect(nestedEvenSum.callCount).to.be.above(1); + nestedEvenSum = originalNestedEvenSum; + }); + + }); + + + + xdescribe('29. Flatten nested arrays', function() { + + it('should return an array', function() { + expect(Array.isArray(flatten([1,[2],[3,[[4]]],5]))).to.equal(true); + }); + + it('should return flattened array', function() { + expect(flatten([[1],[2,3],[[4]],5,6])).to.eql([1,2,3,4,5,6]); + expect(flatten([[12,[[34],[56]],78]])).to.eql([12,34,56,78]); + expect(flatten([3,[0,[34,[7,[18]]]]])).to.eql([3,0,34,7,18]); + expect(flatten([[1],[2,[],3],[],[[4]],5,6])).to.eql([1,2,3,4,5,6]); + }); + + it('should use recursion by calling self', function () { + var originalFlatten = flatten; + flatten = sinon.spy(flatten); + flatten([3,[0,[34,[7,[18]]]]]); + expect(flatten.callCount).to.be.above(1); + flatten = originalFlatten; + }); + + }); + + + + describe('30. Tally letters in string', function() { + + it('should return an object', function() { + expect(typeof(letterTally('orangutan'))).to.equal('object'); + }); + + it('should return object containing tallies of unique letters', function() { + var output = letterTally('potato'); + + expect(output.p).to.equal(1); + expect(output.o).to.equal(2); + expect(output.t).to.equal(2); + expect(output.a).to.equal(1); + }); + + it('should return object containing the number of keys corresponding to unique letters', function () { + var output = letterTally('mississippi'); + var countKeys = Object.keys(output).length; + expect(countKeys).to.equal(4); + }); + + it('should use recursion by calling self', function () { + var originalLetterTally = letterTally; + letterTally = sinon.spy(letterTally); + letterTally('invasion'); + expect(letterTally.callCount).to.be.above(1); + letterTally = originalLetterTally; + }); + + }); + + + + describe('31. Eliminate consecutive duplicates', function() { + var input1 = [1,2,2,3,4,4,5,5,5]; + var input2 = [1,2,2,3,4,4,2,5,5,5,4,4]; + + it('should return an array', function() { + expect(Array.isArray(compress(input1))).to.equal(true); + }); + + it('should remove consecutive duplicates', function() { + expect(compress(input1)).to.eql([1,2,3,4,5]); + expect(compress(input2)).to.eql([1,2,3,4,2,5,4]); + }); + + it('should use recursion by calling self', function () { + var originalCompress = compress; + compress = sinon.spy(compress); + compress(input2); + expect(compress.callCount).to.be.above(1); + compress = originalCompress; + }); + + }); + + + + xdescribe('32. Augment each element in nested arrays', function() { + + it('should return an array', function() { + expect(Array.isArray(augmentElements([[],[3],[7]], 5))).to.equal(true); + }); + + it('should augment each element with given value', function() { + expect(augmentElements([[],[3],[7]], 5)).to.eql([[5],[3,5],[7,5]]); + expect(augmentElements([[],[3],[7]], null)).to.eql([[null],[3,null],[7,null]]); + expect(augmentElements([[],[3],[7]], '')).to.eql([[''],[3,''],[7,'']]); + }); + + it('should use recursion by calling self', function () { + var originalAugElements = augmentElements; + augmentElements = sinon.spy(augmentElements); + augmentElements([[],[3],[7]], 5); + expect(augmentElements.callCount).to.be.above(1); + augmentElements = originalAugElements; + }); + + }); + + + + describe('33. Minimize zeroes', function() { + var input1 = [2,0,0,0,1,4]; + var input2 = [2,0,0,0,1,0,0,4]; + + it('should return an array', function() { + expect(Array.isArray(minimizeZeroes(input1))).to.equal(true); + }); + + it('should remove excess zeroes', function() { + expect(minimizeZeroes(input1)).to.eql([2,0,1,4]); + expect(minimizeZeroes(input2)).to.eql([2,0,1,0,4]); + }); + + it('should use recursion by calling self', function () { + var originalMinZeroes = minimizeZeroes; + minimizeZeroes = sinon.spy(minimizeZeroes); + minimizeZeroes(input1); + expect(minimizeZeroes.callCount).to.be.above(1); + minimizeZeroes = originalMinZeroes; + }); + + }); + + + + describe('34. Alternate sign', function() { + var input1 = [2,7,8,3,1,4]; + var input2 = [-2,-7,8,3,-1,4]; + + it('should return an array', function() { + expect(Array.isArray(alternateSign(input1))).to.equal(true); + }); + + it('should remove excess zeroes', function() { + expect(alternateSign(input1)).to.eql([2,-7,8,-3,1,-4]); + expect(alternateSign(input2)).to.eql([2,-7,8,-3,1,-4]); + }); + + it('should use recursion by calling self', function () { + var originalAltSign = alternateSign; + alternateSign = sinon.spy(alternateSign); + alternateSign(input1); + expect(alternateSign.callCount).to.be.above(1); + alternateSign = originalAltSign; + }); + + }); + + + + xdescribe('35. Convert numbers to text', function() { + + it('should return a string', function() { + expect(typeof(numToText("I have 5 dogs and 6 ponies"))).to.equal('string'); + }); + + it('should convert single digits to their word equivalent', function() { + expect(numToText("I have 5 dogs and 6 ponies")).to.eql("I have five dogs and six ponies"); + expect(numToText("It takes 3 men to screw in 1 light bulb")).to.eql("It takes three men to screw in one light bulb"); + }); + + it('should use recursion by calling self', function () { + var originalNumToText = numToText; + numToText = sinon.spy(numToText); + numToText("I have 5 dogs and 6 ponies"); + expect(numToText.callCount).to.be.above(1); + numToText = originalNumToText; + }); + + }); + + }); + + function checkForNativeMethods(runFunction) { + it('should not use the native version of map', function() { + // These spies are set up in testSupport.js + runFunction(); + expect(Array.prototype.map.called).to.equal(false); + }); + } + From a33c7722f8415266aeacdb04fa7f990beaeab294 Mon Sep 17 00:00:00 2001 From: Jay Kindell Date: Tue, 11 Sep 2018 10:38:02 -0500 Subject: [PATCH 05/36] adds exports for testing --- src/recursion.js | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/recursion.js b/src/recursion.js index e92a8866c..12ca0a3d7 100644 --- a/src/recursion.js +++ b/src/recursion.js @@ -191,7 +191,7 @@ var letterTally = function(str, obj) { var compress = function(list) { }; -// 32. Augument every element in a list with a new value where each element is an array +// 32. Augment every element in a list with a new value where each element is an array // itself. // Example: augmentElements([[],[3],[7]], 5); // [[5],[3,5],[7,5]] var augmentElements = function(array, aug) { @@ -234,3 +234,40 @@ var binarySearch = function(array, target, min, max) { // Sample output: [5,7,23,32,34,62] var mergeSort = function(array) { }; + + + +//----------------------------------- +// DON'T REMOVE THIS CODE ----------- +//----------------------------------- + +if ((typeof process !== 'undefined') && + (typeof process.versions.node !== 'undefined')) { + module.exports = { + factorial, + sum, + isEven, + sumBelow, + range, + exponent, + powerOfTwo, + reverse, + palindrome, + multiply, + compareStr, + createArray, + reverseArr, + buildList, + countOccurrence, + rMap, + nthFibo, + capitalizeWords, + capitalizeFirst, + letterTally, + compress, + minimizeZeroes, + alternateSign, + }; +} + +//----------------------------------- \ No newline at end of file From d8cecf8200c12f9842017b0290948d37eefa2416 Mon Sep 17 00:00:00 2001 From: Jay Kindell Date: Tue, 11 Sep 2018 10:42:48 -0500 Subject: [PATCH 06/36] just the package-lock Please enter the commit message for your changes. Lines starting --- package-lock.json | 331 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..3ceb4b02e --- /dev/null +++ b/package-lock.json @@ -0,0 +1,331 @@ +{ + "name": "recursion-prompts", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@sinonjs/formatio": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", + "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", + "dev": true, + "requires": { + "samsam": "1.3.0" + } + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "chai": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", + "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", + "dev": true, + "requires": { + "assertion-error": "1.1.0", + "check-error": "1.0.2", + "deep-eql": "3.0.1", + "get-func-name": "2.0.0", + "pathval": "1.1.0", + "type-detect": "4.0.8" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "just-extend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-3.0.0.tgz", + "integrity": "sha512-Fu3T6pKBuxjWT/p4DkqGHFRsysc8OauWr4ZRTY9dIx07Y9O0RkoR5jcv28aeD1vuAwhm3nLkDurwLXoALp4DpQ==", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lolex": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.1.tgz", + "integrity": "sha512-Oo2Si3RMKV3+lV5MsSWplDQFoTClz/24S0MMHYcgGWWmFXr6TMlqcqk/l1GtH+d5wLBwNRiqGnwDRMirtFalJw==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.11" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nise": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.4.tgz", + "integrity": "sha512-pxE0c9PzgrUTyhfv5p+5eMIdfU2bLEsq8VQEuE0kxM4zP7SujSar7rk9wpI2F7RyyCEvLyj5O7Is3RER5F36Fg==", + "dev": true, + "requires": { + "@sinonjs/formatio": "2.0.0", + "just-extend": "3.0.0", + "lolex": "2.7.1", + "path-to-regexp": "1.7.0", + "text-encoding": "0.6.4" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "samsam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", + "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", + "dev": true + }, + "sinon": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-5.1.1.tgz", + "integrity": "sha512-h/3uHscbt5pQNxkf7Y/Lb9/OM44YNCicHakcq73ncbrIS8lXg+ZGOZbtuU+/km4YnyiCYfQQEwANaReJz7KDfw==", + "dev": true, + "requires": { + "@sinonjs/formatio": "2.0.0", + "diff": "3.5.0", + "lodash.get": "4.4.2", + "lolex": "2.7.1", + "nise": "1.4.4", + "supports-color": "5.4.0", + "type-detect": "4.0.8" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + }, + "text-encoding": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "dev": true + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } +} From 043dfd4f7e5c2f2307e3ff262e129e310b1c0173 Mon Sep 17 00:00:00 2001 From: Jay Kindell Date: Tue, 11 Sep 2018 11:48:41 -0500 Subject: [PATCH 07/36] requires exercise modules in tests --- test/part1.js | 1979 +++++++++++++++++++++++++++---------------------- 1 file changed, 1108 insertions(+), 871 deletions(-) diff --git a/test/part1.js b/test/part1.js index 990645131..427a409cc 100755 --- a/test/part1.js +++ b/test/part1.js @@ -2,1181 +2,1418 @@ const path = require('path'); const expect = require('chai').expect; const sinon = require('sinon'); +const { + factorial, + sum, + isEven, + sumBelow, + range, + exponent, + powerOfTwo, + reverse, + palindrome, + multiply, + compareStr, + createArray, + reverseArr, + buildList, + countOccurrence, + rMap, + nthFibo, + capitalizeWords, + capitalizeFirst, + letterTally, + compress, + minimizeZeroes, + alternateSign, +} = require(path.join(__dirname, '..', './src/recursion.js')); + +describe('Exercises in Recursion...', function () { + + describe('1. Factorial', function () { + + it('should return a number', function () { + expect(typeof (factorial(5))).to.equal('number'); + }); - describe('Exercises in Recursion in Recursion in Recursion in...', function() { - - describe('1. Factorial', function() { - - it('should return a number', function() { - expect(typeof(factorial(5))).to.equal('number'); - }); - - it('should return factorial for non-negative integers', function() { - expect(factorial(0)).to.equal(1); - expect(factorial(1)).to.equal(1); - expect(factorial(4)).to.equal(24); - expect(factorial(5)).to.equal(120); - }); - - it('should return null for negative integers', function() { - expect(factorial(-5)).to.equal(null); - }); + it('should return factorial for non-negative integers', function () { + expect(factorial(0)).to.equal(1); + expect(factorial(1)).to.equal(1); + expect(factorial(4)).to.equal(24); + expect(factorial(5)).to.equal(120); + }); - it('should use recursion by calling self', function () { - var originalFactorial = factorial; - factorial = sinon.spy(factorial); - factorial(4); - expect(factorial.callCount).to.be.above(1); - factorial = originalFactorial; - }); + it('should return null for negative integers', function () { + expect(factorial(-5)).to.equal(null); + }); + it('should use recursion by calling self', function () { + var originalFactorial = factorial; + factorial = sinon.spy(factorial); + factorial(4); + expect(factorial.callCount).to.be.above(1); + factorial = originalFactorial; }); + }); - describe('2. Sum of Integers', function() { - it('should return a number', function() { - expect(typeof(sum([1,2,3,4,5,6]))).to.eql('number'); - }); + describe('2. Sum of Integers', function () { - it('should return the sum of an array of non-negative integers', function() { - expect(sum([1,2,3,4,5,6])).to.eql(21); - expect(sum([12,34,56,78])).to.eql(180); - expect(sum([3,0,34,7,18])).to.eql(62); - }); + it('should return a number', function () { + expect(typeof (sum([1, 2, 3, 4, 5, 6]))).to.eql('number'); + }); - it('should return the sum of an array of negative integers', function() { - expect(sum([-1,-2,-3,-4,-5,-6])).to.eql(-21); - expect(sum([-12,-34,-56,-78])).to.eql(-180); - expect(sum([-3,-0,-34,-7,-18])).to.eql(-62); - }); + it('should return the sum of an array of non-negative integers', function () { + expect(sum([1, 2, 3, 4, 5, 6])).to.eql(21); + expect(sum([12, 34, 56, 78])).to.eql(180); + expect(sum([3, 0, 34, 7, 18])).to.eql(62); + }); - it('should return the sum of an array of mixed non-negative and negative integers', function() { - expect(sum([1,-2,3,-4,5,-6])).to.eql(-3); - expect(sum([-12,34,-56,78])).to.eql(44); - expect(sum([3,0,-34,-7,18])).to.eql(-20); - }); + it('should return the sum of an array of negative integers', function () { + expect(sum([-1, -2, -3, -4, -5, -6])).to.eql(-21); + expect(sum([-12, -34, -56, -78])).to.eql(-180); + expect(sum([-3, -0, -34, -7, -18])).to.eql(-62); + }); - it('should return 0 for empty array', function() { - expect(sum([])).to.eql(0); - }); + it('should return the sum of an array of mixed non-negative and negative integers', function () { + expect(sum([1, -2, 3, -4, 5, -6])).to.eql(-3); + expect(sum([-12, 34, -56, 78])).to.eql(44); + expect(sum([3, 0, -34, -7, 18])).to.eql(-20); + }); - it('should accept an array with a single integer', function() { - expect(sum([4])).to.eql(4); - expect(sum([0])).to.eql(0); - expect(sum([-37])).to.eql(-37); - }); + it('should return 0 for empty array', function () { + expect(sum([])).to.eql(0); + }); - it('should not mutate the input array', function() { - var input = [1,2,3,4,5]; - var result = sum(input); - expect(input).to.eql([1,2,3,4,5]); - }); + it('should accept an array with a single integer', function () { + expect(sum([4])).to.eql(4); + expect(sum([0])).to.eql(0); + expect(sum([-37])).to.eql(-37); + }); - it('should use recursion by calling self', function () { - var originalSum = sum; - sum = sinon.spy(sum); - sum([1,2,3,4,5,6]); - expect(sum.callCount).to.be.above(1); - sum = originalSum; - }); + it('should not mutate the input array', function () { + var input = [1, 2, 3, 4, 5]; + var result = sum(input); + expect(input).to.eql([1, 2, 3, 4, 5]); + }); + it('should use recursion by calling self', function () { + var originalSum = sum; + sum = sinon.spy(sum); + sum([1, 2, 3, 4, 5, 6]); + expect(sum.callCount).to.be.above(1); + sum = originalSum; }); + }); + - xdescribe('3. Sum Integers in Array', function() { + xdescribe('3. Sum Integers in Array', function () { - it('should return a number', function() { - expect(typeof(arraySum([[1],[2,3],[[4]],5,6]))).to.eql('number'); - }); + it('should return a number', function () { + expect(typeof (arraySum([ + [1], + [2, 3], + [ + [4] + ], 5, 6 + ]))).to.eql('number'); + }); - it('should return the sum of an array with nested arrays of non-negative integers', function() { - expect(arraySum([[1],[2,3],[[4]],5,6])).to.eql(21); - expect(arraySum([[12,[[34],[56]],78]])).to.eql(180); - expect(arraySum([3,[0,[34,[7,[18]]]]])).to.eql(62); - }); + it('should return the sum of an array with nested arrays of non-negative integers', function () { + expect(arraySum([ + [1], + [2, 3], + [ + [4] + ], 5, 6 + ])).to.eql(21); + expect(arraySum([ + [12, [ + [34], + [56] + ], 78] + ])).to.eql(180); + expect(arraySum([3, [0, [34, [7, [18]]]]])).to.eql(62); + }); - it('should return the sum of an array with nested arrays of negative integers', function() { - expect(arraySum([[-1],[-2,-3],[[-4]],-5,-6])).to.eql(-21); - expect(arraySum([[-12,[[-34],[-56]],-78]])).to.eql(-180); - expect(arraySum([-3,[0,[-34,[-7,[-18]]]]])).to.eql(-62); - }); + it('should return the sum of an array with nested arrays of negative integers', function () { + expect(arraySum([ + [-1], + [-2, -3], + [ + [-4] + ], -5, -6 + ])).to.eql(-21); + expect(arraySum([ + [-12, [ + [-34], + [-56] + ], -78] + ])).to.eql(-180); + expect(arraySum([-3, [0, [-34, [-7, [-18]]]]])).to.eql(-62); + }); - it('should return the sum of an array with nested arrays of mixed non-negative and negative integers', function() { - expect(arraySum([[1],[-2,3],[[-4]],5,-6])).to.eql(-3); - expect(arraySum([[-12,[[34],[-56]],78]])).to.eql(44); - expect(arraySum([3,[0,[-34,[-7,[18]]]]])).to.eql(-20); - }); - - it('should return 0 for empty array', function() { - expect(arraySum([])).to.eql(0); - }); + it('should return the sum of an array with nested arrays of mixed non-negative and negative integers', function () { + expect(arraySum([ + [1], + [-2, 3], + [ + [-4] + ], 5, -6 + ])).to.eql(-3); + expect(arraySum([ + [-12, [ + [34], + [-56] + ], 78] + ])).to.eql(44); + expect(arraySum([3, [0, [-34, [-7, [18]]]]])).to.eql(-20); + }); - it('should accept an array with a single integer', function() { - expect(arraySum([4])).to.eql(4); - expect(arraySum([0])).to.eql(0); - expect(arraySum([-37])).to.eql(-37); - }); + it('should return 0 for empty array', function () { + expect(arraySum([])).to.eql(0); + }); - it('should not mutate the input array', function() { - var input = [[1],[2,3],[[4]],5,6]; - var result = arraySum(input); - expect(input).to.eql([[1],[2,3],[[4]],5,6]); - }); + it('should accept an array with a single integer', function () { + expect(arraySum([4])).to.eql(4); + expect(arraySum([0])).to.eql(0); + expect(arraySum([-37])).to.eql(-37); + }); - it('should use recursion by calling self', function () { - var originalArraySum = arraySum; - arraySum = sinon.spy(arraySum); - arraySum([[1],[2,3],[[4]],5,6]); - expect(arraySum.callCount).to.be.above(1); - arraySum = originalArraySum; - }); + it('should not mutate the input array', function () { + var input = [ + [1], + [2, 3], + [ + [4] + ], 5, 6 + ]; + var result = arraySum(input); + expect(input).to.eql([ + [1], + [2, 3], + [ + [4] + ], 5, 6 + ]); + }); + it('should use recursion by calling self', function () { + var originalArraySum = arraySum; + arraySum = sinon.spy(arraySum); + arraySum([ + [1], + [2, 3], + [ + [4] + ], 5, 6 + ]); + expect(arraySum.callCount).to.be.above(1); + arraySum = originalArraySum; }); + }); - describe('4. Check if Even', function() { - - it('should return a boolean', function() { - expect(typeof(isEven(5))).to.equal('boolean'); - expect(typeof(isEven(8))).to.equal('boolean'); - expect(typeof(isEven(-4))).to.equal('boolean'); - }); - - it("should not use modulo", function() { - expect(isEven.toString()).to.not.contain('%'); - }); - - it('should return true for even numbers', function() { - expect(isEven(118)).to.equal(true); - expect(isEven(10)).to.equal(true); - expect(isEven(0)).to.equal(true); - expect(isEven(-34)).to.equal(true); - }); - it('should return false for odd numbers', function() { - expect(isEven(117)).to.equal(false); - expect(isEven(9)).to.equal(false); - expect(isEven(1)).to.equal(false); - expect(isEven(-33)).to.equal(false); - }); + describe('4. Check if Even', function () { - it('should work with negative integers', function() { - expect(isEven(-14)).to.equal(true); - expect(isEven(-81)).to.equal(false); - }); + it('should return a boolean', function () { + expect(typeof (isEven(5))).to.equal('boolean'); + expect(typeof (isEven(8))).to.equal('boolean'); + expect(typeof (isEven(-4))).to.equal('boolean'); + }); - it('should use recursion by calling self', function () { - var originalIsEven = isEven; - isEven = sinon.spy(isEven); - isEven(118); - expect(isEven.callCount).to.be.above(1); - isEven = originalIsEven; - }); + it("should not use modulo", function () { + expect(isEven.toString()).to.not.contain('%'); + }); + it('should return true for even numbers', function () { + expect(isEven(118)).to.equal(true); + expect(isEven(10)).to.equal(true); + expect(isEven(0)).to.equal(true); + expect(isEven(-34)).to.equal(true); }); + it('should return false for odd numbers', function () { + expect(isEven(117)).to.equal(false); + expect(isEven(9)).to.equal(false); + expect(isEven(1)).to.equal(false); + expect(isEven(-33)).to.equal(false); + }); + it('should work with negative integers', function () { + expect(isEven(-14)).to.equal(true); + expect(isEven(-81)).to.equal(false); + }); - describe('5. Sum Below', function() { + it('should use recursion by calling self', function () { + var originalIsEven = isEven; + isEven = sinon.spy(isEven); + isEven(118); + expect(isEven.callCount).to.be.above(1); + isEven = originalIsEven; + }); - it('should return a number', function() { - expect(typeof(sumBelow(10))).to.eql('number'); - }); + }); - it('should return the sum of non-negative integers below given integer', function() { - expect(sumBelow(0)).to.eql(0); - expect(sumBelow(1)).to.eql(0); - expect(sumBelow(2)).to.eql(1); - expect(sumBelow(7)).to.eql(21); - expect(sumBelow(21)).to.eql(210); - expect(sumBelow(92)).to.eql(4186); - }); - it('should return the sum of an array of negative integers', function() { - expect(sumBelow(-1)).to.eql(0); - expect(sumBelow(-2)).to.eql(-1); - expect(sumBelow(-6)).to.eql(-15); - expect(sumBelow(-21)).to.eql(-210); - expect(sumBelow(-92)).to.eql(-4186); - }); - it('should use recursion by calling self', function () { - var originalSumBelow = sumBelow; - sumBelow = sinon.spy(sumBelow); - sumBelow(10); - expect(sumBelow.callCount).to.be.above(1); - sumBelow = originalSumBelow; - }); + describe('5. Sum Below', function () { + it('should return a number', function () { + expect(typeof (sumBelow(10))).to.eql('number'); }); + it('should return the sum of non-negative integers below given integer', function () { + expect(sumBelow(0)).to.eql(0); + expect(sumBelow(1)).to.eql(0); + expect(sumBelow(2)).to.eql(1); + expect(sumBelow(7)).to.eql(21); + expect(sumBelow(21)).to.eql(210); + expect(sumBelow(92)).to.eql(4186); + }); + it('should return the sum of an array of negative integers', function () { + expect(sumBelow(-1)).to.eql(0); + expect(sumBelow(-2)).to.eql(-1); + expect(sumBelow(-6)).to.eql(-15); + expect(sumBelow(-21)).to.eql(-210); + expect(sumBelow(-92)).to.eql(-4186); + }); - describe('6. Integer Range', function() { + it('should use recursion by calling self', function () { + var originalSumBelow = sumBelow; + sumBelow = sinon.spy(sumBelow); + sumBelow(10); + expect(sumBelow.callCount).to.be.above(1); + sumBelow = originalSumBelow; + }); - it('should return an array', function() { - expect(Array.isArray(range(2, 7))).to.equal(true); - }); + }); - it('should return the integers between two numbers', function() { - expect(range(3,8)).to.eql([4,5,6,7]); - expect(range(127,131)).to.eql([128,129,130]); - }); - it('should return empty array if no integers in range', function() { - expect(range(5,5)).to.eql([]); - expect(range(2,3)).to.eql([]); - }); - it('should accept negative integers', function() { - expect(range(-9,-4)).to.eql([-8,-7,-6,-5]); - expect(range(-3,2)).to.eql([-2,-1,0,1]); - expect(range(-3,-2)).to.eql([]); - expect(range(-2,-2)).to.eql([]); - }); + describe('6. Integer Range', function () { + + it('should return an array', function () { + expect(Array.isArray(range(2, 7))).to.equal(true); + }); - it('should accept starting integer that\'s larger than ending', function() { - expect(range(7,2)).to.eql([6,5,4,3]); - expect(range(3,-3)).to.eql([2,1,0,-1,-2]); - expect(range(-9,-4)).to.eql([-8,-7,-6,-5]); - }); + it('should return the integers between two numbers', function () { + expect(range(3, 8)).to.eql([4, 5, 6, 7]); + expect(range(127, 131)).to.eql([128, 129, 130]); + }); - it('should use recursion by calling self', function () { - var originalRange = range; - range = sinon.spy(range); - range(3,8); - expect(range.callCount).to.be.above(1); - range = originalRange; - }); + it('should return empty array if no integers in range', function () { + expect(range(5, 5)).to.eql([]); + expect(range(2, 3)).to.eql([]); + }); + it('should accept negative integers', function () { + expect(range(-9, -4)).to.eql([-8, -7, -6, -5]); + expect(range(-3, 2)).to.eql([-2, -1, 0, 1]); + expect(range(-3, -2)).to.eql([]); + expect(range(-2, -2)).to.eql([]); }); + it('should accept starting integer that\'s larger than ending', function () { + expect(range(7, 2)).to.eql([6, 5, 4, 3]); + expect(range(3, -3)).to.eql([2, 1, 0, -1, -2]); + expect(range(-9, -4)).to.eql([-8, -7, -6, -5]); + }); + it('should use recursion by calling self', function () { + var originalRange = range; + range = sinon.spy(range); + range(3, 8); + expect(range.callCount).to.be.above(1); + range = originalRange; + }); - describe('7. Compute Exponent', function() { + }); - it('should return a number', function() { - expect(typeof(exponent(4,3))).to.eql('number'); - }); - it("should not use complex math", function() { - expect(exponent.toString()).to.not.contain('Math'); - }); - it('should compute exponent of non-negative integers', function() { - expect(exponent(3,4)).to.equal(81); - expect(exponent(12,5)).to.equal(248832); - expect(exponent(7,2)).to.equal(49); - }); + describe('7. Compute Exponent', function () { - it('returns 1 when exponent is 0', function() { - expect(exponent(8,0)).to.equal(1); - expect(exponent(244,0)).to.equal(1); - }); + it('should return a number', function () { + expect(typeof (exponent(4, 3))).to.eql('number'); + }); - it('returns base when exponent is 1', function() { - expect(exponent(9,1)).to.equal(9); - expect(exponent(2300,1)).to.equal(2300); - }); + it("should not use complex math", function () { + expect(exponent.toString()).to.not.contain('Math'); + }); - // it('BONUS: should accept negative integer for base', function() { - // expect(exponent(-3,4)).to.equal(-81); - // expect(exponent(-12,5)).to.equal(-248832); - // expect(exponent(-7,2)).to.equal(-49); - // expect(exponent(-7,4)).to.equal(-2401); - // }); + it('should compute exponent of non-negative integers', function () { + expect(exponent(3, 4)).to.equal(81); + expect(exponent(12, 5)).to.equal(248832); + expect(exponent(7, 2)).to.equal(49); + }); - it('should accept negative integer for exponent', function() { - expect(exponent(4,-2)).to.equal(0.0625); - expect(exponent(5,-4)).to.equal(0.0016); - expect(exponent(2,-5)).to.equal(0.03125); - }); + it('returns 1 when exponent is 0', function () { + expect(exponent(8, 0)).to.equal(1); + expect(exponent(244, 0)).to.equal(1); + }); - it('should use recursion by calling self', function () { - var originalExponent = exponent; - exponent = sinon.spy(exponent); - exponent(3,4); - expect(exponent.callCount).to.be.above(1); - exponent = originalExponent; - }); + it('returns base when exponent is 1', function () { + expect(exponent(9, 1)).to.equal(9); + expect(exponent(2300, 1)).to.equal(2300); + }); + // it('BONUS: should accept negative integer for base', function() { + // expect(exponent(-3,4)).to.equal(-81); + // expect(exponent(-12,5)).to.equal(-248832); + // expect(exponent(-7,2)).to.equal(-49); + // expect(exponent(-7,4)).to.equal(-2401); + // }); + + it('should accept negative integer for exponent', function () { + expect(exponent(4, -2)).to.equal(0.0625); + expect(exponent(5, -4)).to.equal(0.0016); + expect(exponent(2, -5)).to.equal(0.03125); }); + it('should use recursion by calling self', function () { + var originalExponent = exponent; + exponent = sinon.spy(exponent); + exponent(3, 4); + expect(exponent.callCount).to.be.above(1); + exponent = originalExponent; + }); + }); - describe('8. Power of Two', function() { - it('should return a boolean', function() { - expect(typeof(powerOfTwo(10))).to.equal('boolean'); - expect(typeof(powerOfTwo(16))).to.equal('boolean'); - }); - it('should return true for powers of two', function() { - expect(powerOfTwo(0)).to.equal(false); - expect(powerOfTwo(1)).to.equal(true); - expect(powerOfTwo(2)).to.equal(true); - expect(powerOfTwo(10)).to.equal(false); - expect(powerOfTwo(128)).to.equal(true); - expect(powerOfTwo(256)).to.equal(true); - }); + describe('8. Power of Two', function () { - it('should use recursion by calling self', function () { - var originalPowerOfTwo = powerOfTwo; - powerOfTwo = sinon.spy(powerOfTwo); - powerOfTwo(32); - expect(powerOfTwo.callCount).to.be.above(1); - powerOfTwo = originalPowerOfTwo; - }); + it('should return a boolean', function () { + expect(typeof (powerOfTwo(10))).to.equal('boolean'); + expect(typeof (powerOfTwo(16))).to.equal('boolean'); + }); + it('should return true for powers of two', function () { + expect(powerOfTwo(0)).to.equal(false); + expect(powerOfTwo(1)).to.equal(true); + expect(powerOfTwo(2)).to.equal(true); + expect(powerOfTwo(10)).to.equal(false); + expect(powerOfTwo(128)).to.equal(true); + expect(powerOfTwo(256)).to.equal(true); }); + it('should use recursion by calling self', function () { + var originalPowerOfTwo = powerOfTwo; + powerOfTwo = sinon.spy(powerOfTwo); + powerOfTwo(32); + expect(powerOfTwo.callCount).to.be.above(1); + powerOfTwo = originalPowerOfTwo; + }); + }); - describe('9. Reverse String', function() { - it('should return a string', function() { - expect(typeof(reverse('orangutan'))).to.equal('string'); - }); - it('should return a string in reverse', function() { - var poem = 'Roses are red, violets are blue, all my base are belong to you.'; + describe('9. Reverse String', function () { - expect(reverse('Racecar')).to.equal('racecaR'); - expect(reverse(poem)).to.equal('.uoy ot gnoleb era esab ym lla ,eulb era steloiv ,der era sesoR'); - }); + it('should return a string', function () { + expect(typeof (reverse('orangutan'))).to.equal('string'); + }); - it('should not mutate the input string', function() { - var input = 'orangutan'; - var result = reverse(input); - expect(input).to.eql('orangutan'); - }); + it('should return a string in reverse', function () { + var poem = 'Roses are red, violets are blue, all my base are belong to you.'; - it('should use recursion by calling self', function () { - var originalReverse = reverse; - reverse = sinon.spy(reverse); - reverse('orangutan'); - expect(reverse.callCount).to.be.above(1); - reverse = originalReverse; - }); + expect(reverse('Racecar')).to.equal('racecaR'); + expect(reverse(poem)).to.equal('.uoy ot gnoleb era esab ym lla ,eulb era steloiv ,der era sesoR'); + }); + it('should not mutate the input string', function () { + var input = 'orangutan'; + var result = reverse(input); + expect(input).to.eql('orangutan'); }); + it('should use recursion by calling self', function () { + var originalReverse = reverse; + reverse = sinon.spy(reverse); + reverse('orangutan'); + expect(reverse.callCount).to.be.above(1); + reverse = originalReverse; + }); + }); - describe('10. Palindrome', function() { - it('should return a boolean', function() { - expect(typeof(palindrome('rotor'))).to.equal('boolean'); - expect(typeof(palindrome('motor'))).to.equal('boolean'); - }); - it('should return true for palindromes', function() { - expect(palindrome('rotor')).to.eql(true); - expect(palindrome('racecar')).to.eql(true); - expect(palindrome('saippuakivikauppias')).to.eql(true); - }); + describe('10. Palindrome', function () { - it('should return false for non-palindromes', function() { - expect(palindrome('motor')).to.eql(false); - expect(palindrome('orangutan')).to.eql(false); - expect(palindrome('antidisestablishmentarianism')).to.eql(false); - }); + it('should return a boolean', function () { + expect(typeof (palindrome('rotor'))).to.equal('boolean'); + expect(typeof (palindrome('motor'))).to.equal('boolean'); + }); - it('should ignore spaces and capital letters', function() { - expect(palindrome('Rotor')).to.eql(true); - expect(palindrome('race caR')).to.eql(true); - expect(palindrome('sAip puaki v iKaup Pias')).to.eql(true); - }); + it('should return true for palindromes', function () { + expect(palindrome('rotor')).to.eql(true); + expect(palindrome('racecar')).to.eql(true); + expect(palindrome('saippuakivikauppias')).to.eql(true); + }); - it('should use recursion by calling self', function () { - var originalPalindrome = palindrome; - palindrome = sinon.spy(palindrome); - palindrome('saippuakivikauppias'); - expect(palindrome.callCount).to.be.above(1); - palindrome = originalPalindrome; - }); + it('should return false for non-palindromes', function () { + expect(palindrome('motor')).to.eql(false); + expect(palindrome('orangutan')).to.eql(false); + expect(palindrome('antidisestablishmentarianism')).to.eql(false); + }); + it('should ignore spaces and capital letters', function () { + expect(palindrome('Rotor')).to.eql(true); + expect(palindrome('race caR')).to.eql(true); + expect(palindrome('sAip puaki v iKaup Pias')).to.eql(true); }); + it('should use recursion by calling self', function () { + var originalPalindrome = palindrome; + palindrome = sinon.spy(palindrome); + palindrome('saippuakivikauppias'); + expect(palindrome.callCount).to.be.above(1); + palindrome = originalPalindrome; + }); + }); - xdescribe('11. Modulo', function() { - it('should return a number', function() { - expect(typeof(modulo(5,2))).to.equal('number'); - expect(typeof(modulo(8,4))).to.equal('number'); - }); - it("should not use complex math", function() { - expect(modulo.toString()).to.not.contain('*'); - expect(modulo.toString()).to.not.contain('/'); - expect(modulo.toString()).to.not.contain('%'); - expect(modulo.toString()).to.not.contain('Math'); - }); + xdescribe('11. Modulo', function () { - it('should return the remainder of two integers', function() { - expect(modulo(2, 1)).to.equal(2 % 1); - expect(modulo(17, 5)).to.equal(17 % 5); - expect(modulo(78, 453)).to.equal(78 % 453); - expect(modulo(-79, 82)).to.equal(-79 % 82); - expect(modulo(-275, -502)).to.equal(-275 % -502); - expect(modulo(-275, -274)).to.equal(-275 % -274); - expect(modulo(-4, 2)).to.equal(-4 % 2); - expect(modulo(0, 32)).to.equal(0 % 32); - expect(modulo(0, 0).toString()).to.equal('NaN'); - }); + it('should return a number', function () { + expect(typeof (modulo(5, 2))).to.equal('number'); + expect(typeof (modulo(8, 4))).to.equal('number'); + }); - it('should use recursion by calling self', function () { - var originalModulo = modulo; - modulo = sinon.spy(modulo); - modulo(5,2); - expect(modulo.callCount).to.be.above(1); - modulo = originalModulo; - }); - - }); + it("should not use complex math", function () { + expect(modulo.toString()).to.not.contain('*'); + expect(modulo.toString()).to.not.contain('/'); + expect(modulo.toString()).to.not.contain('%'); + expect(modulo.toString()).to.not.contain('Math'); + }); + it('should return the remainder of two integers', function () { + expect(modulo(2, 1)).to.equal(2 % 1); + expect(modulo(17, 5)).to.equal(17 % 5); + expect(modulo(78, 453)).to.equal(78 % 453); + expect(modulo(-79, 82)).to.equal(-79 % 82); + expect(modulo(-275, -502)).to.equal(-275 % -502); + expect(modulo(-275, -274)).to.equal(-275 % -274); + expect(modulo(-4, 2)).to.equal(-4 % 2); + expect(modulo(0, 32)).to.equal(0 % 32); + expect(modulo(0, 0).toString()).to.equal('NaN'); + }); + it('should use recursion by calling self', function () { + var originalModulo = modulo; + modulo = sinon.spy(modulo); + modulo(5, 2); + expect(modulo.callCount).to.be.above(1); + modulo = originalModulo; + }); - describe('12. Multiply', function() { - - it('should return a number', function() { - expect(typeof(multiply(5,2))).to.equal('number'); - expect(typeof(multiply(8,4))).to.equal('number'); - }); - - it("should not use complex math", function() { - expect(multiply.toString()).to.not.contain('*'); - expect(multiply.toString()).to.not.contain('/'); - expect(multiply.toString()).to.not.contain('%'); - expect(multiply.toString()).to.not.contain('Math'); - }); + }); - it('should return the product of two integers', function() { - expect(multiply(2, 1)).to.equal(2 * 1); - expect(multiply(17, 5)).to.equal(17 * 5); - expect(multiply(78, 453)).to.equal(78 * 453); - expect(multiply(-79, 82)).to.equal(-79 * 82); - expect(multiply(-275, -502)).to.equal(-275 * -502); - expect(multiply(0, 32)).to.equal(0 * 32); - expect(multiply(0, 0)).to.equal(0 * 0); - }); - it('should use recursion by calling self', function () { - var originalMultiply = multiply; - multiply = sinon.spy(multiply); - multiply(8,4); - expect(multiply.callCount).to.be.above(1); - multiply = originalMultiply; - }); - - }); - - - - xdescribe('13. Divide', function() { - it('should return a number', function() { - expect(typeof(divide(5,2))).to.equal('number'); - expect(typeof(divide(8,4))).to.equal('number'); - }); + describe('12. Multiply', function () { - it("should not use complex math", function() { - expect(divide.toString()).to.not.contain('*'); - expect(divide.toString()).to.not.contain('/'); - expect(divide.toString()).to.not.contain('%'); - expect(divide.toString()).to.not.contain('Math'); - }); + it('should return a number', function () { + expect(typeof (multiply(5, 2))).to.equal('number'); + expect(typeof (multiply(8, 4))).to.equal('number'); + }); - it('should return the quotient of two integers', function() { - expect(divide(2, 1)).to.equal(~~(2 / 1)); - expect(divide(17, 5)).to.equal(~~(17 / 5)); - expect(divide(78, 453)).to.equal(~~(78 / 453)); - expect(divide(-79, 82)).to.equal(~~(-79 / 82)); - expect(divide(-275, -582)).to.equal(~~(-275 / -582)); - expect(divide(0, 32)).to.equal(~~(0 / 32)); - expect(divide(0, 0).toString()).to.equal('NaN'); - }); + it("should not use complex math", function () { + expect(multiply.toString()).to.not.contain('*'); + expect(multiply.toString()).to.not.contain('/'); + expect(multiply.toString()).to.not.contain('%'); + expect(multiply.toString()).to.not.contain('Math'); + }); - it('should use recursion by calling self', function () { - var originalDivide = divide; - divide = sinon.spy(divide); - divide(17, 5); - expect(divide.callCount).to.be.above(1); - divide = originalDivide; - }); + it('should return the product of two integers', function () { + expect(multiply(2, 1)).to.equal(2 * 1); + expect(multiply(17, 5)).to.equal(17 * 5); + expect(multiply(78, 453)).to.equal(78 * 453); + expect(multiply(-79, 82)).to.equal(-79 * 82); + expect(multiply(-275, -502)).to.equal(-275 * -502); + expect(multiply(0, 32)).to.equal(0 * 32); + expect(multiply(0, 0)).to.equal(0 * 0); + }); + it('should use recursion by calling self', function () { + var originalMultiply = multiply; + multiply = sinon.spy(multiply); + multiply(8, 4); + expect(multiply.callCount).to.be.above(1); + multiply = originalMultiply; }); + }); - xdescribe('14. Greatest Common Divisor', function() { - it('should return a number', function() { - expect(typeof(gcd(4,36))).to.equal('number'); - }); + xdescribe('13. Divide', function () { - it('should return greatest common divisor of two positive integers', function() { - expect(gcd(4,36)).to.equal(4); - expect(gcd(24,88)).to.equal(8); - expect(gcd(339,17)).to.equal(1); - expect(gcd(126,900)).to.equal(18); - }); + it('should return a number', function () { + expect(typeof (divide(5, 2))).to.equal('number'); + expect(typeof (divide(8, 4))).to.equal('number'); + }); - it('should return null for negative integers', function() { - expect(gcd(-4, 2)).to.equal(null); - expect(gcd(-5, 5)).to.equal(null); - expect(gcd(5, -5)).to.equal(null); - expect(gcd(7, -36)).to.equal(null); - expect(gcd(-10, -58)).to.equal(null); - expect(gcd(-92, -5)).to.equal(null); - // expect(gcd(0, 0)).to.equal(null); - // expect(gcd(0, 5)).to.equal(null); - // expect(gcd(5, 0)).to.equal(null); - // expect(gcd(-5, 0)).to.equal(null); - // expect(gcd(0, -5)).to.equal(null); - }); + it("should not use complex math", function () { + expect(divide.toString()).to.not.contain('*'); + expect(divide.toString()).to.not.contain('/'); + expect(divide.toString()).to.not.contain('%'); + expect(divide.toString()).to.not.contain('Math'); + }); - it('should use recursion by calling self', function () { - var originalGcd = gcd; - gcd = sinon.spy(gcd); - gcd(17, 5); - expect(gcd.callCount).to.be.above(1); - gcd = originalGcd; - }); + it('should return the quotient of two integers', function () { + expect(divide(2, 1)).to.equal(~~(2 / 1)); + expect(divide(17, 5)).to.equal(~~(17 / 5)); + expect(divide(78, 453)).to.equal(~~(78 / 453)); + expect(divide(-79, 82)).to.equal(~~(-79 / 82)); + expect(divide(-275, -582)).to.equal(~~(-275 / -582)); + expect(divide(0, 32)).to.equal(~~(0 / 32)); + expect(divide(0, 0).toString()).to.equal('NaN'); + }); + it('should use recursion by calling self', function () { + var originalDivide = divide; + divide = sinon.spy(divide); + divide(17, 5); + expect(divide.callCount).to.be.above(1); + divide = originalDivide; }); + }); - describe('15. Compare Strings', function() { - it('should return a boolean', function() { - expect(typeof(compareStr('house', 'houses'))).to.equal('boolean'); - expect(typeof(compareStr('', ''))).to.equal('boolean'); - expect(typeof(compareStr('tomato', 'tomato'))).to.equal('boolean'); - }); + xdescribe('14. Greatest Common Divisor', function () { - it('should return true for identical strings', function() { - expect(compareStr('house', 'houses')).to.eql(false); - expect(compareStr('', '')).to.eql(true); - expect(compareStr('tomato', 'tomato')).to.eql(true); - expect(compareStr('', 'pop')).to.eql(false); - expect(compareStr('foot', '')).to.eql(false); - expect(compareStr('big dog', 'big dog')).to.eql(true); - }); + it('should return a number', function () { + expect(typeof (gcd(4, 36))).to.equal('number'); + }); - it('should use recursion by calling self', function () { - var originalCompareStr = compareStr; - compareStr = sinon.spy(compareStr); - compareStr('house', 'houses'); - expect(compareStr.callCount).to.be.above(1); - compareStr = originalCompareStr; - }); + it('should return greatest common divisor of two positive integers', function () { + expect(gcd(4, 36)).to.equal(4); + expect(gcd(24, 88)).to.equal(8); + expect(gcd(339, 17)).to.equal(1); + expect(gcd(126, 900)).to.equal(18); + }); + it('should return null for negative integers', function () { + expect(gcd(-4, 2)).to.equal(null); + expect(gcd(-5, 5)).to.equal(null); + expect(gcd(5, -5)).to.equal(null); + expect(gcd(7, -36)).to.equal(null); + expect(gcd(-10, -58)).to.equal(null); + expect(gcd(-92, -5)).to.equal(null); + // expect(gcd(0, 0)).to.equal(null); + // expect(gcd(0, 5)).to.equal(null); + // expect(gcd(5, 0)).to.equal(null); + // expect(gcd(-5, 0)).to.equal(null); + // expect(gcd(0, -5)).to.equal(null); }); + it('should use recursion by calling self', function () { + var originalGcd = gcd; + gcd = sinon.spy(gcd); + gcd(17, 5); + expect(gcd.callCount).to.be.above(1); + gcd = originalGcd; + }); + }); - describe('16. Create array from string', function() { - it('should return an array', function() { - expect(Array.isArray(createArray('hello'))).to.equal(true); - }); - it('should return an array where each index is a letter of the string', function() { - expect(createArray('hello')).to.eql(['h','e','l','l','o']); - expect(createArray('this is not a pipe')).to.eql(['t','h','i','s',' ','i','s',' ','n','o','t',' ','a',' ','p','i','p','e']); - expect(createArray('hologram')).to.eql(['h','o','l','o','g','r','a','m']); - expect(createArray('i')).to.eql(['i']); - }); + describe('15. Compare Strings', function () { - it('should use recursion by calling self', function () { - var originalCreateArray = createArray; - createArray = sinon.spy(createArray); - createArray('hello'); - expect(createArray.callCount).to.be.above(1); - createArray = originalCreateArray; - }); + it('should return a boolean', function () { + expect(typeof (compareStr('house', 'houses'))).to.equal('boolean'); + expect(typeof (compareStr('', ''))).to.equal('boolean'); + expect(typeof (compareStr('tomato', 'tomato'))).to.equal('boolean'); + }); + it('should return true for identical strings', function () { + expect(compareStr('house', 'houses')).to.eql(false); + expect(compareStr('', '')).to.eql(true); + expect(compareStr('tomato', 'tomato')).to.eql(true); + expect(compareStr('', 'pop')).to.eql(false); + expect(compareStr('foot', '')).to.eql(false); + expect(compareStr('big dog', 'big dog')).to.eql(true); }); + it('should use recursion by calling self', function () { + var originalCompareStr = compareStr; + compareStr = sinon.spy(compareStr); + compareStr('house', 'houses'); + expect(compareStr.callCount).to.be.above(1); + compareStr = originalCompareStr; + }); + }); - describe('17. Reverse an array', function() { - it('should return an array', function() { - expect(Array.isArray(reverseArr([5,4,3,2,1]))).to.equal(true); - }); - it('should return array in reversed order', function() { - expect(reverseArr([1,2,3,4,5])).to.eql([5,4,3,2,1]); - expect(reverseArr([5,4,3,2,1])).to.eql([1,2,3,4,5]); - expect(reverseArr([2,4,6,8])).to.eql([8,6,4,2]); - expect(reverseArr([8,6,4,2])).to.eql([2,4,6,8]); - }); + describe('16. Create array from string', function () { - it('should use recursion by calling self', function () { - var originalReverseArr = reverseArr; - reverseArr = sinon.spy(reverseArr); - reverseArr([5,4,3,2,1]); - expect(reverseArr.callCount).to.be.above(1); - reverseArr = originalReverseArr; - }); + it('should return an array', function () { + expect(Array.isArray(createArray('hello'))).to.equal(true); + }); + it('should return an array where each index is a letter of the string', function () { + expect(createArray('hello')).to.eql(['h', 'e', 'l', 'l', 'o']); + expect(createArray('this is not a pipe')).to.eql(['t', 'h', 'i', 's', ' ', 'i', 's', ' ', 'n', 'o', 't', ' ', 'a', ' ', 'p', 'i', 'p', 'e']); + expect(createArray('hologram')).to.eql(['h', 'o', 'l', 'o', 'g', 'r', 'a', 'm']); + expect(createArray('i')).to.eql(['i']); }); + it('should use recursion by calling self', function () { + var originalCreateArray = createArray; + createArray = sinon.spy(createArray); + createArray('hello'); + expect(createArray.callCount).to.be.above(1); + createArray = originalCreateArray; + }); + }); - describe('18. Build an array with a given value and length', function() { - it('should return an array', function() { - expect(Array.isArray(buildList(0,5))).to.equal(true); - }); - it('should return array of given length with given value at each index', function() { - expect(buildList(0, 5)).to.eql([0,0,0,0,0]); - expect(buildList('banana', 3)).to.eql(['banana','banana','banana']); - expect(buildList(NaN, 4)).to.eql([NaN, NaN, NaN, NaN]); - expect(buildList(undefined, 1)).to.eql([undefined]); - expect(buildList([], 2)).to.eql([[],[]]); - expect(buildList({}, 4)).to.eql([{},{},{},{}]); - expect(buildList(true, 3)).to.eql([true,true,true]); - expect(buildList(5+5, 3)).to.eql([10,10,10]); - }); + describe('17. Reverse an array', function () { - it('should use recursion by calling self', function () { - var originalBuildList = buildList; - buildList = sinon.spy(buildList); - buildList(2,7); - expect(buildList.callCount).to.be.above(1); - buildList = originalBuildList; - }); + it('should return an array', function () { + expect(Array.isArray(reverseArr([5, 4, 3, 2, 1]))).to.equal(true); + }); + it('should return array in reversed order', function () { + expect(reverseArr([1, 2, 3, 4, 5])).to.eql([5, 4, 3, 2, 1]); + expect(reverseArr([5, 4, 3, 2, 1])).to.eql([1, 2, 3, 4, 5]); + expect(reverseArr([2, 4, 6, 8])).to.eql([8, 6, 4, 2]); + expect(reverseArr([8, 6, 4, 2])).to.eql([2, 4, 6, 8]); }); + it('should use recursion by calling self', function () { + var originalReverseArr = reverseArr; + reverseArr = sinon.spy(reverseArr); + reverseArr([5, 4, 3, 2, 1]); + expect(reverseArr.callCount).to.be.above(1); + reverseArr = originalReverseArr; + }); + }); - describe('19. Count value in array', function() { - it('should return a number', function() { - expect(typeof(countOccurrence([2,7,4,4,1,4], 4))).to.equal('number'); - expect(typeof(countOccurrence([2,'banana',4,4,1,'banana'], 'banana'))).to.equal('number'); - }); - it('should return the number of occurrences of the value', function() { - expect(countOccurrence([2,7,4,4,1,4], 4)).to.eql(3); - expect(countOccurrence([2,'banana',4,4,1,'banana'], 'banana')).to.eql(2); - expect(countOccurrence([undefined,7,undefined,4,1,4], undefined)).to.eql(2); - expect(countOccurrence(['',7,null,0,'0',false], 0)).to.eql(1); - expect(countOccurrence(['',7,null,0,'0',false], false)).to.eql(1); - expect(countOccurrence(['',7,null,0,'0',false], null)).to.eql(1); - expect(countOccurrence(['',7,null,0,'0',false], '')).to.eql(1); - // expect(countOccurrence(['',7,null,0,NaN,'0',false], NaN)).to.eql(1); - }); + describe('18. Build an array with a given value and length', function () { - it('should use recursion by calling self', function () { - var originalCountOccurrence = countOccurrence; - countOccurrence = sinon.spy(countOccurrence); - countOccurrence([2,7,4,4,1,4], 4); - expect(countOccurrence.callCount).to.be.above(1); - countOccurrence = originalCountOccurrence; - }); + it('should return an array', function () { + expect(Array.isArray(buildList(0, 5))).to.equal(true); + }); + it('should return array of given length with given value at each index', function () { + expect(buildList(0, 5)).to.eql([0, 0, 0, 0, 0]); + expect(buildList('banana', 3)).to.eql(['banana', 'banana', 'banana']); + expect(buildList(NaN, 4)).to.eql([NaN, NaN, NaN, NaN]); + expect(buildList(undefined, 1)).to.eql([undefined]); + expect(buildList([], 2)).to.eql([ + [], + [] + ]); + expect(buildList({}, 4)).to.eql([{}, {}, {}, {}]); + expect(buildList(true, 3)).to.eql([true, true, true]); + expect(buildList(5 + 5, 3)).to.eql([10, 10, 10]); }); + it('should use recursion by calling self', function () { + var originalBuildList = buildList; + buildList = sinon.spy(buildList); + buildList(2, 7); + expect(buildList.callCount).to.be.above(1); + buildList = originalBuildList; + }); + }); - describe('20. Recursive Map', function() { - var timesTwo = function(n) { return n * 2; }; - var input3 = [1,2,3,4,5]; - it('should return an array', function() { - expect(Array.isArray(rMap([1,2,3], timesTwo))).to.equal(true); - }); + describe('19. Count value in array', function () { - checkForNativeMethods(function() { - rMap([1,2,3,4], timesTwo); - }); + it('should return a number', function () { + expect(typeof (countOccurrence([2, 7, 4, 4, 1, 4], 4))).to.equal('number'); + expect(typeof (countOccurrence([2, 'banana', 4, 4, 1, 'banana'], 'banana'))).to.equal('number'); + }); - it('should return new array without mutating the input array', function() { - var input = [1,2,3,4,5]; - var result = rMap(input, function(num) { /* poop */ }); - expect(input).to.eql([1,2,3,4,5]); - expect(result).to.not.equal(input); - }); + it('should return the number of occurrences of the value', function () { + expect(countOccurrence([2, 7, 4, 4, 1, 4], 4)).to.eql(3); + expect(countOccurrence([2, 'banana', 4, 4, 1, 'banana'], 'banana')).to.eql(2); + expect(countOccurrence([undefined, 7, undefined, 4, 1, 4], undefined)).to.eql(2); + expect(countOccurrence(['', 7, null, 0, '0', false], 0)).to.eql(1); + expect(countOccurrence(['', 7, null, 0, '0', false], false)).to.eql(1); + expect(countOccurrence(['', 7, null, 0, '0', false], null)).to.eql(1); + expect(countOccurrence(['', 7, null, 0, '0', false], '')).to.eql(1); + // expect(countOccurrence(['',7,null,0,NaN,'0',false], NaN)).to.eql(1); + }); - it('should apply a function to every value in an array', function() { - var doubledNumbers = rMap([1,2,3], timesTwo); - expect(doubledNumbers).to.eql([2,4,6]); - }); + it('should use recursion by calling self', function () { + var originalCountOccurrence = countOccurrence; + countOccurrence = sinon.spy(countOccurrence); + countOccurrence([2, 7, 4, 4, 1, 4], 4); + expect(countOccurrence.callCount).to.be.above(1); + countOccurrence = originalCountOccurrence; + }); - it('should use recursion by calling self', function () { - var originalrMap = rMap; - rMap = sinon.spy(rMap); - rMap([1,2,3,4], timesTwo); - expect(rMap.callCount).to.be.above(1); - rMap = originalrMap; - }); + }); - }); + describe('20. Recursive Map', function () { - xdescribe('21. Count key in object', function() { - var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; + var timesTwo = function (n) { + return n * 2; + }; + var input3 = [1, 2, 3, 4, 5]; - it('should return a number', function() { - expect(typeof(countKeysInObj(input, 'r'))).to.equal('number'); - expect(typeof(countKeysInObj(input, 'e'))).to.equal('number'); - expect(typeof(countKeysInObj(input, 'p'))).to.equal('number'); - }); + it('should return an array', function () { + expect(Array.isArray(rMap([1, 2, 3], timesTwo))).to.equal(true); + }); - it('should return the number of occurrences of the property', function() { - expect(countKeysInObj(input, 'e')).to.eql(2); - expect(countKeysInObj(input, 'x')).to.eql(1); - expect(countKeysInObj(input, 'y')).to.eql(2); - expect(countKeysInObj(input, 't')).to.eql(1); - expect(countKeysInObj(input, 'r')).to.eql(1); - expect(countKeysInObj(input, 'p')).to.eql(1); - }); + checkForNativeMethods(function () { + rMap([1, 2, 3, 4], timesTwo); + }); - it('should use recursion by calling self', function () { - var originalCountKeysInObj = countKeysInObj; - countKeysInObj = sinon.spy(countKeysInObj); - countKeysInObj(input, 'e'); - expect(countKeysInObj.callCount).to.be.above(1); - countKeysInObj = originalCountKeysInObj; - }); + it('should return new array without mutating the input array', function () { + var input = [1, 2, 3, 4, 5]; + var result = rMap(input, function (num) { /* poop */ }); + expect(input).to.eql([1, 2, 3, 4, 5]); + expect(result).to.not.equal(input); + }); + it('should apply a function to every value in an array', function () { + var doubledNumbers = rMap([1, 2, 3], timesTwo); + expect(doubledNumbers).to.eql([2, 4, 6]); }); + it('should use recursion by calling self', function () { + var originalrMap = rMap; + rMap = sinon.spy(rMap); + rMap([1, 2, 3, 4], timesTwo); + expect(rMap.callCount).to.be.above(1); + rMap = originalrMap; + }); + }); - xdescribe('22. Count value in object', function() { - var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; - it('should return a number', function() { - expect(typeof(countValuesInObj(input, 'r'))).to.equal('number'); - expect(typeof(countValuesInObj(input, 'e'))).to.equal('number'); - expect(typeof(countValuesInObj(input, 'p'))).to.equal('number'); - }); - it('should return the count of the occurrences of the property', function() { - expect(countValuesInObj(input, 'e')).to.eql(1); - expect(countValuesInObj(input, 'x')).to.eql(0); - expect(countValuesInObj(input, 'y')).to.eql(1); - expect(countValuesInObj(input, 't')).to.eql(0); - expect(countValuesInObj(input, 'r')).to.eql(2); - expect(countValuesInObj(input, 'p')).to.eql(0); - }); + xdescribe('21. Count key in object', function () { + var input = { + 'e': { + 'x': 'y' + }, + 't': { + 'r': { + 'e': 'r' + }, + 'p': { + 'y': 'r' + } + }, + 'y': 'e' + }; + + it('should return a number', function () { + expect(typeof (countKeysInObj(input, 'r'))).to.equal('number'); + expect(typeof (countKeysInObj(input, 'e'))).to.equal('number'); + expect(typeof (countKeysInObj(input, 'p'))).to.equal('number'); + }); - it('should use recursion by calling self', function () { - var originalCountValuesInObj = countValuesInObj; - countValuesInObj = sinon.spy(countValuesInObj); - countValuesInObj(input, 'r'); - expect(countValuesInObj.callCount).to.be.above(1); - countValuesInObj = originalCountValuesInObj; - }); + it('should return the number of occurrences of the property', function () { + expect(countKeysInObj(input, 'e')).to.eql(2); + expect(countKeysInObj(input, 'x')).to.eql(1); + expect(countKeysInObj(input, 'y')).to.eql(2); + expect(countKeysInObj(input, 't')).to.eql(1); + expect(countKeysInObj(input, 'r')).to.eql(1); + expect(countKeysInObj(input, 'p')).to.eql(1); + }); + it('should use recursion by calling self', function () { + var originalCountKeysInObj = countKeysInObj; + countKeysInObj = sinon.spy(countKeysInObj); + countKeysInObj(input, 'e'); + expect(countKeysInObj.callCount).to.be.above(1); + countKeysInObj = originalCountKeysInObj; }); + }); - xdescribe('23. Replace keys in object', function() { - var tallyKeys = function(obj) { - var count = 0; - for (var k in obj) { - if (typeof obj[k] === 'object') { - count += tallyKeys(obj[k]); - } - count++; + xdescribe('22. Count value in object', function () { + var input = { + 'e': { + 'x': 'y' + }, + 't': { + 'r': { + 'e': 'r' + }, + 'p': { + 'y': 'r' } - return count; - }; + }, + 'y': 'e' + }; + + it('should return a number', function () { + expect(typeof (countValuesInObj(input, 'r'))).to.equal('number'); + expect(typeof (countValuesInObj(input, 'e'))).to.equal('number'); + expect(typeof (countValuesInObj(input, 'p'))).to.equal('number'); + }); - it('should return an object', function() { - var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; - expect(typeof(replaceKeysInObj(input, 'r', 'a'))).to.equal('object'); - expect(typeof(replaceKeysInObj(input, 'e', 0))).to.equal('object'); - }); - - it('should return object containing renamed keys', function() { - var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}}, 'y':'e'}; - var output = replaceKeysInObj(input, 'e', 'f'); - - expect(output.e).to.equal(undefined); - expect(output.f.x).to.equal('y'); - expect(output.t.r.e).to.equal(undefined); - expect(output.t.r.f).to.equal('r'); - expect(output.t.p.y).to.equal('r'); - expect(output.y).to.equal('e'); + it('should return the count of the occurrences of the property', function () { + expect(countValuesInObj(input, 'e')).to.eql(1); + expect(countValuesInObj(input, 'x')).to.eql(0); + expect(countValuesInObj(input, 'y')).to.eql(1); + expect(countValuesInObj(input, 't')).to.eql(0); + expect(countValuesInObj(input, 'r')).to.eql(2); + expect(countValuesInObj(input, 'p')).to.eql(0); + }); - expect(output.hasOwnProperty('e')).to.equal(false); - expect(output.hasOwnProperty('f')).to.equal(true); - expect(output.hasOwnProperty('t')).to.equal(true); - expect(output.hasOwnProperty('y')).to.equal(true); + it('should use recursion by calling self', function () { + var originalCountValuesInObj = countValuesInObj; + countValuesInObj = sinon.spy(countValuesInObj); + countValuesInObj(input, 'r'); + expect(countValuesInObj.callCount).to.be.above(1); + countValuesInObj = originalCountValuesInObj; + }); - expect(output.t.hasOwnProperty('r')).to.equal(true); - expect(output.t.hasOwnProperty('p')).to.equal(true); + }); - expect(output.t.r.hasOwnProperty('e')).to.equal(false); - expect(output.t.r.hasOwnProperty('f')).to.equal(true); - expect(output.t.p.hasOwnProperty('y')).to.equal(true); - }); - it('should return object with same number of keys', function () { - var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}}, 'y':'e'}; - var output1 = replaceKeysInObj(input, 'e', 'f'); - var output2 = replaceKeysInObj(output1, 'e', 'f'); - expect(tallyKeys(input)).to.equal(8); - expect(tallyKeys(output1)).to.equal(8); - expect(tallyKeys(output2)).to.equal(8); - }); - it('should use recursion by calling self', function () { - var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; - var originalReplaceKeysInObj = replaceKeysInObj; - replaceKeysInObj = sinon.spy(replaceKeysInObj); - replaceKeysInObj(input, 'r', 'a'); - expect(replaceKeysInObj.callCount).to.be.above(1); - replaceKeysInObj = originalReplaceKeysInObj; - }); + xdescribe('23. Replace keys in object', function () { + var tallyKeys = function (obj) { + var count = 0; + for (var k in obj) { + if (typeof obj[k] === 'object') { + count += tallyKeys(obj[k]); + } + count++; + } + return count; + }; + + it('should return an object', function () { + var input = { + 'e': { + 'x': 'y' + }, + 't': { + 'r': { + 'e': 'r' + }, + 'p': { + 'y': 'r' + } + }, + 'y': 'e' + }; + expect(typeof (replaceKeysInObj(input, 'r', 'a'))).to.equal('object'); + expect(typeof (replaceKeysInObj(input, 'e', 0))).to.equal('object'); }); + it('should return object containing renamed keys', function () { + var input = { + 'e': { + 'x': 'y' + }, + 't': { + 'r': { + 'e': 'r' + }, + 'p': { + 'y': 'r' + } + }, + 'y': 'e' + }; + var output = replaceKeysInObj(input, 'e', 'f'); + + expect(output.e).to.equal(undefined); + expect(output.f.x).to.equal('y'); + expect(output.t.r.e).to.equal(undefined); + expect(output.t.r.f).to.equal('r'); + expect(output.t.p.y).to.equal('r'); + expect(output.y).to.equal('e'); + + expect(output.hasOwnProperty('e')).to.equal(false); + expect(output.hasOwnProperty('f')).to.equal(true); + expect(output.hasOwnProperty('t')).to.equal(true); + expect(output.hasOwnProperty('y')).to.equal(true); + + expect(output.t.hasOwnProperty('r')).to.equal(true); + expect(output.t.hasOwnProperty('p')).to.equal(true); + + expect(output.t.r.hasOwnProperty('e')).to.equal(false); + expect(output.t.r.hasOwnProperty('f')).to.equal(true); + expect(output.t.p.hasOwnProperty('y')).to.equal(true); + }); - xdescribe('24. First n Fibonacci', function() { + it('should return object with same number of keys', function () { + var input = { + 'e': { + 'x': 'y' + }, + 't': { + 'r': { + 'e': 'r' + }, + 'p': { + 'y': 'r' + } + }, + 'y': 'e' + }; + var output1 = replaceKeysInObj(input, 'e', 'f'); + var output2 = replaceKeysInObj(output1, 'e', 'f'); + expect(tallyKeys(input)).to.equal(8); + expect(tallyKeys(output1)).to.equal(8); + expect(tallyKeys(output2)).to.equal(8); + }); + + it('should use recursion by calling self', function () { + var input = { + 'e': { + 'x': 'y' + }, + 't': { + 'r': { + 'e': 'r' + }, + 'p': { + 'y': 'r' + } + }, + 'y': 'e' + }; + var originalReplaceKeysInObj = replaceKeysInObj; + replaceKeysInObj = sinon.spy(replaceKeysInObj); + replaceKeysInObj(input, 'r', 'a'); + expect(replaceKeysInObj.callCount).to.be.above(1); + replaceKeysInObj = originalReplaceKeysInObj; + }); - it('should return an array', function() { - expect(Array.isArray(fibonacci(5))).to.equal(true); - }); + }); - it('should return first n Fibonacci numbers where n starts at index 1', function() { - expect(fibonacci(1)).to.eql([0, 1]); - expect(fibonacci(2)).to.eql([0, 1, 1]); - expect(fibonacci(3)).to.eql([0, 1, 1, 2]); - expect(fibonacci(4)).to.eql([0, 1, 1, 2, 3]); - expect(fibonacci(5)).to.eql([0, 1, 1, 2, 3, 5]); - expect(fibonacci(12)).to.eql([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]); - }); - it('should return null for zero and negative integers', function() { - expect(fibonacci(0)).to.equal(null); - expect(fibonacci(-7)).to.equal(null); - }); + xdescribe('24. First n Fibonacci', function () { + + it('should return an array', function () { + expect(Array.isArray(fibonacci(5))).to.equal(true); + }); - it('should use recursion by calling self', function () { - var originalFibonacci = fibonacci; - fibonacci = sinon.spy(fibonacci); - fibonacci(5); - expect(fibonacci.callCount).to.be.above(1); - fibonacci = originalFibonacci; - }); + it('should return first n Fibonacci numbers where n starts at index 1', function () { + expect(fibonacci(1)).to.eql([0, 1]); + expect(fibonacci(2)).to.eql([0, 1, 1]); + expect(fibonacci(3)).to.eql([0, 1, 1, 2]); + expect(fibonacci(4)).to.eql([0, 1, 1, 2, 3]); + expect(fibonacci(5)).to.eql([0, 1, 1, 2, 3, 5]); + expect(fibonacci(12)).to.eql([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]); + }); + it('should return null for zero and negative integers', function () { + expect(fibonacci(0)).to.equal(null); + expect(fibonacci(-7)).to.equal(null); }); + it('should use recursion by calling self', function () { + var originalFibonacci = fibonacci; + fibonacci = sinon.spy(fibonacci); + fibonacci(5); + expect(fibonacci.callCount).to.be.above(1); + fibonacci = originalFibonacci; + }); + }); - describe('25. Return nth Fibonacci', function() { - it('should return a number', function() { - expect(typeof(nthFibo(5))).to.equal('number'); - }); - it('should return the nth Fibonacci number', function() { - expect(nthFibo(0)).to.eql(0); - expect(nthFibo(1)).to.eql(1); - expect(nthFibo(2)).to.eql(1); - expect(nthFibo(3)).to.eql(2); - expect(nthFibo(4)).to.eql(3); - expect(nthFibo(5)).to.eql(5); - expect(nthFibo(12)).to.eql(144); - }); + describe('25. Return nth Fibonacci', function () { - it('should return null for negative integers', function() { - expect(nthFibo(-5)).to.equal(null); - expect(nthFibo(-7)).to.equal(null); - }); + it('should return a number', function () { + expect(typeof (nthFibo(5))).to.equal('number'); + }); - it('should use recursion by calling self', function () { - var originalNthFibo = nthFibo; - nthFibo = sinon.spy(nthFibo); - nthFibo(5); - expect(nthFibo.callCount).to.be.above(1); - nthFibo = originalNthFibo; - }); + it('should return the nth Fibonacci number', function () { + expect(nthFibo(0)).to.eql(0); + expect(nthFibo(1)).to.eql(1); + expect(nthFibo(2)).to.eql(1); + expect(nthFibo(3)).to.eql(2); + expect(nthFibo(4)).to.eql(3); + expect(nthFibo(5)).to.eql(5); + expect(nthFibo(12)).to.eql(144); + }); + it('should return null for negative integers', function () { + expect(nthFibo(-5)).to.equal(null); + expect(nthFibo(-7)).to.equal(null); }); + it('should use recursion by calling self', function () { + var originalNthFibo = nthFibo; + nthFibo = sinon.spy(nthFibo); + nthFibo(5); + expect(nthFibo.callCount).to.be.above(1); + nthFibo = originalNthFibo; + }); + }); - describe('26. Capitalize words in array', function() { - it('should return an array', function() { - expect(Array.isArray(capitalizeWords(['i','am','learning','recursion']))).to.equal(true); - }); - it('should capitalize all words in array', function() { - expect(capitalizeWords(['i','am','learning','recursion'])).to.eql(['I', 'AM', 'LEARNING', 'RECURSION']); - expect(capitalizeWords(["ceci","n'est","pas","une","pipe"])).to.eql(["CECI", "N'EST", "PAS", "UNE", "PIPE"]); - }); + describe('26. Capitalize words in array', function () { - it('should use recursion by calling self', function () { - var originalCapitalizeWords = capitalizeWords; - capitalizeWords = sinon.spy(capitalizeWords); - capitalizeWords(["ceci","n'est","pas","une","pipe"]); - expect(capitalizeWords.callCount).to.be.above(1); - capitalizeWords = originalCapitalizeWords; - }); + it('should return an array', function () { + expect(Array.isArray(capitalizeWords(['i', 'am', 'learning', 'recursion']))).to.equal(true); + }); + it('should capitalize all words in array', function () { + expect(capitalizeWords(['i', 'am', 'learning', 'recursion'])).to.eql(['I', 'AM', 'LEARNING', 'RECURSION']); + expect(capitalizeWords(["ceci", "n'est", "pas", "une", "pipe"])).to.eql(["CECI", "N'EST", "PAS", "UNE", "PIPE"]); }); + it('should use recursion by calling self', function () { + var originalCapitalizeWords = capitalizeWords; + capitalizeWords = sinon.spy(capitalizeWords); + capitalizeWords(["ceci", "n'est", "pas", "une", "pipe"]); + expect(capitalizeWords.callCount).to.be.above(1); + capitalizeWords = originalCapitalizeWords; + }); + }); - describe('27. Capitalize first letter of words in array', function() { - it('should return an array', function() { - expect(Array.isArray(capitalizeFirst(['i','am','learning','recursion']))).to.equal(true); - }); - it('should capitalize first letter of each word in array', function() { - expect(capitalizeFirst(['i','am','learning','recursion'])).to.eql(['I', 'Am', 'Learning', 'Recursion']); - expect(capitalizeFirst(["ceci","n'est","pas","une","pipe"])).to.eql(["Ceci", "N'est", "Pas", "Une", "Pipe"]); - }); + describe('27. Capitalize first letter of words in array', function () { - it('should use recursion by calling self', function () { - var originalCapitalizeFirst = capitalizeFirst; - capitalizeFirst = sinon.spy(capitalizeFirst); - capitalizeFirst(["ceci","n'est","pas","une","pipe"]); - expect(capitalizeFirst.callCount).to.be.above(1); - capitalizeFirst = originalCapitalizeFirst; - }); + it('should return an array', function () { + expect(Array.isArray(capitalizeFirst(['i', 'am', 'learning', 'recursion']))).to.equal(true); + }); + it('should capitalize first letter of each word in array', function () { + expect(capitalizeFirst(['i', 'am', 'learning', 'recursion'])).to.eql(['I', 'Am', 'Learning', 'Recursion']); + expect(capitalizeFirst(["ceci", "n'est", "pas", "une", "pipe"])).to.eql(["Ceci", "N'est", "Pas", "Une", "Pipe"]); }); + it('should use recursion by calling self', function () { + var originalCapitalizeFirst = capitalizeFirst; + capitalizeFirst = sinon.spy(capitalizeFirst); + capitalizeFirst(["ceci", "n'est", "pas", "une", "pipe"]); + expect(capitalizeFirst.callCount).to.be.above(1); + capitalizeFirst = originalCapitalizeFirst; + }); + }); - xdescribe('28. Sum even numbers in nested objects', function() { - var obj = { - a: 2, - b: {b: 2, bb: {b: 3, bb: {b: 2}}}, - c: {c: {c: 2}, cc: 'ball', ccc: 5}, - d: 1, - e: {e: {e: 2}, ee: 'car'} - }; - it('should return a number', function() { - expect(typeof(nestedEvenSum(obj))).to.equal('number'); - }); - it('should sum even numbers', function() { - expect(nestedEvenSum(obj)).to.eql(10); - }); + xdescribe('28. Sum even numbers in nested objects', function () { + var obj = { + a: 2, + b: { + b: 2, + bb: { + b: 3, + bb: { + b: 2 + } + } + }, + c: { + c: { + c: 2 + }, + cc: 'ball', + ccc: 5 + }, + d: 1, + e: { + e: { + e: 2 + }, + ee: 'car' + } + }; + + it('should return a number', function () { + expect(typeof (nestedEvenSum(obj))).to.equal('number'); + }); - it('should use recursion by calling self', function () { - var originalNestedEvenSum = nestedEvenSum; - nestedEvenSum = sinon.spy(nestedEvenSum); - nestedEvenSum(obj); - expect(nestedEvenSum.callCount).to.be.above(1); - nestedEvenSum = originalNestedEvenSum; - }); + it('should sum even numbers', function () { + expect(nestedEvenSum(obj)).to.eql(10); + }); + it('should use recursion by calling self', function () { + var originalNestedEvenSum = nestedEvenSum; + nestedEvenSum = sinon.spy(nestedEvenSum); + nestedEvenSum(obj); + expect(nestedEvenSum.callCount).to.be.above(1); + nestedEvenSum = originalNestedEvenSum; }); + }); - xdescribe('29. Flatten nested arrays', function() { - it('should return an array', function() { - expect(Array.isArray(flatten([1,[2],[3,[[4]]],5]))).to.equal(true); - }); + xdescribe('29. Flatten nested arrays', function () { - it('should return flattened array', function() { - expect(flatten([[1],[2,3],[[4]],5,6])).to.eql([1,2,3,4,5,6]); - expect(flatten([[12,[[34],[56]],78]])).to.eql([12,34,56,78]); - expect(flatten([3,[0,[34,[7,[18]]]]])).to.eql([3,0,34,7,18]); - expect(flatten([[1],[2,[],3],[],[[4]],5,6])).to.eql([1,2,3,4,5,6]); - }); + it('should return an array', function () { + expect(Array.isArray(flatten([1, [2], + [3, [ + [4] + ]], 5 + ]))).to.equal(true); + }); - it('should use recursion by calling self', function () { - var originalFlatten = flatten; - flatten = sinon.spy(flatten); - flatten([3,[0,[34,[7,[18]]]]]); - expect(flatten.callCount).to.be.above(1); - flatten = originalFlatten; - }); + it('should return flattened array', function () { + expect(flatten([ + [1], + [2, 3], + [ + [4] + ], 5, 6 + ])).to.eql([1, 2, 3, 4, 5, 6]); + expect(flatten([ + [12, [ + [34], + [56] + ], 78] + ])).to.eql([12, 34, 56, 78]); + expect(flatten([3, [0, [34, [7, [18]]]]])).to.eql([3, 0, 34, 7, 18]); + expect(flatten([ + [1], + [2, [], 3], + [], + [ + [4] + ], 5, 6 + ])).to.eql([1, 2, 3, 4, 5, 6]); + }); + it('should use recursion by calling self', function () { + var originalFlatten = flatten; + flatten = sinon.spy(flatten); + flatten([3, [0, [34, [7, [18]]]]]); + expect(flatten.callCount).to.be.above(1); + flatten = originalFlatten; }); + }); - describe('30. Tally letters in string', function() { - it('should return an object', function() { - expect(typeof(letterTally('orangutan'))).to.equal('object'); - }); + describe('30. Tally letters in string', function () { - it('should return object containing tallies of unique letters', function() { - var output = letterTally('potato'); + it('should return an object', function () { + expect(typeof (letterTally('orangutan'))).to.equal('object'); + }); - expect(output.p).to.equal(1); - expect(output.o).to.equal(2); - expect(output.t).to.equal(2); - expect(output.a).to.equal(1); - }); + it('should return object containing tallies of unique letters', function () { + var output = letterTally('potato'); - it('should return object containing the number of keys corresponding to unique letters', function () { - var output = letterTally('mississippi'); - var countKeys = Object.keys(output).length; - expect(countKeys).to.equal(4); - }); + expect(output.p).to.equal(1); + expect(output.o).to.equal(2); + expect(output.t).to.equal(2); + expect(output.a).to.equal(1); + }); - it('should use recursion by calling self', function () { - var originalLetterTally = letterTally; - letterTally = sinon.spy(letterTally); - letterTally('invasion'); - expect(letterTally.callCount).to.be.above(1); - letterTally = originalLetterTally; - }); + it('should return object containing the number of keys corresponding to unique letters', function () { + var output = letterTally('mississippi'); + var countKeys = Object.keys(output).length; + expect(countKeys).to.equal(4); + }); + it('should use recursion by calling self', function () { + var originalLetterTally = letterTally; + letterTally = sinon.spy(letterTally); + letterTally('invasion'); + expect(letterTally.callCount).to.be.above(1); + letterTally = originalLetterTally; }); + }); - describe('31. Eliminate consecutive duplicates', function() { - var input1 = [1,2,2,3,4,4,5,5,5]; - var input2 = [1,2,2,3,4,4,2,5,5,5,4,4]; - it('should return an array', function() { - expect(Array.isArray(compress(input1))).to.equal(true); - }); + describe('31. Eliminate consecutive duplicates', function () { + var input1 = [1, 2, 2, 3, 4, 4, 5, 5, 5]; + var input2 = [1, 2, 2, 3, 4, 4, 2, 5, 5, 5, 4, 4]; - it('should remove consecutive duplicates', function() { - expect(compress(input1)).to.eql([1,2,3,4,5]); - expect(compress(input2)).to.eql([1,2,3,4,2,5,4]); - }); + it('should return an array', function () { + expect(Array.isArray(compress(input1))).to.equal(true); + }); - it('should use recursion by calling self', function () { - var originalCompress = compress; - compress = sinon.spy(compress); - compress(input2); - expect(compress.callCount).to.be.above(1); - compress = originalCompress; - }); + it('should remove consecutive duplicates', function () { + expect(compress(input1)).to.eql([1, 2, 3, 4, 5]); + expect(compress(input2)).to.eql([1, 2, 3, 4, 2, 5, 4]); + }); + it('should use recursion by calling self', function () { + var originalCompress = compress; + compress = sinon.spy(compress); + compress(input2); + expect(compress.callCount).to.be.above(1); + compress = originalCompress; }); + }); - xdescribe('32. Augment each element in nested arrays', function() { - it('should return an array', function() { - expect(Array.isArray(augmentElements([[],[3],[7]], 5))).to.equal(true); - }); + xdescribe('32. Augment each element in nested arrays', function () { - it('should augment each element with given value', function() { - expect(augmentElements([[],[3],[7]], 5)).to.eql([[5],[3,5],[7,5]]); - expect(augmentElements([[],[3],[7]], null)).to.eql([[null],[3,null],[7,null]]); - expect(augmentElements([[],[3],[7]], '')).to.eql([[''],[3,''],[7,'']]); - }); + it('should return an array', function () { + expect(Array.isArray(augmentElements([ + [], + [3], + [7] + ], 5))).to.equal(true); + }); - it('should use recursion by calling self', function () { - var originalAugElements = augmentElements; - augmentElements = sinon.spy(augmentElements); - augmentElements([[],[3],[7]], 5); - expect(augmentElements.callCount).to.be.above(1); - augmentElements = originalAugElements; - }); + it('should augment each element with given value', function () { + expect(augmentElements([ + [], + [3], + [7] + ], 5)).to.eql([ + [5], + [3, 5], + [7, 5] + ]); + expect(augmentElements([ + [], + [3], + [7] + ], null)).to.eql([ + [null], + [3, null], + [7, null] + ]); + expect(augmentElements([ + [], + [3], + [7] + ], '')).to.eql([ + [''], + [3, ''], + [7, ''] + ]); + }); + it('should use recursion by calling self', function () { + var originalAugElements = augmentElements; + augmentElements = sinon.spy(augmentElements); + augmentElements([ + [], + [3], + [7] + ], 5); + expect(augmentElements.callCount).to.be.above(1); + augmentElements = originalAugElements; }); + }); - describe('33. Minimize zeroes', function() { - var input1 = [2,0,0,0,1,4]; - var input2 = [2,0,0,0,1,0,0,4]; - it('should return an array', function() { - expect(Array.isArray(minimizeZeroes(input1))).to.equal(true); - }); + describe('33. Minimize zeroes', function () { + var input1 = [2, 0, 0, 0, 1, 4]; + var input2 = [2, 0, 0, 0, 1, 0, 0, 4]; - it('should remove excess zeroes', function() { - expect(minimizeZeroes(input1)).to.eql([2,0,1,4]); - expect(minimizeZeroes(input2)).to.eql([2,0,1,0,4]); - }); + it('should return an array', function () { + expect(Array.isArray(minimizeZeroes(input1))).to.equal(true); + }); - it('should use recursion by calling self', function () { - var originalMinZeroes = minimizeZeroes; - minimizeZeroes = sinon.spy(minimizeZeroes); - minimizeZeroes(input1); - expect(minimizeZeroes.callCount).to.be.above(1); - minimizeZeroes = originalMinZeroes; - }); + it('should remove excess zeroes', function () { + expect(minimizeZeroes(input1)).to.eql([2, 0, 1, 4]); + expect(minimizeZeroes(input2)).to.eql([2, 0, 1, 0, 4]); + }); + it('should use recursion by calling self', function () { + var originalMinZeroes = minimizeZeroes; + minimizeZeroes = sinon.spy(minimizeZeroes); + minimizeZeroes(input1); + expect(minimizeZeroes.callCount).to.be.above(1); + minimizeZeroes = originalMinZeroes; }); + }); - describe('34. Alternate sign', function() { - var input1 = [2,7,8,3,1,4]; - var input2 = [-2,-7,8,3,-1,4]; - it('should return an array', function() { - expect(Array.isArray(alternateSign(input1))).to.equal(true); - }); + describe('34. Alternate sign', function () { + var input1 = [2, 7, 8, 3, 1, 4]; + var input2 = [-2, -7, 8, 3, -1, 4]; - it('should remove excess zeroes', function() { - expect(alternateSign(input1)).to.eql([2,-7,8,-3,1,-4]); - expect(alternateSign(input2)).to.eql([2,-7,8,-3,1,-4]); - }); + it('should return an array', function () { + expect(Array.isArray(alternateSign(input1))).to.equal(true); + }); - it('should use recursion by calling self', function () { - var originalAltSign = alternateSign; - alternateSign = sinon.spy(alternateSign); - alternateSign(input1); - expect(alternateSign.callCount).to.be.above(1); - alternateSign = originalAltSign; - }); + it('should remove excess zeroes', function () { + expect(alternateSign(input1)).to.eql([2, -7, 8, -3, 1, -4]); + expect(alternateSign(input2)).to.eql([2, -7, 8, -3, 1, -4]); + }); + it('should use recursion by calling self', function () { + var originalAltSign = alternateSign; + alternateSign = sinon.spy(alternateSign); + alternateSign(input1); + expect(alternateSign.callCount).to.be.above(1); + alternateSign = originalAltSign; }); + }); - xdescribe('35. Convert numbers to text', function() { - it('should return a string', function() { - expect(typeof(numToText("I have 5 dogs and 6 ponies"))).to.equal('string'); - }); + xdescribe('35. Convert numbers to text', function () { - it('should convert single digits to their word equivalent', function() { - expect(numToText("I have 5 dogs and 6 ponies")).to.eql("I have five dogs and six ponies"); - expect(numToText("It takes 3 men to screw in 1 light bulb")).to.eql("It takes three men to screw in one light bulb"); - }); + it('should return a string', function () { + expect(typeof (numToText("I have 5 dogs and 6 ponies"))).to.equal('string'); + }); - it('should use recursion by calling self', function () { - var originalNumToText = numToText; - numToText = sinon.spy(numToText); - numToText("I have 5 dogs and 6 ponies"); - expect(numToText.callCount).to.be.above(1); - numToText = originalNumToText; - }); + it('should convert single digits to their word equivalent', function () { + expect(numToText("I have 5 dogs and 6 ponies")).to.eql("I have five dogs and six ponies"); + expect(numToText("It takes 3 men to screw in 1 light bulb")).to.eql("It takes three men to screw in one light bulb"); + }); + it('should use recursion by calling self', function () { + var originalNumToText = numToText; + numToText = sinon.spy(numToText); + numToText("I have 5 dogs and 6 ponies"); + expect(numToText.callCount).to.be.above(1); + numToText = originalNumToText; }); }); - function checkForNativeMethods(runFunction) { - it('should not use the native version of map', function() { - // These spies are set up in testSupport.js - runFunction(); - expect(Array.prototype.map.called).to.equal(false); - }); - } +}); +function checkForNativeMethods(runFunction) { + it('should not use the native version of map', function () { + // These spies are set up in testSupport.js + runFunction(); + expect(Array.prototype.map.called).to.equal(false); + }); +} From b04e25751f598e15af67018702fd21ddc60c8993 Mon Sep 17 00:00:00 2001 From: Jay Kindell Date: Tue, 23 Oct 2018 17:37:26 -0500 Subject: [PATCH 08/36] adds karma config & global location variable --- .travis.yml | 19 +++++++++++++++++++ SpecRunner.html | 2 +- karma.conf.js | 33 +++++++++++++++++++++++++++++++++ lib/location.js | 1 + lib/testSupport.js | 30 ++++++++++++++++-------------- package.json | 15 +++++++++++++-- 6 files changed, 83 insertions(+), 17 deletions(-) create mode 100644 .travis.yml create mode 100644 karma.conf.js create mode 100644 lib/location.js diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..cc644d875 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,19 @@ +language: node_js +node_js: + - "7" +dist: trusty # needs Ubuntu Trusty +sudo: true # needed for Chromium sandbox +addons: + chrome: stable # have Travis install chrome stable. +cache: + yarn: true + directories: + - node_modules +before_install: + - google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost & +install: + - yarn +script: + - yarn test +notifications: + webhooks: https://greenlight.operationspark.org/api/v2/webhooks/travisci diff --git a/SpecRunner.html b/SpecRunner.html index 5a18ca964..ef5fa35ff 100644 --- a/SpecRunner.html +++ b/SpecRunner.html @@ -4,7 +4,7 @@ Recursion Test Suite - + diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 000000000..f8a81dabc --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,33 @@ +const ChromiumRevision = require('puppeteer/package.json').puppeteer.chromium_revision +const Downloader = require('puppeteer/utils/ChromiumDownloader') +const revisionInfo = Downloader.revisionInfo(Downloader.currentPlatform(), ChromiumRevision) + +process.env.CHROME_BIN = revisionInfo.executablePath + +module.exports = function (config) { + config.set({ + frameworks: ['chai', 'mocha', 'sinon-chai', 'sinon'], + files: [ + 'lib/location.js', + { pattern: 'lib/css/mocha.css', included: false, served: true }, + { pattern: 'lib/chai.js', included: false, served: true }, + { pattern: 'lib/mocha.js', included: false, served: true }, + { pattern: 'lib/sinon.js', included: false, served: true }, + { pattern: 'lib/sinon-chai.js', included: false, served: true }, + { pattern: 'lib/cardboard.js', included: false, served: true }, + { pattern: 'lib/testSupport.js', included: false, served: true }, + { pattern: 'lib/jquery.js', included: false, served: true }, + { pattern: 'SpecRunner.html', included: true, served: true }, + { pattern: 'src/recursion.js', included: false, served: true }, + { pattern: 'spec/*.js', included: false, served: true }, + ], + reporters: ['progress'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + browsers: ['ChromeHeadless'], + autoWatch: false, + concurrency: Infinity, + globals: {inKarma: true} + }) +} \ No newline at end of file diff --git a/lib/location.js b/lib/location.js new file mode 100644 index 000000000..35563f1e6 --- /dev/null +++ b/lib/location.js @@ -0,0 +1 @@ +window.inKarma = true; \ No newline at end of file diff --git a/lib/testSupport.js b/lib/testSupport.js index a733c25e0..6f60e1cd0 100755 --- a/lib/testSupport.js +++ b/lib/testSupport.js @@ -1,26 +1,28 @@ -(function() { +(function () { 'use strict'; - mocha.setup({ ui: 'bdd', reporter: cardboard }); + window.inKarma ? mocha.setup({ ui: 'tdd', reporter: cardboard }) : mocha.setup({ ui: 'bdd', reporter: cardboard }); + // console.log(window.inKarma); + // mocha.setup({ reporter: cardboard }); window.expect = chai.expect; - window.onload = function() { + window.onload = function () { window.mochaPhantomJS ? mochaPhantomJS.run() : mocha.run(); }; // Disabling native methods is dangerous, we should spy on them instead - before(function() { - sinon.spy(Array.prototype,'map'); - sinon.spy(Array.prototype,'indexOf'); - sinon.spy(Array.prototype,'forEach'); - sinon.spy(Array.prototype,'filter'); - sinon.spy(Array.prototype,'reduce'); - sinon.spy(Array.prototype,'every'); - sinon.spy(Array.prototype,'some'); - sinon.spy(Array.prototype,'sort'); + before(function () { + sinon.spy(Array.prototype, 'map'); + sinon.spy(Array.prototype, 'indexOf'); + sinon.spy(Array.prototype, 'forEach'); + sinon.spy(Array.prototype, 'filter'); + sinon.spy(Array.prototype, 'reduce'); + sinon.spy(Array.prototype, 'every'); + sinon.spy(Array.prototype, 'some'); + sinon.spy(Array.prototype, 'sort'); }); - afterEach(function() { + afterEach(function () { Array.prototype.map.reset(); Array.prototype.indexOf.reset(); Array.prototype.forEach.reset(); @@ -31,7 +33,7 @@ Array.prototype.sort.reset(); }); - after(function() { + after(function () { Array.prototype.map.restore(); Array.prototype.indexOf.restore(); Array.prototype.forEach.restore(); diff --git a/package.json b/package.json index 4e6ef9dbc..a3402d8c5 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ }, "scripts": { "pretest": "npm install", - "test": "mocha ./test || :" + "test": "karma start --single-run --browsers ChromeHeadless karma.conf.js" }, "repository": { "type": "git", @@ -24,6 +24,17 @@ "devDependencies": { "chai": "^4.1.2", "mocha": "^5.2.0", - "sinon": "^5.0.10" + "sinon": "^5.0.10", + "karma": "^1.7.1", + "karma-chai": "^0.1.0", + "karma-chrome-launcher": "^2.2.0", + "karma-mocha": "^1.3.0", + "puppeteer": "^0.11.0" + }, + "dependencies": { + "karma-sinon": "^1.0.5", + "karma-sinon-chai": "^1.3.2", + "sinon": "^4.0.1", + "sinon-chai": "^2.14.0" } } From 340121038f274a455ff8607dd6378bf98d52cbf1 Mon Sep 17 00:00:00 2001 From: Jay Kindell Date: Tue, 23 Oct 2018 17:40:32 -0500 Subject: [PATCH 09/36] remove folder with node tests --- test/mocha.opts | 1 - test/part1.js | 1419 ----------------------------------------------- 2 files changed, 1420 deletions(-) delete mode 100644 test/mocha.opts delete mode 100755 test/part1.js diff --git a/test/mocha.opts b/test/mocha.opts deleted file mode 100644 index b512b38b9..000000000 --- a/test/mocha.opts +++ /dev/null @@ -1 +0,0 @@ ---reporter json \ No newline at end of file diff --git a/test/part1.js b/test/part1.js deleted file mode 100755 index 427a409cc..000000000 --- a/test/part1.js +++ /dev/null @@ -1,1419 +0,0 @@ -const path = require('path'); -const expect = require('chai').expect; -const sinon = require('sinon'); - -const { - factorial, - sum, - isEven, - sumBelow, - range, - exponent, - powerOfTwo, - reverse, - palindrome, - multiply, - compareStr, - createArray, - reverseArr, - buildList, - countOccurrence, - rMap, - nthFibo, - capitalizeWords, - capitalizeFirst, - letterTally, - compress, - minimizeZeroes, - alternateSign, -} = require(path.join(__dirname, '..', './src/recursion.js')); - -describe('Exercises in Recursion...', function () { - - describe('1. Factorial', function () { - - it('should return a number', function () { - expect(typeof (factorial(5))).to.equal('number'); - }); - - it('should return factorial for non-negative integers', function () { - expect(factorial(0)).to.equal(1); - expect(factorial(1)).to.equal(1); - expect(factorial(4)).to.equal(24); - expect(factorial(5)).to.equal(120); - }); - - it('should return null for negative integers', function () { - expect(factorial(-5)).to.equal(null); - }); - - it('should use recursion by calling self', function () { - var originalFactorial = factorial; - factorial = sinon.spy(factorial); - factorial(4); - expect(factorial.callCount).to.be.above(1); - factorial = originalFactorial; - }); - - }); - - - - describe('2. Sum of Integers', function () { - - it('should return a number', function () { - expect(typeof (sum([1, 2, 3, 4, 5, 6]))).to.eql('number'); - }); - - it('should return the sum of an array of non-negative integers', function () { - expect(sum([1, 2, 3, 4, 5, 6])).to.eql(21); - expect(sum([12, 34, 56, 78])).to.eql(180); - expect(sum([3, 0, 34, 7, 18])).to.eql(62); - }); - - it('should return the sum of an array of negative integers', function () { - expect(sum([-1, -2, -3, -4, -5, -6])).to.eql(-21); - expect(sum([-12, -34, -56, -78])).to.eql(-180); - expect(sum([-3, -0, -34, -7, -18])).to.eql(-62); - }); - - it('should return the sum of an array of mixed non-negative and negative integers', function () { - expect(sum([1, -2, 3, -4, 5, -6])).to.eql(-3); - expect(sum([-12, 34, -56, 78])).to.eql(44); - expect(sum([3, 0, -34, -7, 18])).to.eql(-20); - }); - - it('should return 0 for empty array', function () { - expect(sum([])).to.eql(0); - }); - - it('should accept an array with a single integer', function () { - expect(sum([4])).to.eql(4); - expect(sum([0])).to.eql(0); - expect(sum([-37])).to.eql(-37); - }); - - it('should not mutate the input array', function () { - var input = [1, 2, 3, 4, 5]; - var result = sum(input); - expect(input).to.eql([1, 2, 3, 4, 5]); - }); - - it('should use recursion by calling self', function () { - var originalSum = sum; - sum = sinon.spy(sum); - sum([1, 2, 3, 4, 5, 6]); - expect(sum.callCount).to.be.above(1); - sum = originalSum; - }); - - }); - - - - xdescribe('3. Sum Integers in Array', function () { - - it('should return a number', function () { - expect(typeof (arraySum([ - [1], - [2, 3], - [ - [4] - ], 5, 6 - ]))).to.eql('number'); - }); - - it('should return the sum of an array with nested arrays of non-negative integers', function () { - expect(arraySum([ - [1], - [2, 3], - [ - [4] - ], 5, 6 - ])).to.eql(21); - expect(arraySum([ - [12, [ - [34], - [56] - ], 78] - ])).to.eql(180); - expect(arraySum([3, [0, [34, [7, [18]]]]])).to.eql(62); - }); - - it('should return the sum of an array with nested arrays of negative integers', function () { - expect(arraySum([ - [-1], - [-2, -3], - [ - [-4] - ], -5, -6 - ])).to.eql(-21); - expect(arraySum([ - [-12, [ - [-34], - [-56] - ], -78] - ])).to.eql(-180); - expect(arraySum([-3, [0, [-34, [-7, [-18]]]]])).to.eql(-62); - }); - - it('should return the sum of an array with nested arrays of mixed non-negative and negative integers', function () { - expect(arraySum([ - [1], - [-2, 3], - [ - [-4] - ], 5, -6 - ])).to.eql(-3); - expect(arraySum([ - [-12, [ - [34], - [-56] - ], 78] - ])).to.eql(44); - expect(arraySum([3, [0, [-34, [-7, [18]]]]])).to.eql(-20); - }); - - it('should return 0 for empty array', function () { - expect(arraySum([])).to.eql(0); - }); - - it('should accept an array with a single integer', function () { - expect(arraySum([4])).to.eql(4); - expect(arraySum([0])).to.eql(0); - expect(arraySum([-37])).to.eql(-37); - }); - - it('should not mutate the input array', function () { - var input = [ - [1], - [2, 3], - [ - [4] - ], 5, 6 - ]; - var result = arraySum(input); - expect(input).to.eql([ - [1], - [2, 3], - [ - [4] - ], 5, 6 - ]); - }); - - it('should use recursion by calling self', function () { - var originalArraySum = arraySum; - arraySum = sinon.spy(arraySum); - arraySum([ - [1], - [2, 3], - [ - [4] - ], 5, 6 - ]); - expect(arraySum.callCount).to.be.above(1); - arraySum = originalArraySum; - }); - - }); - - - - describe('4. Check if Even', function () { - - it('should return a boolean', function () { - expect(typeof (isEven(5))).to.equal('boolean'); - expect(typeof (isEven(8))).to.equal('boolean'); - expect(typeof (isEven(-4))).to.equal('boolean'); - }); - - it("should not use modulo", function () { - expect(isEven.toString()).to.not.contain('%'); - }); - - it('should return true for even numbers', function () { - expect(isEven(118)).to.equal(true); - expect(isEven(10)).to.equal(true); - expect(isEven(0)).to.equal(true); - expect(isEven(-34)).to.equal(true); - }); - - it('should return false for odd numbers', function () { - expect(isEven(117)).to.equal(false); - expect(isEven(9)).to.equal(false); - expect(isEven(1)).to.equal(false); - expect(isEven(-33)).to.equal(false); - }); - - it('should work with negative integers', function () { - expect(isEven(-14)).to.equal(true); - expect(isEven(-81)).to.equal(false); - }); - - it('should use recursion by calling self', function () { - var originalIsEven = isEven; - isEven = sinon.spy(isEven); - isEven(118); - expect(isEven.callCount).to.be.above(1); - isEven = originalIsEven; - }); - - }); - - - - describe('5. Sum Below', function () { - - it('should return a number', function () { - expect(typeof (sumBelow(10))).to.eql('number'); - }); - - it('should return the sum of non-negative integers below given integer', function () { - expect(sumBelow(0)).to.eql(0); - expect(sumBelow(1)).to.eql(0); - expect(sumBelow(2)).to.eql(1); - expect(sumBelow(7)).to.eql(21); - expect(sumBelow(21)).to.eql(210); - expect(sumBelow(92)).to.eql(4186); - }); - - it('should return the sum of an array of negative integers', function () { - expect(sumBelow(-1)).to.eql(0); - expect(sumBelow(-2)).to.eql(-1); - expect(sumBelow(-6)).to.eql(-15); - expect(sumBelow(-21)).to.eql(-210); - expect(sumBelow(-92)).to.eql(-4186); - }); - - it('should use recursion by calling self', function () { - var originalSumBelow = sumBelow; - sumBelow = sinon.spy(sumBelow); - sumBelow(10); - expect(sumBelow.callCount).to.be.above(1); - sumBelow = originalSumBelow; - }); - - }); - - - - describe('6. Integer Range', function () { - - it('should return an array', function () { - expect(Array.isArray(range(2, 7))).to.equal(true); - }); - - it('should return the integers between two numbers', function () { - expect(range(3, 8)).to.eql([4, 5, 6, 7]); - expect(range(127, 131)).to.eql([128, 129, 130]); - }); - - it('should return empty array if no integers in range', function () { - expect(range(5, 5)).to.eql([]); - expect(range(2, 3)).to.eql([]); - }); - - it('should accept negative integers', function () { - expect(range(-9, -4)).to.eql([-8, -7, -6, -5]); - expect(range(-3, 2)).to.eql([-2, -1, 0, 1]); - expect(range(-3, -2)).to.eql([]); - expect(range(-2, -2)).to.eql([]); - }); - - it('should accept starting integer that\'s larger than ending', function () { - expect(range(7, 2)).to.eql([6, 5, 4, 3]); - expect(range(3, -3)).to.eql([2, 1, 0, -1, -2]); - expect(range(-9, -4)).to.eql([-8, -7, -6, -5]); - }); - - it('should use recursion by calling self', function () { - var originalRange = range; - range = sinon.spy(range); - range(3, 8); - expect(range.callCount).to.be.above(1); - range = originalRange; - }); - - }); - - - - describe('7. Compute Exponent', function () { - - it('should return a number', function () { - expect(typeof (exponent(4, 3))).to.eql('number'); - }); - - it("should not use complex math", function () { - expect(exponent.toString()).to.not.contain('Math'); - }); - - it('should compute exponent of non-negative integers', function () { - expect(exponent(3, 4)).to.equal(81); - expect(exponent(12, 5)).to.equal(248832); - expect(exponent(7, 2)).to.equal(49); - }); - - it('returns 1 when exponent is 0', function () { - expect(exponent(8, 0)).to.equal(1); - expect(exponent(244, 0)).to.equal(1); - }); - - it('returns base when exponent is 1', function () { - expect(exponent(9, 1)).to.equal(9); - expect(exponent(2300, 1)).to.equal(2300); - }); - - // it('BONUS: should accept negative integer for base', function() { - // expect(exponent(-3,4)).to.equal(-81); - // expect(exponent(-12,5)).to.equal(-248832); - // expect(exponent(-7,2)).to.equal(-49); - // expect(exponent(-7,4)).to.equal(-2401); - // }); - - it('should accept negative integer for exponent', function () { - expect(exponent(4, -2)).to.equal(0.0625); - expect(exponent(5, -4)).to.equal(0.0016); - expect(exponent(2, -5)).to.equal(0.03125); - }); - - it('should use recursion by calling self', function () { - var originalExponent = exponent; - exponent = sinon.spy(exponent); - exponent(3, 4); - expect(exponent.callCount).to.be.above(1); - exponent = originalExponent; - }); - - }); - - - - describe('8. Power of Two', function () { - - it('should return a boolean', function () { - expect(typeof (powerOfTwo(10))).to.equal('boolean'); - expect(typeof (powerOfTwo(16))).to.equal('boolean'); - }); - - it('should return true for powers of two', function () { - expect(powerOfTwo(0)).to.equal(false); - expect(powerOfTwo(1)).to.equal(true); - expect(powerOfTwo(2)).to.equal(true); - expect(powerOfTwo(10)).to.equal(false); - expect(powerOfTwo(128)).to.equal(true); - expect(powerOfTwo(256)).to.equal(true); - }); - - it('should use recursion by calling self', function () { - var originalPowerOfTwo = powerOfTwo; - powerOfTwo = sinon.spy(powerOfTwo); - powerOfTwo(32); - expect(powerOfTwo.callCount).to.be.above(1); - powerOfTwo = originalPowerOfTwo; - }); - - }); - - - - describe('9. Reverse String', function () { - - it('should return a string', function () { - expect(typeof (reverse('orangutan'))).to.equal('string'); - }); - - it('should return a string in reverse', function () { - var poem = 'Roses are red, violets are blue, all my base are belong to you.'; - - expect(reverse('Racecar')).to.equal('racecaR'); - expect(reverse(poem)).to.equal('.uoy ot gnoleb era esab ym lla ,eulb era steloiv ,der era sesoR'); - }); - - it('should not mutate the input string', function () { - var input = 'orangutan'; - var result = reverse(input); - expect(input).to.eql('orangutan'); - }); - - it('should use recursion by calling self', function () { - var originalReverse = reverse; - reverse = sinon.spy(reverse); - reverse('orangutan'); - expect(reverse.callCount).to.be.above(1); - reverse = originalReverse; - }); - - }); - - - - describe('10. Palindrome', function () { - - it('should return a boolean', function () { - expect(typeof (palindrome('rotor'))).to.equal('boolean'); - expect(typeof (palindrome('motor'))).to.equal('boolean'); - }); - - it('should return true for palindromes', function () { - expect(palindrome('rotor')).to.eql(true); - expect(palindrome('racecar')).to.eql(true); - expect(palindrome('saippuakivikauppias')).to.eql(true); - }); - - it('should return false for non-palindromes', function () { - expect(palindrome('motor')).to.eql(false); - expect(palindrome('orangutan')).to.eql(false); - expect(palindrome('antidisestablishmentarianism')).to.eql(false); - }); - - it('should ignore spaces and capital letters', function () { - expect(palindrome('Rotor')).to.eql(true); - expect(palindrome('race caR')).to.eql(true); - expect(palindrome('sAip puaki v iKaup Pias')).to.eql(true); - }); - - it('should use recursion by calling self', function () { - var originalPalindrome = palindrome; - palindrome = sinon.spy(palindrome); - palindrome('saippuakivikauppias'); - expect(palindrome.callCount).to.be.above(1); - palindrome = originalPalindrome; - }); - - }); - - - - xdescribe('11. Modulo', function () { - - it('should return a number', function () { - expect(typeof (modulo(5, 2))).to.equal('number'); - expect(typeof (modulo(8, 4))).to.equal('number'); - }); - - it("should not use complex math", function () { - expect(modulo.toString()).to.not.contain('*'); - expect(modulo.toString()).to.not.contain('/'); - expect(modulo.toString()).to.not.contain('%'); - expect(modulo.toString()).to.not.contain('Math'); - }); - - it('should return the remainder of two integers', function () { - expect(modulo(2, 1)).to.equal(2 % 1); - expect(modulo(17, 5)).to.equal(17 % 5); - expect(modulo(78, 453)).to.equal(78 % 453); - expect(modulo(-79, 82)).to.equal(-79 % 82); - expect(modulo(-275, -502)).to.equal(-275 % -502); - expect(modulo(-275, -274)).to.equal(-275 % -274); - expect(modulo(-4, 2)).to.equal(-4 % 2); - expect(modulo(0, 32)).to.equal(0 % 32); - expect(modulo(0, 0).toString()).to.equal('NaN'); - }); - - it('should use recursion by calling self', function () { - var originalModulo = modulo; - modulo = sinon.spy(modulo); - modulo(5, 2); - expect(modulo.callCount).to.be.above(1); - modulo = originalModulo; - }); - - }); - - - - describe('12. Multiply', function () { - - it('should return a number', function () { - expect(typeof (multiply(5, 2))).to.equal('number'); - expect(typeof (multiply(8, 4))).to.equal('number'); - }); - - it("should not use complex math", function () { - expect(multiply.toString()).to.not.contain('*'); - expect(multiply.toString()).to.not.contain('/'); - expect(multiply.toString()).to.not.contain('%'); - expect(multiply.toString()).to.not.contain('Math'); - }); - - it('should return the product of two integers', function () { - expect(multiply(2, 1)).to.equal(2 * 1); - expect(multiply(17, 5)).to.equal(17 * 5); - expect(multiply(78, 453)).to.equal(78 * 453); - expect(multiply(-79, 82)).to.equal(-79 * 82); - expect(multiply(-275, -502)).to.equal(-275 * -502); - expect(multiply(0, 32)).to.equal(0 * 32); - expect(multiply(0, 0)).to.equal(0 * 0); - }); - - it('should use recursion by calling self', function () { - var originalMultiply = multiply; - multiply = sinon.spy(multiply); - multiply(8, 4); - expect(multiply.callCount).to.be.above(1); - multiply = originalMultiply; - }); - - }); - - - - xdescribe('13. Divide', function () { - - it('should return a number', function () { - expect(typeof (divide(5, 2))).to.equal('number'); - expect(typeof (divide(8, 4))).to.equal('number'); - }); - - it("should not use complex math", function () { - expect(divide.toString()).to.not.contain('*'); - expect(divide.toString()).to.not.contain('/'); - expect(divide.toString()).to.not.contain('%'); - expect(divide.toString()).to.not.contain('Math'); - }); - - it('should return the quotient of two integers', function () { - expect(divide(2, 1)).to.equal(~~(2 / 1)); - expect(divide(17, 5)).to.equal(~~(17 / 5)); - expect(divide(78, 453)).to.equal(~~(78 / 453)); - expect(divide(-79, 82)).to.equal(~~(-79 / 82)); - expect(divide(-275, -582)).to.equal(~~(-275 / -582)); - expect(divide(0, 32)).to.equal(~~(0 / 32)); - expect(divide(0, 0).toString()).to.equal('NaN'); - }); - - it('should use recursion by calling self', function () { - var originalDivide = divide; - divide = sinon.spy(divide); - divide(17, 5); - expect(divide.callCount).to.be.above(1); - divide = originalDivide; - }); - - }); - - - - xdescribe('14. Greatest Common Divisor', function () { - - it('should return a number', function () { - expect(typeof (gcd(4, 36))).to.equal('number'); - }); - - it('should return greatest common divisor of two positive integers', function () { - expect(gcd(4, 36)).to.equal(4); - expect(gcd(24, 88)).to.equal(8); - expect(gcd(339, 17)).to.equal(1); - expect(gcd(126, 900)).to.equal(18); - }); - - it('should return null for negative integers', function () { - expect(gcd(-4, 2)).to.equal(null); - expect(gcd(-5, 5)).to.equal(null); - expect(gcd(5, -5)).to.equal(null); - expect(gcd(7, -36)).to.equal(null); - expect(gcd(-10, -58)).to.equal(null); - expect(gcd(-92, -5)).to.equal(null); - // expect(gcd(0, 0)).to.equal(null); - // expect(gcd(0, 5)).to.equal(null); - // expect(gcd(5, 0)).to.equal(null); - // expect(gcd(-5, 0)).to.equal(null); - // expect(gcd(0, -5)).to.equal(null); - }); - - it('should use recursion by calling self', function () { - var originalGcd = gcd; - gcd = sinon.spy(gcd); - gcd(17, 5); - expect(gcd.callCount).to.be.above(1); - gcd = originalGcd; - }); - - }); - - - - describe('15. Compare Strings', function () { - - it('should return a boolean', function () { - expect(typeof (compareStr('house', 'houses'))).to.equal('boolean'); - expect(typeof (compareStr('', ''))).to.equal('boolean'); - expect(typeof (compareStr('tomato', 'tomato'))).to.equal('boolean'); - }); - - it('should return true for identical strings', function () { - expect(compareStr('house', 'houses')).to.eql(false); - expect(compareStr('', '')).to.eql(true); - expect(compareStr('tomato', 'tomato')).to.eql(true); - expect(compareStr('', 'pop')).to.eql(false); - expect(compareStr('foot', '')).to.eql(false); - expect(compareStr('big dog', 'big dog')).to.eql(true); - }); - - it('should use recursion by calling self', function () { - var originalCompareStr = compareStr; - compareStr = sinon.spy(compareStr); - compareStr('house', 'houses'); - expect(compareStr.callCount).to.be.above(1); - compareStr = originalCompareStr; - }); - - }); - - - - describe('16. Create array from string', function () { - - it('should return an array', function () { - expect(Array.isArray(createArray('hello'))).to.equal(true); - }); - - it('should return an array where each index is a letter of the string', function () { - expect(createArray('hello')).to.eql(['h', 'e', 'l', 'l', 'o']); - expect(createArray('this is not a pipe')).to.eql(['t', 'h', 'i', 's', ' ', 'i', 's', ' ', 'n', 'o', 't', ' ', 'a', ' ', 'p', 'i', 'p', 'e']); - expect(createArray('hologram')).to.eql(['h', 'o', 'l', 'o', 'g', 'r', 'a', 'm']); - expect(createArray('i')).to.eql(['i']); - }); - - it('should use recursion by calling self', function () { - var originalCreateArray = createArray; - createArray = sinon.spy(createArray); - createArray('hello'); - expect(createArray.callCount).to.be.above(1); - createArray = originalCreateArray; - }); - - }); - - - - describe('17. Reverse an array', function () { - - it('should return an array', function () { - expect(Array.isArray(reverseArr([5, 4, 3, 2, 1]))).to.equal(true); - }); - - it('should return array in reversed order', function () { - expect(reverseArr([1, 2, 3, 4, 5])).to.eql([5, 4, 3, 2, 1]); - expect(reverseArr([5, 4, 3, 2, 1])).to.eql([1, 2, 3, 4, 5]); - expect(reverseArr([2, 4, 6, 8])).to.eql([8, 6, 4, 2]); - expect(reverseArr([8, 6, 4, 2])).to.eql([2, 4, 6, 8]); - }); - - it('should use recursion by calling self', function () { - var originalReverseArr = reverseArr; - reverseArr = sinon.spy(reverseArr); - reverseArr([5, 4, 3, 2, 1]); - expect(reverseArr.callCount).to.be.above(1); - reverseArr = originalReverseArr; - }); - - }); - - - - describe('18. Build an array with a given value and length', function () { - - it('should return an array', function () { - expect(Array.isArray(buildList(0, 5))).to.equal(true); - }); - - it('should return array of given length with given value at each index', function () { - expect(buildList(0, 5)).to.eql([0, 0, 0, 0, 0]); - expect(buildList('banana', 3)).to.eql(['banana', 'banana', 'banana']); - expect(buildList(NaN, 4)).to.eql([NaN, NaN, NaN, NaN]); - expect(buildList(undefined, 1)).to.eql([undefined]); - expect(buildList([], 2)).to.eql([ - [], - [] - ]); - expect(buildList({}, 4)).to.eql([{}, {}, {}, {}]); - expect(buildList(true, 3)).to.eql([true, true, true]); - expect(buildList(5 + 5, 3)).to.eql([10, 10, 10]); - }); - - it('should use recursion by calling self', function () { - var originalBuildList = buildList; - buildList = sinon.spy(buildList); - buildList(2, 7); - expect(buildList.callCount).to.be.above(1); - buildList = originalBuildList; - }); - - }); - - - - describe('19. Count value in array', function () { - - it('should return a number', function () { - expect(typeof (countOccurrence([2, 7, 4, 4, 1, 4], 4))).to.equal('number'); - expect(typeof (countOccurrence([2, 'banana', 4, 4, 1, 'banana'], 'banana'))).to.equal('number'); - }); - - it('should return the number of occurrences of the value', function () { - expect(countOccurrence([2, 7, 4, 4, 1, 4], 4)).to.eql(3); - expect(countOccurrence([2, 'banana', 4, 4, 1, 'banana'], 'banana')).to.eql(2); - expect(countOccurrence([undefined, 7, undefined, 4, 1, 4], undefined)).to.eql(2); - expect(countOccurrence(['', 7, null, 0, '0', false], 0)).to.eql(1); - expect(countOccurrence(['', 7, null, 0, '0', false], false)).to.eql(1); - expect(countOccurrence(['', 7, null, 0, '0', false], null)).to.eql(1); - expect(countOccurrence(['', 7, null, 0, '0', false], '')).to.eql(1); - // expect(countOccurrence(['',7,null,0,NaN,'0',false], NaN)).to.eql(1); - }); - - it('should use recursion by calling self', function () { - var originalCountOccurrence = countOccurrence; - countOccurrence = sinon.spy(countOccurrence); - countOccurrence([2, 7, 4, 4, 1, 4], 4); - expect(countOccurrence.callCount).to.be.above(1); - countOccurrence = originalCountOccurrence; - }); - - }); - - - - describe('20. Recursive Map', function () { - - var timesTwo = function (n) { - return n * 2; - }; - var input3 = [1, 2, 3, 4, 5]; - - it('should return an array', function () { - expect(Array.isArray(rMap([1, 2, 3], timesTwo))).to.equal(true); - }); - - checkForNativeMethods(function () { - rMap([1, 2, 3, 4], timesTwo); - }); - - it('should return new array without mutating the input array', function () { - var input = [1, 2, 3, 4, 5]; - var result = rMap(input, function (num) { /* poop */ }); - expect(input).to.eql([1, 2, 3, 4, 5]); - expect(result).to.not.equal(input); - }); - - it('should apply a function to every value in an array', function () { - var doubledNumbers = rMap([1, 2, 3], timesTwo); - expect(doubledNumbers).to.eql([2, 4, 6]); - }); - - it('should use recursion by calling self', function () { - var originalrMap = rMap; - rMap = sinon.spy(rMap); - rMap([1, 2, 3, 4], timesTwo); - expect(rMap.callCount).to.be.above(1); - rMap = originalrMap; - }); - - }); - - - - xdescribe('21. Count key in object', function () { - var input = { - 'e': { - 'x': 'y' - }, - 't': { - 'r': { - 'e': 'r' - }, - 'p': { - 'y': 'r' - } - }, - 'y': 'e' - }; - - it('should return a number', function () { - expect(typeof (countKeysInObj(input, 'r'))).to.equal('number'); - expect(typeof (countKeysInObj(input, 'e'))).to.equal('number'); - expect(typeof (countKeysInObj(input, 'p'))).to.equal('number'); - }); - - it('should return the number of occurrences of the property', function () { - expect(countKeysInObj(input, 'e')).to.eql(2); - expect(countKeysInObj(input, 'x')).to.eql(1); - expect(countKeysInObj(input, 'y')).to.eql(2); - expect(countKeysInObj(input, 't')).to.eql(1); - expect(countKeysInObj(input, 'r')).to.eql(1); - expect(countKeysInObj(input, 'p')).to.eql(1); - }); - - it('should use recursion by calling self', function () { - var originalCountKeysInObj = countKeysInObj; - countKeysInObj = sinon.spy(countKeysInObj); - countKeysInObj(input, 'e'); - expect(countKeysInObj.callCount).to.be.above(1); - countKeysInObj = originalCountKeysInObj; - }); - - }); - - - - xdescribe('22. Count value in object', function () { - var input = { - 'e': { - 'x': 'y' - }, - 't': { - 'r': { - 'e': 'r' - }, - 'p': { - 'y': 'r' - } - }, - 'y': 'e' - }; - - it('should return a number', function () { - expect(typeof (countValuesInObj(input, 'r'))).to.equal('number'); - expect(typeof (countValuesInObj(input, 'e'))).to.equal('number'); - expect(typeof (countValuesInObj(input, 'p'))).to.equal('number'); - }); - - it('should return the count of the occurrences of the property', function () { - expect(countValuesInObj(input, 'e')).to.eql(1); - expect(countValuesInObj(input, 'x')).to.eql(0); - expect(countValuesInObj(input, 'y')).to.eql(1); - expect(countValuesInObj(input, 't')).to.eql(0); - expect(countValuesInObj(input, 'r')).to.eql(2); - expect(countValuesInObj(input, 'p')).to.eql(0); - }); - - it('should use recursion by calling self', function () { - var originalCountValuesInObj = countValuesInObj; - countValuesInObj = sinon.spy(countValuesInObj); - countValuesInObj(input, 'r'); - expect(countValuesInObj.callCount).to.be.above(1); - countValuesInObj = originalCountValuesInObj; - }); - - }); - - - - xdescribe('23. Replace keys in object', function () { - - var tallyKeys = function (obj) { - var count = 0; - for (var k in obj) { - if (typeof obj[k] === 'object') { - count += tallyKeys(obj[k]); - } - count++; - } - return count; - }; - - it('should return an object', function () { - var input = { - 'e': { - 'x': 'y' - }, - 't': { - 'r': { - 'e': 'r' - }, - 'p': { - 'y': 'r' - } - }, - 'y': 'e' - }; - expect(typeof (replaceKeysInObj(input, 'r', 'a'))).to.equal('object'); - expect(typeof (replaceKeysInObj(input, 'e', 0))).to.equal('object'); - }); - - it('should return object containing renamed keys', function () { - var input = { - 'e': { - 'x': 'y' - }, - 't': { - 'r': { - 'e': 'r' - }, - 'p': { - 'y': 'r' - } - }, - 'y': 'e' - }; - var output = replaceKeysInObj(input, 'e', 'f'); - - expect(output.e).to.equal(undefined); - expect(output.f.x).to.equal('y'); - expect(output.t.r.e).to.equal(undefined); - expect(output.t.r.f).to.equal('r'); - expect(output.t.p.y).to.equal('r'); - expect(output.y).to.equal('e'); - - expect(output.hasOwnProperty('e')).to.equal(false); - expect(output.hasOwnProperty('f')).to.equal(true); - expect(output.hasOwnProperty('t')).to.equal(true); - expect(output.hasOwnProperty('y')).to.equal(true); - - expect(output.t.hasOwnProperty('r')).to.equal(true); - expect(output.t.hasOwnProperty('p')).to.equal(true); - - expect(output.t.r.hasOwnProperty('e')).to.equal(false); - expect(output.t.r.hasOwnProperty('f')).to.equal(true); - expect(output.t.p.hasOwnProperty('y')).to.equal(true); - }); - - it('should return object with same number of keys', function () { - var input = { - 'e': { - 'x': 'y' - }, - 't': { - 'r': { - 'e': 'r' - }, - 'p': { - 'y': 'r' - } - }, - 'y': 'e' - }; - var output1 = replaceKeysInObj(input, 'e', 'f'); - var output2 = replaceKeysInObj(output1, 'e', 'f'); - expect(tallyKeys(input)).to.equal(8); - expect(tallyKeys(output1)).to.equal(8); - expect(tallyKeys(output2)).to.equal(8); - }); - - it('should use recursion by calling self', function () { - var input = { - 'e': { - 'x': 'y' - }, - 't': { - 'r': { - 'e': 'r' - }, - 'p': { - 'y': 'r' - } - }, - 'y': 'e' - }; - var originalReplaceKeysInObj = replaceKeysInObj; - replaceKeysInObj = sinon.spy(replaceKeysInObj); - replaceKeysInObj(input, 'r', 'a'); - expect(replaceKeysInObj.callCount).to.be.above(1); - replaceKeysInObj = originalReplaceKeysInObj; - }); - - }); - - - xdescribe('24. First n Fibonacci', function () { - - it('should return an array', function () { - expect(Array.isArray(fibonacci(5))).to.equal(true); - }); - - it('should return first n Fibonacci numbers where n starts at index 1', function () { - expect(fibonacci(1)).to.eql([0, 1]); - expect(fibonacci(2)).to.eql([0, 1, 1]); - expect(fibonacci(3)).to.eql([0, 1, 1, 2]); - expect(fibonacci(4)).to.eql([0, 1, 1, 2, 3]); - expect(fibonacci(5)).to.eql([0, 1, 1, 2, 3, 5]); - expect(fibonacci(12)).to.eql([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]); - }); - - it('should return null for zero and negative integers', function () { - expect(fibonacci(0)).to.equal(null); - expect(fibonacci(-7)).to.equal(null); - }); - - it('should use recursion by calling self', function () { - var originalFibonacci = fibonacci; - fibonacci = sinon.spy(fibonacci); - fibonacci(5); - expect(fibonacci.callCount).to.be.above(1); - fibonacci = originalFibonacci; - }); - - }); - - - - describe('25. Return nth Fibonacci', function () { - - it('should return a number', function () { - expect(typeof (nthFibo(5))).to.equal('number'); - }); - - it('should return the nth Fibonacci number', function () { - expect(nthFibo(0)).to.eql(0); - expect(nthFibo(1)).to.eql(1); - expect(nthFibo(2)).to.eql(1); - expect(nthFibo(3)).to.eql(2); - expect(nthFibo(4)).to.eql(3); - expect(nthFibo(5)).to.eql(5); - expect(nthFibo(12)).to.eql(144); - }); - - it('should return null for negative integers', function () { - expect(nthFibo(-5)).to.equal(null); - expect(nthFibo(-7)).to.equal(null); - }); - - it('should use recursion by calling self', function () { - var originalNthFibo = nthFibo; - nthFibo = sinon.spy(nthFibo); - nthFibo(5); - expect(nthFibo.callCount).to.be.above(1); - nthFibo = originalNthFibo; - }); - - }); - - - - describe('26. Capitalize words in array', function () { - - it('should return an array', function () { - expect(Array.isArray(capitalizeWords(['i', 'am', 'learning', 'recursion']))).to.equal(true); - }); - - it('should capitalize all words in array', function () { - expect(capitalizeWords(['i', 'am', 'learning', 'recursion'])).to.eql(['I', 'AM', 'LEARNING', 'RECURSION']); - expect(capitalizeWords(["ceci", "n'est", "pas", "une", "pipe"])).to.eql(["CECI", "N'EST", "PAS", "UNE", "PIPE"]); - }); - - it('should use recursion by calling self', function () { - var originalCapitalizeWords = capitalizeWords; - capitalizeWords = sinon.spy(capitalizeWords); - capitalizeWords(["ceci", "n'est", "pas", "une", "pipe"]); - expect(capitalizeWords.callCount).to.be.above(1); - capitalizeWords = originalCapitalizeWords; - }); - - }); - - - - describe('27. Capitalize first letter of words in array', function () { - - it('should return an array', function () { - expect(Array.isArray(capitalizeFirst(['i', 'am', 'learning', 'recursion']))).to.equal(true); - }); - - it('should capitalize first letter of each word in array', function () { - expect(capitalizeFirst(['i', 'am', 'learning', 'recursion'])).to.eql(['I', 'Am', 'Learning', 'Recursion']); - expect(capitalizeFirst(["ceci", "n'est", "pas", "une", "pipe"])).to.eql(["Ceci", "N'est", "Pas", "Une", "Pipe"]); - }); - - it('should use recursion by calling self', function () { - var originalCapitalizeFirst = capitalizeFirst; - capitalizeFirst = sinon.spy(capitalizeFirst); - capitalizeFirst(["ceci", "n'est", "pas", "une", "pipe"]); - expect(capitalizeFirst.callCount).to.be.above(1); - capitalizeFirst = originalCapitalizeFirst; - }); - - }); - - - - xdescribe('28. Sum even numbers in nested objects', function () { - var obj = { - a: 2, - b: { - b: 2, - bb: { - b: 3, - bb: { - b: 2 - } - } - }, - c: { - c: { - c: 2 - }, - cc: 'ball', - ccc: 5 - }, - d: 1, - e: { - e: { - e: 2 - }, - ee: 'car' - } - }; - - it('should return a number', function () { - expect(typeof (nestedEvenSum(obj))).to.equal('number'); - }); - - it('should sum even numbers', function () { - expect(nestedEvenSum(obj)).to.eql(10); - }); - - it('should use recursion by calling self', function () { - var originalNestedEvenSum = nestedEvenSum; - nestedEvenSum = sinon.spy(nestedEvenSum); - nestedEvenSum(obj); - expect(nestedEvenSum.callCount).to.be.above(1); - nestedEvenSum = originalNestedEvenSum; - }); - - }); - - - - xdescribe('29. Flatten nested arrays', function () { - - it('should return an array', function () { - expect(Array.isArray(flatten([1, [2], - [3, [ - [4] - ]], 5 - ]))).to.equal(true); - }); - - it('should return flattened array', function () { - expect(flatten([ - [1], - [2, 3], - [ - [4] - ], 5, 6 - ])).to.eql([1, 2, 3, 4, 5, 6]); - expect(flatten([ - [12, [ - [34], - [56] - ], 78] - ])).to.eql([12, 34, 56, 78]); - expect(flatten([3, [0, [34, [7, [18]]]]])).to.eql([3, 0, 34, 7, 18]); - expect(flatten([ - [1], - [2, [], 3], - [], - [ - [4] - ], 5, 6 - ])).to.eql([1, 2, 3, 4, 5, 6]); - }); - - it('should use recursion by calling self', function () { - var originalFlatten = flatten; - flatten = sinon.spy(flatten); - flatten([3, [0, [34, [7, [18]]]]]); - expect(flatten.callCount).to.be.above(1); - flatten = originalFlatten; - }); - - }); - - - - describe('30. Tally letters in string', function () { - - it('should return an object', function () { - expect(typeof (letterTally('orangutan'))).to.equal('object'); - }); - - it('should return object containing tallies of unique letters', function () { - var output = letterTally('potato'); - - expect(output.p).to.equal(1); - expect(output.o).to.equal(2); - expect(output.t).to.equal(2); - expect(output.a).to.equal(1); - }); - - it('should return object containing the number of keys corresponding to unique letters', function () { - var output = letterTally('mississippi'); - var countKeys = Object.keys(output).length; - expect(countKeys).to.equal(4); - }); - - it('should use recursion by calling self', function () { - var originalLetterTally = letterTally; - letterTally = sinon.spy(letterTally); - letterTally('invasion'); - expect(letterTally.callCount).to.be.above(1); - letterTally = originalLetterTally; - }); - - }); - - - - describe('31. Eliminate consecutive duplicates', function () { - var input1 = [1, 2, 2, 3, 4, 4, 5, 5, 5]; - var input2 = [1, 2, 2, 3, 4, 4, 2, 5, 5, 5, 4, 4]; - - it('should return an array', function () { - expect(Array.isArray(compress(input1))).to.equal(true); - }); - - it('should remove consecutive duplicates', function () { - expect(compress(input1)).to.eql([1, 2, 3, 4, 5]); - expect(compress(input2)).to.eql([1, 2, 3, 4, 2, 5, 4]); - }); - - it('should use recursion by calling self', function () { - var originalCompress = compress; - compress = sinon.spy(compress); - compress(input2); - expect(compress.callCount).to.be.above(1); - compress = originalCompress; - }); - - }); - - - - xdescribe('32. Augment each element in nested arrays', function () { - - it('should return an array', function () { - expect(Array.isArray(augmentElements([ - [], - [3], - [7] - ], 5))).to.equal(true); - }); - - it('should augment each element with given value', function () { - expect(augmentElements([ - [], - [3], - [7] - ], 5)).to.eql([ - [5], - [3, 5], - [7, 5] - ]); - expect(augmentElements([ - [], - [3], - [7] - ], null)).to.eql([ - [null], - [3, null], - [7, null] - ]); - expect(augmentElements([ - [], - [3], - [7] - ], '')).to.eql([ - [''], - [3, ''], - [7, ''] - ]); - }); - - it('should use recursion by calling self', function () { - var originalAugElements = augmentElements; - augmentElements = sinon.spy(augmentElements); - augmentElements([ - [], - [3], - [7] - ], 5); - expect(augmentElements.callCount).to.be.above(1); - augmentElements = originalAugElements; - }); - - }); - - - - describe('33. Minimize zeroes', function () { - var input1 = [2, 0, 0, 0, 1, 4]; - var input2 = [2, 0, 0, 0, 1, 0, 0, 4]; - - it('should return an array', function () { - expect(Array.isArray(minimizeZeroes(input1))).to.equal(true); - }); - - it('should remove excess zeroes', function () { - expect(minimizeZeroes(input1)).to.eql([2, 0, 1, 4]); - expect(minimizeZeroes(input2)).to.eql([2, 0, 1, 0, 4]); - }); - - it('should use recursion by calling self', function () { - var originalMinZeroes = minimizeZeroes; - minimizeZeroes = sinon.spy(minimizeZeroes); - minimizeZeroes(input1); - expect(minimizeZeroes.callCount).to.be.above(1); - minimizeZeroes = originalMinZeroes; - }); - - }); - - - - describe('34. Alternate sign', function () { - var input1 = [2, 7, 8, 3, 1, 4]; - var input2 = [-2, -7, 8, 3, -1, 4]; - - it('should return an array', function () { - expect(Array.isArray(alternateSign(input1))).to.equal(true); - }); - - it('should remove excess zeroes', function () { - expect(alternateSign(input1)).to.eql([2, -7, 8, -3, 1, -4]); - expect(alternateSign(input2)).to.eql([2, -7, 8, -3, 1, -4]); - }); - - it('should use recursion by calling self', function () { - var originalAltSign = alternateSign; - alternateSign = sinon.spy(alternateSign); - alternateSign(input1); - expect(alternateSign.callCount).to.be.above(1); - alternateSign = originalAltSign; - }); - - }); - - - - xdescribe('35. Convert numbers to text', function () { - - it('should return a string', function () { - expect(typeof (numToText("I have 5 dogs and 6 ponies"))).to.equal('string'); - }); - - it('should convert single digits to their word equivalent', function () { - expect(numToText("I have 5 dogs and 6 ponies")).to.eql("I have five dogs and six ponies"); - expect(numToText("It takes 3 men to screw in 1 light bulb")).to.eql("It takes three men to screw in one light bulb"); - }); - - it('should use recursion by calling self', function () { - var originalNumToText = numToText; - numToText = sinon.spy(numToText); - numToText("I have 5 dogs and 6 ponies"); - expect(numToText.callCount).to.be.above(1); - numToText = originalNumToText; - }); - - }); - -}); - -function checkForNativeMethods(runFunction) { - it('should not use the native version of map', function () { - // These spies are set up in testSupport.js - runFunction(); - expect(Array.prototype.map.called).to.equal(false); - }); -} From 90607346017e947f950d0252d40aa3ec258c10f6 Mon Sep 17 00:00:00 2001 From: Cain Date: Tue, 27 Nov 2018 20:58:08 -0600 Subject: [PATCH 10/36] (chore) Add mocha test script --- package-lock.json | 3659 +++++++++++++++++++++++++++++++++++++++++++-- package.json | 4 +- 2 files changed, 3540 insertions(+), 123 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3ceb4b02e..b55546be2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,53 +6,380 @@ "dependencies": { "@sinonjs/formatio": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", + "resolved": "http://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", - "dev": true, "requires": { "samsam": "1.3.0" } }, + "@sinonjs/samsam": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-2.1.0.tgz", + "integrity": "sha512-5x2kFgJYupaF1ns/RmharQ90lQkd2ELS8A9X0ymkAAdemYHGtI2KiUHG8nX2WU0T1qgnOU5YMqnBM2V7NUanNw==", + "requires": { + "array-from": "^2.1.1" + } + }, + "accepts": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", + "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=", + "dev": true, + "requires": { + "mime-types": "~2.1.11", + "negotiator": "0.6.1" + } + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", + "dev": true + }, + "agent-base": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", + "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "requires": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-from": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", + "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=" + }, + "array-slice": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", + "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "arraybuffer.slice": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", + "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=", + "dev": true + }, "assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", + "dev": true + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", + "dev": true + }, + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", + "dev": true + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "dev": true, + "requires": { + "callsite": "1.0.0" + } + }, + "binary-extensions": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", + "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", + "dev": true + }, + "blob": { + "version": "0.0.4", + "resolved": "http://registry.npmjs.org/blob/-/blob-0.0.4.tgz", + "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=", + "dev": true + }, + "bluebird": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", + "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", + "dev": true + }, + "body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "~2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", + "dev": true + }, "chai": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", "dev": true, "requires": { - "assertion-error": "1.1.0", - "check-error": "1.0.2", - "deep-eql": "3.0.1", - "get-func-name": "2.0.0", - "pathval": "1.1.0", - "type-detect": "4.0.8" + "assertion-error": "^1.0.1", + "check-error": "^1.0.1", + "deep-eql": "^3.0.0", + "get-func-name": "^2.0.0", + "pathval": "^1.0.0", + "type-detect": "^4.0.0" } }, "check-error": { @@ -61,18 +388,186 @@ "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", "dev": true }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, + "requires": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "colors": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.2.tgz", + "integrity": "sha512-rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ==", + "dev": true + }, + "combine-lists": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz", + "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=", + "dev": true, + "requires": { + "lodash": "^4.5.0" + }, + "dependencies": { + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + } + } + }, "commander": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", "dev": true }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "connect": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", + "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", + "dev": true, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.0", + "parseurl": "~1.3.2", + "utils-merge": "1.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-js": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "dev": true + }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", @@ -82,142 +577,1648 @@ "ms": "2.0.0" } }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, "deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", "dev": true, "requires": { - "type-detect": "4.0.8" + "type-detect": "^4.0.0" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } } }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", + "dev": true + }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "dev": true, + "requires": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", "dev": true }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "engine.io": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.3.tgz", + "integrity": "sha1-jef5eJXSDTm4X4ju7nd7K9QrE9Q=", "dev": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "accepts": "1.3.3", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "2.3.3", + "engine.io-parser": "1.3.2", + "ws": "1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.3.3", + "resolved": "http://registry.npmjs.org/debug/-/debug-2.3.3.tgz", + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", + "dev": true, + "requires": { + "ms": "0.7.2" + } + }, + "ms": { + "version": "0.7.2", + "resolved": "http://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "dev": true + } } }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true + "engine.io-client": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.3.tgz", + "integrity": "sha1-F5jtk0USRkU9TG9jXXogH+lA1as=", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "2.3.3", + "engine.io-parser": "1.3.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parsejson": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "1.1.2", + "xmlhttprequest-ssl": "1.5.3", + "yeast": "0.1.2" + }, + "dependencies": { + "debug": { + "version": "2.3.3", + "resolved": "http://registry.npmjs.org/debug/-/debug-2.3.3.tgz", + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", + "dev": true, + "requires": { + "ms": "0.7.2" + } + }, + "ms": { + "version": "0.7.2", + "resolved": "http://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "dev": true + } + } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "engine.io-parser": { + "version": "1.3.2", + "resolved": "http://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz", + "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=", + "dev": true, + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "0.0.6", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.4", + "has-binary": "0.1.7", + "wtf-8": "1.0.0" + } + }, + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", "dev": true }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "es6-promise": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz", + "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==", "dev": true }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "es6-promisify": { + "version": "5.0.0", + "resolved": "http://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "dev": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "es6-promise": "^4.0.3" } }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", "dev": true }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, - "just-extend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-3.0.0.tgz", - "integrity": "sha512-Fu3T6pKBuxjWT/p4DkqGHFRsysc8OauWr4ZRTY9dIx07Y9O0RkoR5jcv28aeD1vuAwhm3nLkDurwLXoALp4DpQ==", + "eventemitter3": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", + "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", "dev": true }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", - "dev": true + "expand-braces": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz", + "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", + "dev": true, + "requires": { + "array-slice": "^0.2.3", + "array-unique": "^0.2.1", + "braces": "^0.1.2" + }, + "dependencies": { + "braces": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz", + "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=", + "dev": true, + "requires": { + "expand-range": "^0.1.0" + } + }, + "expand-range": { + "version": "0.1.1", + "resolved": "http://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", + "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", + "dev": true, + "requires": { + "is-number": "^0.1.1", + "repeat-string": "^0.2.2" + } + }, + "is-number": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz", + "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=", + "dev": true + }, + "repeat-string": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz", + "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=", + "dev": true + } + } }, - "lolex": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.1.tgz", - "integrity": "sha512-Oo2Si3RMKV3+lV5MsSWplDQFoTClz/24S0MMHYcgGWWmFXr6TMlqcqk/l1GtH+d5wLBwNRiqGnwDRMirtFalJw==", - "dev": true + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "^0.1.0" + } }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "expand-range": { + "version": "1.8.2", + "resolved": "http://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { - "brace-expansion": "1.1.11" + "fill-range": "^2.1.0" } }, - "minimist": { - "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, - "mkdirp": { - "version": "0.5.1", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { - "minimist": "0.0.8" + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } } }, - "mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { - "browser-stdout": "1.3.1", + "is-extglob": "^1.0.0" + } + }, + "extract-zip": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", + "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", + "dev": true, + "requires": { + "concat-stream": "1.6.2", + "debug": "2.6.9", + "mkdirp": "0.5.1", + "yauzl": "2.4.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "dev": true, + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.1", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.3.1", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + } + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "dev": true, + "requires": { + "debug": "=3.1.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs-access": { + "version": "1.0.1", + "resolved": "http://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", + "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", + "dev": true, + "requires": { + "null-check": "^1.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", + "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.21", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": "^2.1.0" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "minipass": { + "version": "2.2.4", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.1", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.1.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.1.10", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.5.1", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.0.5" + } + }, + "safe-buffer": { + "version": "5.1.1", + "bundled": true, + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.5.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.0.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.2.4", + "minizlib": "^1.1.0", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.1", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "3.0.2", + "bundled": true, + "dev": true + } + } + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "^2.0.0" + } + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "has-binary": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz", + "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "http-errors": { + "version": "1.6.3", + "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "http-proxy": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "dev": true, + "requires": { + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "https-proxy-agent": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", + "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "dev": true, + "requires": { + "agent-base": "^4.1.0", + "debug": "^3.1.0" + } + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "^2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "isbinaryfile": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz", + "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==", + "dev": true, + "requires": { + "buffer-alloc": "^1.2.0" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", + "dev": true + }, + "just-extend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-3.0.0.tgz", + "integrity": "sha512-Fu3T6pKBuxjWT/p4DkqGHFRsysc8OauWr4ZRTY9dIx07Y9O0RkoR5jcv28aeD1vuAwhm3nLkDurwLXoALp4DpQ==" + }, + "karma": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/karma/-/karma-1.7.1.tgz", + "integrity": "sha512-k5pBjHDhmkdaUccnC7gE3mBzZjcxyxYsYVaqiL2G5AqlfLyBO5nw2VdNK+O16cveEPd/gIOWULH7gkiYYwVNHg==", + "dev": true, + "requires": { + "bluebird": "^3.3.0", + "body-parser": "^1.16.1", + "chokidar": "^1.4.1", + "colors": "^1.1.0", + "combine-lists": "^1.0.0", + "connect": "^3.6.0", + "core-js": "^2.2.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.0", + "expand-braces": "^0.1.1", + "glob": "^7.1.1", + "graceful-fs": "^4.1.2", + "http-proxy": "^1.13.0", + "isbinaryfile": "^3.0.0", + "lodash": "^3.8.0", + "log4js": "^0.6.31", + "mime": "^1.3.4", + "minimatch": "^3.0.2", + "optimist": "^0.6.1", + "qjobs": "^1.1.4", + "range-parser": "^1.2.0", + "rimraf": "^2.6.0", + "safe-buffer": "^5.0.1", + "socket.io": "1.7.3", + "source-map": "^0.5.3", + "tmp": "0.0.31", + "useragent": "^2.1.12" + } + }, + "karma-chai": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/karma-chai/-/karma-chai-0.1.0.tgz", + "integrity": "sha1-vuWtQEAFF4Ea40u5RfdikJEIt5o=", + "dev": true + }, + "karma-chrome-launcher": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", + "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", + "dev": true, + "requires": { + "fs-access": "^1.0.0", + "which": "^1.2.1" + } + }, + "karma-mocha": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-1.3.0.tgz", + "integrity": "sha1-7qrH/8DiAetjxGdEDStpx883eL8=", + "dev": true, + "requires": { + "minimist": "1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "karma-sinon": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/karma-sinon/-/karma-sinon-1.0.5.tgz", + "integrity": "sha1-TjRD8oMP3s/2JNN0cWPxIX2qKpo=" + }, + "karma-sinon-chai": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/karma-sinon-chai/-/karma-sinon-chai-1.3.4.tgz", + "integrity": "sha512-Oatu8tdkfWaSveM809euI6KGcNJRdoXFilz9ozSf+vPwrM73kncu54nsfkLcMqR/iht3PXASAGK9La5oU2xDKQ==", + "requires": { + "lolex": "^1.6.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "lodash": { + "version": "3.10.1", + "resolved": "http://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + }, + "log4js": { + "version": "0.6.38", + "resolved": "http://registry.npmjs.org/log4js/-/log4js-0.6.38.tgz", + "integrity": "sha1-LElBFmldb7JUgJQ9P8hy5mKlIv0=", + "dev": true, + "requires": { + "readable-stream": "~1.0.2", + "semver": "~4.3.3" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "lolex": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", + "integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=" + }, + "lru-cache": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.4.tgz", + "integrity": "sha512-EPstzZ23znHUVLKj+lcXO1KvZkrlw+ZirdwvOmnAnA/1PB4ggyXJ77LRkCqkff+ShQ+cqoxCxLQOh4cKITO5iA==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^3.0.2" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "math-random": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", + "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "dev": true + }, + "mime-types": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "dev": true, + "requires": { + "mime-db": "~1.37.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", "commander": "2.15.1", "debug": "3.1.0", "diff": "3.5.0", @@ -236,17 +2237,185 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, - "nise": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.4.tgz", - "integrity": "sha512-pxE0c9PzgrUTyhfv5p+5eMIdfU2bLEsq8VQEuE0kxM4zP7SujSar7rk9wpI2F7RyyCEvLyj5O7Is3RER5F36Fg==", + "nan": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", + "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "dev": true + }, + "nise": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.6.tgz", + "integrity": "sha512-1GedetLKzmqmgwabuMSqPsT7oumdR77SBpDfNNJhADRIeA3LN/2RVqR4fFqwvzhAqcTef6PPCzQwITE/YQ8S8A==", + "requires": { + "@sinonjs/formatio": "3.0.0", + "just-extend": "^3.0.0", + "lolex": "^2.3.2", + "path-to-regexp": "^1.7.0", + "text-encoding": "^0.6.4" + }, + "dependencies": { + "@sinonjs/formatio": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.0.0.tgz", + "integrity": "sha512-vdjoYLDptCgvtJs57ULshak3iJe4NW3sJ3g36xVDGff5AE8P30S6A093EIEPjdi2noGhfuNOEkbxt3J3awFW1w==", + "requires": { + "@sinonjs/samsam": "2.1.0" + } + }, + "lolex": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", + "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==" + } + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "null-check": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", + "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", + "dev": true + }, + "object-assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", + "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", + "dev": true + }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", "dev": true, "requires": { - "@sinonjs/formatio": "2.0.0", - "just-extend": "3.0.0", - "lolex": "2.7.1", - "path-to-regexp": "1.7.0", - "text-encoding": "0.6.4" + "ee-first": "1.1.1" } }, "once": { @@ -255,9 +2424,82 @@ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "options": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", + "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + } + }, + "parsejson": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz", + "integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" } }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -268,7 +2510,6 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", - "dev": true, "requires": { "isarray": "0.0.1" } @@ -279,46 +2520,1177 @@ "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", "dev": true }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "progress": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz", + "integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==", + "dev": true + }, + "proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "puppeteer": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-0.11.0.tgz", + "integrity": "sha512-/o8uY6VChG74B1HYBZkLDU6aIekWeOd85wez9YxB9SNbDnFNsUddv2F4xWuhwvQ4ab84vb+1VX4fxs2kBz3u8g==", + "dev": true, + "requires": { + "debug": "^2.6.8", + "extract-zip": "^1.6.5", + "https-proxy-agent": "^2.1.0", + "mime": "^1.3.4", + "progress": "^2.0.0", + "proxy-from-env": "^1.0.0", + "rimraf": "^2.6.1", + "ws": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + } + } + }, + "qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "randomatic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", + "dev": true, + "requires": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", + "dev": true + }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "dev": true, + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + } + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "requires": { + "is-equal-shallow": "^0.1.3" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "^7.0.5" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, "samsam": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", - "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", + "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==" + }, + "semver": { + "version": "4.3.6", + "resolved": "http://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", + "dev": true + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", "dev": true }, "sinon": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-5.1.1.tgz", - "integrity": "sha512-h/3uHscbt5pQNxkf7Y/Lb9/OM44YNCicHakcq73ncbrIS8lXg+ZGOZbtuU+/km4YnyiCYfQQEwANaReJz7KDfw==", + "version": "4.5.0", + "resolved": "http://registry.npmjs.org/sinon/-/sinon-4.5.0.tgz", + "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==", + "requires": { + "@sinonjs/formatio": "^2.0.0", + "diff": "^3.1.0", + "lodash.get": "^4.4.2", + "lolex": "^2.2.0", + "nise": "^1.2.0", + "supports-color": "^5.1.0", + "type-detect": "^4.0.5" + }, + "dependencies": { + "lolex": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", + "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==" + } + } + }, + "sinon-chai": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-2.14.0.tgz", + "integrity": "sha512-9stIF1utB0ywNHNT7RgiXbdmen8QDCRsrTjw+G9TgKt1Yexjiv8TOWZ6WHsTPz57Yky3DIswZvEqX8fpuHNDtQ==" + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "requires": { - "@sinonjs/formatio": "2.0.0", - "diff": "3.5.0", - "lodash.get": "4.4.2", - "lolex": "2.7.1", - "nise": "1.4.4", - "supports-color": "5.4.0", - "type-detect": "4.0.8" + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + } + }, + "socket.io": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.7.3.tgz", + "integrity": "sha1-uK+cq6AJSeVo42nxMn6pvp6iRhs=", + "dev": true, + "requires": { + "debug": "2.3.3", + "engine.io": "1.8.3", + "has-binary": "0.1.7", + "object-assign": "4.1.0", + "socket.io-adapter": "0.5.0", + "socket.io-client": "1.7.3", + "socket.io-parser": "2.3.1" + }, + "dependencies": { + "debug": { + "version": "2.3.3", + "resolved": "http://registry.npmjs.org/debug/-/debug-2.3.3.tgz", + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", + "dev": true, + "requires": { + "ms": "0.7.2" + } + }, + "ms": { + "version": "0.7.2", + "resolved": "http://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "dev": true + } + } + }, + "socket.io-adapter": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz", + "integrity": "sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s=", + "dev": true, + "requires": { + "debug": "2.3.3", + "socket.io-parser": "2.3.1" + }, + "dependencies": { + "debug": { + "version": "2.3.3", + "resolved": "http://registry.npmjs.org/debug/-/debug-2.3.3.tgz", + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", + "dev": true, + "requires": { + "ms": "0.7.2" + } + }, + "ms": { + "version": "0.7.2", + "resolved": "http://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "dev": true + } + } + }, + "socket.io-client": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.3.tgz", + "integrity": "sha1-sw6GqhDV7zVGYBwJzeR2Xjgdo3c=", + "dev": true, + "requires": { + "backo2": "1.0.2", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "2.3.3", + "engine.io-client": "1.8.3", + "has-binary": "0.1.7", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseuri": "0.0.5", + "socket.io-parser": "2.3.1", + "to-array": "0.1.4" + }, + "dependencies": { + "debug": { + "version": "2.3.3", + "resolved": "http://registry.npmjs.org/debug/-/debug-2.3.3.tgz", + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", + "dev": true, + "requires": { + "ms": "0.7.2" + } + }, + "ms": { + "version": "0.7.2", + "resolved": "http://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "dev": true + } + } + }, + "socket.io-parser": { + "version": "2.3.1", + "resolved": "http://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz", + "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=", + "dev": true, + "requires": { + "component-emitter": "1.1.2", + "debug": "2.2.0", + "isarray": "0.0.1", + "json3": "3.3.2" + }, + "dependencies": { + "component-emitter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", + "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=", + "dev": true + }, + "debug": { + "version": "2.2.0", + "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "http://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" } }, "supports-color": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } }, "text-encoding": { "version": "0.6.4", - "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", - "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "resolved": "http://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=" + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", "dev": true }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + } + } + }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.18" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "ultron": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", + "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", + "dev": true + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "useragent": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", + "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==", + "dev": true, + "requires": { + "lru-cache": "4.1.x", + "tmp": "0.0.x" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", "dev": true }, "wrappy": { @@ -326,6 +3698,49 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true + }, + "ws": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz", + "integrity": "sha1-iiRPoFJAHgjJiGz0SoUYnh/UBn8=", + "dev": true, + "requires": { + "options": ">=0.0.5", + "ultron": "1.0.x" + } + }, + "wtf-8": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wtf-8/-/wtf-8-1.0.0.tgz", + "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=", + "dev": true + }, + "xmlhttprequest-ssl": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", + "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=", + "dev": true + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "dev": true + }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "dev": true, + "requires": { + "fd-slicer": "~1.0.1" + } + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", + "dev": true } } } diff --git a/package.json b/package.json index a3402d8c5..0d1c6482b 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,9 @@ }, "scripts": { "pretest": "npm install", - "test": "karma start --single-run --browsers ChromeHeadless karma.conf.js" + "test": "mocha ./test || :", + "posttest": "rm -rf ./test ./node_modules", + "test:travis": "karma start --single-run --browsers ChromeHeadless karma.conf.js" }, "repository": { "type": "git", From 27a3fa553b63f6edef7a206ad9696ec29c0c9907 Mon Sep 17 00:00:00 2001 From: Cain Date: Tue, 27 Nov 2018 20:58:23 -0600 Subject: [PATCH 11/36] (chore) Use test:travis cmd in travis yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cc644d875..56abebb1f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,6 @@ before_install: install: - yarn script: - - yarn test + - yarn test:travis notifications: webhooks: https://greenlight.operationspark.org/api/v2/webhooks/travisci From 99562bc191582da9683f8b92da62ed8a3d710b0a Mon Sep 17 00:00:00 2001 From: Cain Date: Tue, 27 Nov 2018 20:58:45 -0600 Subject: [PATCH 12/36] (chore) Add test files --- test/mocha.opts | 1 + test/part1.js | 1187 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1188 insertions(+) create mode 100644 test/mocha.opts create mode 100755 test/part1.js diff --git a/test/mocha.opts b/test/mocha.opts new file mode 100644 index 000000000..5639158f5 --- /dev/null +++ b/test/mocha.opts @@ -0,0 +1 @@ +--reporter json diff --git a/test/part1.js b/test/part1.js new file mode 100755 index 000000000..1d1283b4b --- /dev/null +++ b/test/part1.js @@ -0,0 +1,1187 @@ +(function() { + 'use strict'; + + const sinon = require('sinon'); + const { expect } = require('chai'); + const { + factorial, + sum, + arraySum, + isEven, + sumBelow, + range, + exponent, + powerOfTwo, + reverse, + palindrome, + modulo, + multiply, + divide, + gcd, + compareStr, + createArray, + reverseArr, + buildList, + countOccurrence, + rMap, + countKeysInObj, + countValuesInObj, + replaceKeysInObj, + fibonacci, + nthFibo, + capitalizeWords, + capitalizeFirst, + nestedEvenSum, + flatten, + letterTally, + compress, + augmentElements, + minimizeZeroes, + alternateSign, + numToText, + tagCount, + binarySearch, + mergeSort, + } = require('../src/recursion'); + + describe('Exercises in Recursion in Recursion in Recursion in...', function() { + + before(function() { + sinon.spy(Array.prototype, 'map'); + sinon.spy(Array.prototype, 'indexOf'); + // sinon.spy(Array.prototype, 'forEach'); + sinon.spy(Array.prototype, 'filter'); + sinon.spy(Array.prototype, 'reduce'); + sinon.spy(Array.prototype, 'every'); + sinon.spy(Array.prototype, 'some'); + sinon.spy(Array.prototype, 'sort'); + }); + + afterEach(function () { + Array.prototype.map.resetHistory(); + Array.prototype.indexOf.resetHistory(); + // Array.prototype.forEach.resetHistory(); + Array.prototype.filter.resetHistory(); + Array.prototype.reduce.resetHistory(); + Array.prototype.every.resetHistory(); + Array.prototype.some.resetHistory(); + Array.prototype.sort.resetHistory(); + }); + + after(function () { + Array.prototype.map.restore(); + Array.prototype.indexOf.restore(); + // Array.prototype.forEach.restore(); + Array.prototype.filter.restore(); + Array.prototype.reduce.restore(); + Array.prototype.every.restore(); + Array.prototype.some.restore(); + Array.prototype.sort.restore(); + }); + + describe('1. Factorial', function() { + + it('should return a number', function() { + expect(typeof(factorial(5))).to.equal('number'); + }); + + it('should return factorial for non-negative integers', function() { + expect(factorial(0)).to.equal(1); + expect(factorial(1)).to.equal(1); + expect(factorial(4)).to.equal(24); + expect(factorial(5)).to.equal(120); + }); + + it('should return null for negative integers', function() { + expect(factorial(-5)).to.equal(null); + }); + + it('should use recursion by calling self', function () { + factorial.proxyCallCount = 0; + factorial(4); + expect(factorial.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('2. Sum of Integers', function() { + + it('should return a number', function() { + expect(typeof(sum([1,2,3,4,5,6]))).to.eql('number'); + }); + + it('should return the sum of an array of non-negative integers', function() { + expect(sum([1,2,3,4,5,6])).to.eql(21); + expect(sum([12,34,56,78])).to.eql(180); + expect(sum([3,0,34,7,18])).to.eql(62); + }); + + it('should return the sum of an array of negative integers', function() { + expect(sum([-1,-2,-3,-4,-5,-6])).to.eql(-21); + expect(sum([-12,-34,-56,-78])).to.eql(-180); + expect(sum([-3,-0,-34,-7,-18])).to.eql(-62); + }); + + it('should return the sum of an array of mixed non-negative and negative integers', function() { + expect(sum([1,-2,3,-4,5,-6])).to.eql(-3); + expect(sum([-12,34,-56,78])).to.eql(44); + expect(sum([3,0,-34,-7,18])).to.eql(-20); + }); + + it('should return 0 for empty array', function() { + expect(sum([])).to.eql(0); + }); + + it('should accept an array with a single integer', function() { + expect(sum([4])).to.eql(4); + expect(sum([0])).to.eql(0); + expect(sum([-37])).to.eql(-37); + }); + + it('should not mutate the input array', function() { + var input = [1,2,3,4,5]; + var result = sum(input); + expect(input).to.eql([1,2,3,4,5]); + }); + + it('should use recursion by calling self', function () { + sum.proxyCallCount = 0; + sum([1,2,3,4,5,6]); + expect(sum.proxyCallCount).to.be.above(1); + }); + + }); + + + + xdescribe('3. Sum Integers in Array', function() { + + it('should return a number', function() { + expect(typeof(arraySum([[1],[2,3],[[4]],5,6]))).to.eql('number'); + }); + + it('should return the sum of an array with nested arrays of non-negative integers', function() { + expect(arraySum([[1],[2,3],[[4]],5,6])).to.eql(21); + expect(arraySum([[12,[[34],[56]],78]])).to.eql(180); + expect(arraySum([3,[0,[34,[7,[18]]]]])).to.eql(62); + }); + + it('should return the sum of an array with nested arrays of negative integers', function() { + expect(arraySum([[-1],[-2,-3],[[-4]],-5,-6])).to.eql(-21); + expect(arraySum([[-12,[[-34],[-56]],-78]])).to.eql(-180); + expect(arraySum([-3,[0,[-34,[-7,[-18]]]]])).to.eql(-62); + }); + + it('should return the sum of an array with nested arrays of mixed non-negative and negative integers', function() { + expect(arraySum([[1],[-2,3],[[-4]],5,-6])).to.eql(-3); + expect(arraySum([[-12,[[34],[-56]],78]])).to.eql(44); + expect(arraySum([3,[0,[-34,[-7,[18]]]]])).to.eql(-20); + }); + + it('should return 0 for empty array', function() { + expect(arraySum([])).to.eql(0); + }); + + it('should accept an array with a single integer', function() { + expect(arraySum([4])).to.eql(4); + expect(arraySum([0])).to.eql(0); + expect(arraySum([-37])).to.eql(-37); + }); + + it('should not mutate the input array', function() { + var input = [[1],[2,3],[[4]],5,6]; + var result = arraySum(input); + expect(input).to.eql([[1],[2,3],[[4]],5,6]); + }); + + it('should use recursion by calling self', function () { + arraySum.proxyCallCount = 0; + arraySum([[1],[2,3],[[4]],5,6]); + expect(arraySum.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('4. Check if Even', function() { + + it('should return a boolean', function() { + expect(typeof(isEven(5))).to.equal('boolean'); + expect(typeof(isEven(8))).to.equal('boolean'); + expect(typeof(isEven(-4))).to.equal('boolean'); + }); + + it("should not use modulo", function() { + expect(isEven.toString()).to.not.contain('%'); + }); + + it('should return true for even numbers', function() { + expect(isEven(118)).to.equal(true); + expect(isEven(10)).to.equal(true); + expect(isEven(0)).to.equal(true); + expect(isEven(-34)).to.equal(true); + }); + + it('should return false for odd numbers', function() { + expect(isEven(117)).to.equal(false); + expect(isEven(9)).to.equal(false); + expect(isEven(1)).to.equal(false); + expect(isEven(-33)).to.equal(false); + }); + + it('should work with negative integers', function() { + expect(isEven(-14)).to.equal(true); + expect(isEven(-81)).to.equal(false); + }); + + it('should use recursion by calling self', function () { + isEven.proxyCallCount = 0; + isEven(118); + expect(isEven.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('5. Sum Below', function() { + + it('should return a number', function() { + expect(typeof(sumBelow(10))).to.eql('number'); + }); + + it('should return the sum of non-negative integers below given integer', function() { + expect(sumBelow(0)).to.eql(0); + expect(sumBelow(1)).to.eql(0); + expect(sumBelow(2)).to.eql(1); + expect(sumBelow(7)).to.eql(21); + expect(sumBelow(21)).to.eql(210); + expect(sumBelow(92)).to.eql(4186); + }); + + it('should return the sum of an array of negative integers', function() { + expect(sumBelow(-1)).to.eql(0); + expect(sumBelow(-2)).to.eql(-1); + expect(sumBelow(-6)).to.eql(-15); + expect(sumBelow(-21)).to.eql(-210); + expect(sumBelow(-92)).to.eql(-4186); + }); + + it('should use recursion by calling self', function () { + sumBelow.proxyCallCount = 0; + sumBelow(10); + expect(sumBelow.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('6. Integer Range', function() { + + it('should return an array', function() { + expect(Array.isArray(range(2, 7))).to.equal(true); + }); + + it('should return the integers between two numbers', function() { + expect(range(3,8)).to.eql([4,5,6,7]); + expect(range(127,131)).to.eql([128,129,130]); + }); + + it('should return empty array if no integers in range', function() { + expect(range(5,5)).to.eql([]); + expect(range(2,3)).to.eql([]); + }); + + it('should accept negative integers', function() { + expect(range(-9,-4)).to.eql([-8,-7,-6,-5]); + expect(range(-3,2)).to.eql([-2,-1,0,1]); + expect(range(-3,-2)).to.eql([]); + expect(range(-2,-2)).to.eql([]); + }); + + it('should accept starting integer that\'s larger than ending', function() { + expect(range(7,2)).to.eql([6,5,4,3]); + expect(range(3,-3)).to.eql([2,1,0,-1,-2]); + expect(range(-9,-4)).to.eql([-8,-7,-6,-5]); + }); + + it('should use recursion by calling self', function () { + range.proxyCallCount = 0; + range(3,8); + expect(range.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('7. Compute Exponent', function() { + + it('should return a number', function() { + expect(typeof(exponent(4,3))).to.eql('number'); + }); + + it("should not use complex math", function() { + expect(exponent.toString()).to.not.contain('Math'); + }); + + it('should compute exponent of non-negative integers', function() { + expect(exponent(3,4)).to.equal(81); + expect(exponent(12,5)).to.equal(248832); + expect(exponent(7,2)).to.equal(49); + }); + + it('returns 1 when exponent is 0', function() { + expect(exponent(8,0)).to.equal(1); + expect(exponent(244,0)).to.equal(1); + }); + + it('returns base when exponent is 1', function() { + expect(exponent(9,1)).to.equal(9); + expect(exponent(2300,1)).to.equal(2300); + }); + + // it('BONUS: should accept negative integer for base', function() { + // expect(exponent(-3,4)).to.equal(-81); + // expect(exponent(-12,5)).to.equal(-248832); + // expect(exponent(-7,2)).to.equal(-49); + // expect(exponent(-7,4)).to.equal(-2401); + // }); + + it('should accept negative integer for exponent', function() { + expect(exponent(4,-2)).to.equal(0.0625); + expect(exponent(5,-4)).to.equal(0.0016); + expect(exponent(2,-5)).to.equal(0.03125); + }); + + it('should use recursion by calling self', function () { + exponent.proxyCallCount = 0; + exponent(3,4); + expect(exponent.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('8. Power of Two', function() { + + it('should return a boolean', function() { + expect(typeof(powerOfTwo(10))).to.equal('boolean'); + expect(typeof(powerOfTwo(16))).to.equal('boolean'); + }); + + it('should return true for powers of two', function() { + expect(powerOfTwo(0)).to.equal(false); + expect(powerOfTwo(1)).to.equal(true); + expect(powerOfTwo(2)).to.equal(true); + expect(powerOfTwo(10)).to.equal(false); + expect(powerOfTwo(128)).to.equal(true); + expect(powerOfTwo(256)).to.equal(true); + }); + + it('should use recursion by calling self', function () { + powerOfTwo.proxyCallCount = 0; + powerOfTwo(32); + expect(powerOfTwo.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('9. Reverse String', function() { + + it('should return a string', function() { + expect(typeof(reverse('orangutan'))).to.equal('string'); + }); + + it('should return a string in reverse', function() { + var poem = 'Roses are red, violets are blue, all my base are belong to you.'; + + expect(reverse('Racecar')).to.equal('racecaR'); + expect(reverse(poem)).to.equal('.uoy ot gnoleb era esab ym lla ,eulb era steloiv ,der era sesoR'); + }); + + it('should not mutate the input string', function() { + var input = 'orangutan'; + var result = reverse(input); + expect(input).to.eql('orangutan'); + }); + + it('should use recursion by calling self', function () { + reverse.proxyCallCount = 0; + reverse('orangutan'); + expect(reverse.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('10. Palindrome', function() { + + it('should return a boolean', function() { + expect(typeof(palindrome('rotor'))).to.equal('boolean'); + expect(typeof(palindrome('motor'))).to.equal('boolean'); + }); + + it('should return true for palindromes', function() { + expect(palindrome('rotor')).to.eql(true); + expect(palindrome('racecar')).to.eql(true); + expect(palindrome('saippuakivikauppias')).to.eql(true); + }); + + it('should return false for non-palindromes', function() { + expect(palindrome('motor')).to.eql(false); + expect(palindrome('orangutan')).to.eql(false); + expect(palindrome('antidisestablishmentarianism')).to.eql(false); + }); + + it('should ignore spaces and capital letters', function() { + expect(palindrome('Rotor')).to.eql(true); + expect(palindrome('race caR')).to.eql(true); + expect(palindrome('sAip puaki v iKaup Pias')).to.eql(true); + }); + + it('should use recursion by calling self', function () { + palindrome.proxyCallCount = 0; + palindrome('saippuakivikauppias'); + expect(palindrome.proxyCallCount).to.be.above(1); + }); + + }); + + + + xdescribe('11. Modulo', function() { + + it('should return a number', function() { + expect(typeof(modulo(5,2))).to.equal('number'); + expect(typeof(modulo(8,4))).to.equal('number'); + }); + + it("should not use complex math", function() { + expect(modulo.toString()).to.not.contain('*'); + expect(modulo.toString()).to.not.contain('/'); + expect(modulo.toString()).to.not.contain('%'); + expect(modulo.toString()).to.not.contain('Math'); + }); + + it('should return the remainder of two integers', function() { + expect(modulo(2, 1)).to.equal(2 % 1); + expect(modulo(17, 5)).to.equal(17 % 5); + expect(modulo(78, 453)).to.equal(78 % 453); + expect(modulo(-79, 82)).to.equal(-79 % 82); + expect(modulo(-275, -502)).to.equal(-275 % -502); + expect(modulo(-275, -274)).to.equal(-275 % -274); + expect(modulo(-4, 2)).to.equal(-4 % 2); + expect(modulo(0, 32)).to.equal(0 % 32); + expect(modulo(0, 0).toString()).to.equal('NaN'); + }); + + it('should use recursion by calling self', function () { + modulo.proxyCallCount = 0; + modulo(5,2); + expect(modulo.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('12. Multiply', function() { + + it('should return a number', function() { + expect(typeof(multiply(5,2))).to.equal('number'); + expect(typeof(multiply(8,4))).to.equal('number'); + }); + + it("should not use complex math", function() { + expect(multiply.toString()).to.not.contain('*'); + expect(multiply.toString()).to.not.contain('/'); + expect(multiply.toString()).to.not.contain('%'); + expect(multiply.toString()).to.not.contain('Math'); + }); + + it('should return the product of two integers', function() { + expect(multiply(2, 1)).to.equal(2 * 1); + expect(multiply(17, 5)).to.equal(17 * 5); + expect(multiply(78, 453)).to.equal(78 * 453); + expect(multiply(-79, 82)).to.equal(-79 * 82); + expect(multiply(-275, -502)).to.equal(-275 * -502); + expect(multiply(0, 32)).to.equal(0 * 32); + expect(multiply(0, 0)).to.equal(0 * 0); + }); + + it('should use recursion by calling self', function () { + multiply.proxyCallCount = 0; + multiply(8,4); + expect(multiply.proxyCallCount).to.be.above(1); + }); + + }); + + + + xdescribe('13. Divide', function() { + + it('should return a number', function() { + expect(typeof(divide(5,2))).to.equal('number'); + expect(typeof(divide(8,4))).to.equal('number'); + }); + + it("should not use complex math", function() { + expect(divide.toString()).to.not.contain('*'); + expect(divide.toString()).to.not.contain('/'); + expect(divide.toString()).to.not.contain('%'); + expect(divide.toString()).to.not.contain('Math'); + }); + + it('should return the quotient of two integers', function() { + expect(divide(2, 1)).to.equal(~~(2 / 1)); + expect(divide(17, 5)).to.equal(~~(17 / 5)); + expect(divide(78, 453)).to.equal(~~(78 / 453)); + expect(divide(-79, 82)).to.equal(~~(-79 / 82)); + expect(divide(-275, -582)).to.equal(~~(-275 / -582)); + expect(divide(0, 32)).to.equal(~~(0 / 32)); + expect(divide(0, 0).toString()).to.equal('NaN'); + }); + + it('should use recursion by calling self', function () { + divide.proxyCallCount = 0; + divide(17, 5); + expect(divide.proxyCallCount).to.be.above(1); + }); + + }); + + + + xdescribe('14. Greatest Common Divisor', function() { + + it('should return a number', function() { + expect(typeof(gcd(4,36))).to.equal('number'); + }); + + it('should return greatest common divisor of two positive integers', function() { + expect(gcd(4,36)).to.equal(4); + expect(gcd(24,88)).to.equal(8); + expect(gcd(339,17)).to.equal(1); + expect(gcd(126,900)).to.equal(18); + }); + + it('should return null for negative integers', function() { + expect(gcd(-4, 2)).to.equal(null); + expect(gcd(-5, 5)).to.equal(null); + expect(gcd(5, -5)).to.equal(null); + expect(gcd(7, -36)).to.equal(null); + expect(gcd(-10, -58)).to.equal(null); + expect(gcd(-92, -5)).to.equal(null); + // expect(gcd(0, 0)).to.equal(null); + // expect(gcd(0, 5)).to.equal(null); + // expect(gcd(5, 0)).to.equal(null); + // expect(gcd(-5, 0)).to.equal(null); + // expect(gcd(0, -5)).to.equal(null); + }); + + it('should use recursion by calling self', function () { + gcd.proxyCallCount = 0; + gcd(17, 5); + expect(gcd.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('15. Compare Strings', function() { + + it('should return a boolean', function() { + expect(typeof(compareStr('house', 'houses'))).to.equal('boolean'); + expect(typeof(compareStr('', ''))).to.equal('boolean'); + expect(typeof(compareStr('tomato', 'tomato'))).to.equal('boolean'); + }); + + it('should return true for identical strings', function() { + expect(compareStr('house', 'houses')).to.eql(false); + expect(compareStr('', '')).to.eql(true); + expect(compareStr('tomato', 'tomato')).to.eql(true); + expect(compareStr('', 'pop')).to.eql(false); + expect(compareStr('foot', '')).to.eql(false); + expect(compareStr('big dog', 'big dog')).to.eql(true); + }); + + it('should use recursion by calling self', function () { + compareStr.proxyCallCount = 0; + compareStr('house', 'houses'); + expect(compareStr.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('16. Create array from string', function() { + + it('should return an array', function() { + expect(Array.isArray(createArray('hello'))).to.equal(true); + }); + + it('should return an array where each index is a letter of the string', function() { + expect(createArray('hello')).to.eql(['h','e','l','l','o']); + expect(createArray('this is not a pipe')).to.eql(['t','h','i','s',' ','i','s',' ','n','o','t',' ','a',' ','p','i','p','e']); + expect(createArray('hologram')).to.eql(['h','o','l','o','g','r','a','m']); + expect(createArray('i')).to.eql(['i']); + }); + + it('should use recursion by calling self', function () { + createArray.proxyCallCount = 0; + createArray('hello'); + expect(createArray.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('17. Reverse an array', function() { + + it('should return an array', function() { + expect(Array.isArray(reverseArr([5,4,3,2,1]))).to.equal(true); + }); + + it('should return array in reversed order', function() { + expect(reverseArr([1,2,3,4,5])).to.eql([5,4,3,2,1]); + expect(reverseArr([5,4,3,2,1])).to.eql([1,2,3,4,5]); + expect(reverseArr([2,4,6,8])).to.eql([8,6,4,2]); + expect(reverseArr([8,6,4,2])).to.eql([2,4,6,8]); + }); + + it('should use recursion by calling self', function () { + reverseArr.proxyCallCount = 0; + reverseArr([5,4,3,2,1]); + expect(reverseArr.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('18. Build an array with a given value and length', function() { + + it('should return an array', function() { + expect(Array.isArray(buildList(0,5))).to.equal(true); + }); + + it('should return array of given length with given value at each index', function() { + expect(buildList(0, 5)).to.eql([0,0,0,0,0]); + expect(buildList('banana', 3)).to.eql(['banana','banana','banana']); + expect(buildList(NaN, 4)).to.eql([NaN, NaN, NaN, NaN]); + expect(buildList(undefined, 1)).to.eql([undefined]); + expect(buildList([], 2)).to.eql([[],[]]); + expect(buildList({}, 4)).to.eql([{},{},{},{}]); + expect(buildList(true, 3)).to.eql([true,true,true]); + expect(buildList(5+5, 3)).to.eql([10,10,10]); + }); + + it('should use recursion by calling self', function () { + buildList.proxyCallCount = 0; + buildList(2,7); + expect(buildList.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('19. Count value in array', function() { + + it('should return a number', function() { + expect(typeof(countOccurrence([2,7,4,4,1,4], 4))).to.equal('number'); + expect(typeof(countOccurrence([2,'banana',4,4,1,'banana'], 'banana'))).to.equal('number'); + }); + + it('should return the number of occurrences of the value', function() { + expect(countOccurrence([2,7,4,4,1,4], 4)).to.eql(3); + expect(countOccurrence([2,'banana',4,4,1,'banana'], 'banana')).to.eql(2); + expect(countOccurrence([undefined,7,undefined,4,1,4], undefined)).to.eql(2); + expect(countOccurrence(['',7,null,0,'0',false], 0)).to.eql(1); + expect(countOccurrence(['',7,null,0,'0',false], false)).to.eql(1); + expect(countOccurrence(['',7,null,0,'0',false], null)).to.eql(1); + expect(countOccurrence(['',7,null,0,'0',false], '')).to.eql(1); + // expect(countOccurrence(['',7,null,0,NaN,'0',false], NaN)).to.eql(1); + }); + + it('should use recursion by calling self', function () { + countOccurrence.proxyCallCount = 0; + countOccurrence([2,7,4,4,1,4], 4); + expect(countOccurrence.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('20. Recursive Map', function() { + + var timesTwo = function(n) { return n * 2; }; + var input3 = [1,2,3,4,5]; + + it('should return an array', function() { + expect(Array.isArray(rMap([1,2,3], timesTwo))).to.equal(true); + }); + + checkForNativeMethods(function() { + rMap([1,2,3,4], timesTwo); + }); + + it('should return new array without mutating the input array', function() { + var input = [1,2,3,4,5]; + var result = rMap(input, function(num) { /* poop */ }); + expect(input).to.eql([1,2,3,4,5]); + expect(result).to.not.equal(input); + }); + + it('should apply a function to every value in an array', function() { + var doubledNumbers = rMap([1,2,3], timesTwo); + expect(doubledNumbers).to.eql([2,4,6]); + }); + + it('should use recursion by calling self', function () { + rMap.proxyCallCount = 0; + rMap([1,2,3,4], timesTwo); + expect(rMap.proxyCallCount).to.be.above(1); + }); + + }); + + + + xdescribe('21. Count key in object', function() { + var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; + + it('should return a number', function() { + expect(typeof(countKeysInObj(input, 'r'))).to.equal('number'); + expect(typeof(countKeysInObj(input, 'e'))).to.equal('number'); + expect(typeof(countKeysInObj(input, 'p'))).to.equal('number'); + }); + + it('should return the number of occurrences of the property', function() { + expect(countKeysInObj(input, 'e')).to.eql(2); + expect(countKeysInObj(input, 'x')).to.eql(1); + expect(countKeysInObj(input, 'y')).to.eql(2); + expect(countKeysInObj(input, 't')).to.eql(1); + expect(countKeysInObj(input, 'r')).to.eql(1); + expect(countKeysInObj(input, 'p')).to.eql(1); + }); + + it('should use recursion by calling self', function () { + countKeysInObj.proxyCallCount = 0; + countKeysInObj(input, 'e'); + expect(countKeysInObj.proxyCallCount).to.be.above(1); + }); + + }); + + + + xdescribe('22. Count value in object', function() { + var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; + + it('should return a number', function() { + expect(typeof(countValuesInObj(input, 'r'))).to.equal('number'); + expect(typeof(countValuesInObj(input, 'e'))).to.equal('number'); + expect(typeof(countValuesInObj(input, 'p'))).to.equal('number'); + }); + + it('should return the count of the occurrences of the property', function() { + expect(countValuesInObj(input, 'e')).to.eql(1); + expect(countValuesInObj(input, 'x')).to.eql(0); + expect(countValuesInObj(input, 'y')).to.eql(1); + expect(countValuesInObj(input, 't')).to.eql(0); + expect(countValuesInObj(input, 'r')).to.eql(2); + expect(countValuesInObj(input, 'p')).to.eql(0); + }); + + it('should use recursion by calling self', function () { + countValuesInObj.proxyCallCount = 0; + countValuesInObj(input, 'r'); + expect(countValuesInObj.proxyCallCount).to.be.above(1); + }); + + }); + + + + xdescribe('23. Replace keys in object', function() { + + var tallyKeys = function(obj) { + var count = 0; + for (var k in obj) { + if (typeof obj[k] === 'object') { + count += tallyKeys(obj[k]); + } + count++; + } + return count; + }; + + it('should return an object', function() { + var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; + expect(typeof(replaceKeysInObj(input, 'r', 'a'))).to.equal('object'); + expect(typeof(replaceKeysInObj(input, 'e', 0))).to.equal('object'); + }); + + it('should return object containing renamed keys', function() { + var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}}, 'y':'e'}; + var output = replaceKeysInObj(input, 'e', 'f'); + + expect(output.e).to.equal(undefined); + expect(output.f.x).to.equal('y'); + expect(output.t.r.e).to.equal(undefined); + expect(output.t.r.f).to.equal('r'); + expect(output.t.p.y).to.equal('r'); + expect(output.y).to.equal('e'); + + expect(output.hasOwnProperty('e')).to.equal(false); + expect(output.hasOwnProperty('f')).to.equal(true); + expect(output.hasOwnProperty('t')).to.equal(true); + expect(output.hasOwnProperty('y')).to.equal(true); + + expect(output.t.hasOwnProperty('r')).to.equal(true); + expect(output.t.hasOwnProperty('p')).to.equal(true); + + expect(output.t.r.hasOwnProperty('e')).to.equal(false); + expect(output.t.r.hasOwnProperty('f')).to.equal(true); + expect(output.t.p.hasOwnProperty('y')).to.equal(true); + }); + + it('should return object with same number of keys', function () { + var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}}, 'y':'e'}; + var output1 = replaceKeysInObj(input, 'e', 'f'); + var output2 = replaceKeysInObj(output1, 'e', 'f'); + expect(tallyKeys(input)).to.equal(8); + expect(tallyKeys(output1)).to.equal(8); + expect(tallyKeys(output2)).to.equal(8); + }); + + it('should use recursion by calling self', function () { + var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; + replaceKeysInObj.proxyCallCount = 0; + replaceKeysInObj(input, 'r', 'a'); + expect(replaceKeysInObj.proxyCallCount).to.be.above(1); + }); + + }); + + + xdescribe('24. First n Fibonacci', function() { + + it('should return an array', function() { + expect(Array.isArray(fibonacci(5))).to.equal(true); + }); + + it('should return first n Fibonacci numbers where n starts at index 1', function() { + expect(fibonacci(1)).to.eql([0, 1]); + expect(fibonacci(2)).to.eql([0, 1, 1]); + expect(fibonacci(3)).to.eql([0, 1, 1, 2]); + expect(fibonacci(4)).to.eql([0, 1, 1, 2, 3]); + expect(fibonacci(5)).to.eql([0, 1, 1, 2, 3, 5]); + expect(fibonacci(12)).to.eql([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]); + }); + + it('should return null for zero and negative integers', function() { + expect(fibonacci(0)).to.equal(null); + expect(fibonacci(-7)).to.equal(null); + }); + + it('should use recursion by calling self', function () { + fibonacci.proxyCallCount = 0; + fibonacci(5); + expect(fibonacci.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('25. Return nth Fibonacci', function() { + + it('should return a number', function() { + expect(typeof(nthFibo(5))).to.equal('number'); + }); + + it('should return the nth Fibonacci number', function() { + expect(nthFibo(0)).to.eql(0); + expect(nthFibo(1)).to.eql(1); + expect(nthFibo(2)).to.eql(1); + expect(nthFibo(3)).to.eql(2); + expect(nthFibo(4)).to.eql(3); + expect(nthFibo(5)).to.eql(5); + expect(nthFibo(12)).to.eql(144); + }); + + it('should return null for negative integers', function() { + expect(nthFibo(-5)).to.equal(null); + expect(nthFibo(-7)).to.equal(null); + }); + + it('should use recursion by calling self', function () { + nthFibo.proxyCallCount = 0; + nthFibo(5); + expect(nthFibo.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('26. Capitalize words in array', function() { + + it('should return an array', function() { + expect(Array.isArray(capitalizeWords(['i','am','learning','recursion']))).to.equal(true); + }); + + it('should capitalize all words in array', function() { + expect(capitalizeWords(['i','am','learning','recursion'])).to.eql(['I', 'AM', 'LEARNING', 'RECURSION']); + expect(capitalizeWords(["ceci","n'est","pas","une","pipe"])).to.eql(["CECI", "N'EST", "PAS", "UNE", "PIPE"]); + }); + + it('should use recursion by calling self', function () { + capitalizeWords.proxyCallCount = 0; + capitalizeWords(["ceci","n'est","pas","une","pipe"]); + expect(capitalizeWords.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('27. Capitalize first letter of words in array', function() { + + it('should return an array', function() { + expect(Array.isArray(capitalizeFirst(['i','am','learning','recursion']))).to.equal(true); + }); + + it('should capitalize first letter of each word in array', function() { + expect(capitalizeFirst(['i','am','learning','recursion'])).to.eql(['I', 'Am', 'Learning', 'Recursion']); + expect(capitalizeFirst(["ceci","n'est","pas","une","pipe"])).to.eql(["Ceci", "N'est", "Pas", "Une", "Pipe"]); + }); + + it('should use recursion by calling self', function () { + capitalizeFirst.proxyCallCount = 0; + capitalizeFirst(["ceci","n'est","pas","une","pipe"]); + expect(capitalizeFirst.proxyCallCount).to.be.above(1); + }); + + }); + + + + xdescribe('28. Sum even numbers in nested objects', function() { + var obj = { + a: 2, + b: {b: 2, bb: {b: 3, bb: {b: 2}}}, + c: {c: {c: 2}, cc: 'ball', ccc: 5}, + d: 1, + e: {e: {e: 2}, ee: 'car'} + }; + + it('should return a number', function() { + expect(typeof(nestedEvenSum(obj))).to.equal('number'); + }); + + it('should sum even numbers', function() { + expect(nestedEvenSum(obj)).to.eql(10); + }); + + it('should use recursion by calling self', function () { + nestedEvenSum.proxyCallCount = 0; + nestedEvenSum(obj); + expect(nestedEvenSum.proxyCallCount).to.be.above(1); + }); + + }); + + + + xdescribe('29. Flatten nested arrays', function() { + + it('should return an array', function() { + expect(Array.isArray(flatten([1,[2],[3,[[4]]],5]))).to.equal(true); + }); + + it('should return flattened array', function() { + expect(flatten([[1],[2,3],[[4]],5,6])).to.eql([1,2,3,4,5,6]); + expect(flatten([[12,[[34],[56]],78]])).to.eql([12,34,56,78]); + expect(flatten([3,[0,[34,[7,[18]]]]])).to.eql([3,0,34,7,18]); + expect(flatten([[1],[2,[],3],[],[[4]],5,6])).to.eql([1,2,3,4,5,6]); + }); + + it('should use recursion by calling self', function () { + flatten.proxyCallCount = 0; + flatten([3,[0,[34,[7,[18]]]]]); + expect(flatten.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('30. Tally letters in string', function() { + + it('should return an object', function() { + expect(typeof(letterTally('orangutan'))).to.equal('object'); + }); + + it('should return object containing tallies of unique letters', function() { + var output = letterTally('potato'); + + expect(output.p).to.equal(1); + expect(output.o).to.equal(2); + expect(output.t).to.equal(2); + expect(output.a).to.equal(1); + }); + + it('should return object containing the number of keys corresponding to unique letters', function () { + var output = letterTally('mississippi'); + var countKeys = Object.keys(output).length; + expect(countKeys).to.equal(4); + }); + + it('should use recursion by calling self', function () { + letterTally.proxyCallCount = 0; + letterTally('invasion'); + expect(letterTally.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('31. Eliminate consecutive duplicates', function() { + var input1 = [1,2,2,3,4,4,5,5,5]; + var input2 = [1,2,2,3,4,4,2,5,5,5,4,4]; + + it('should return an array', function() { + expect(Array.isArray(compress(input1))).to.equal(true); + }); + + it('should remove consecutive duplicates', function() { + expect(compress(input1)).to.eql([1,2,3,4,5]); + expect(compress(input2)).to.eql([1,2,3,4,2,5,4]); + }); + + it('should use recursion by calling self', function () { + compress.proxyCallCount = 0; + compress(input2); + expect(compress.proxyCallCount).to.be.above(1); + }); + + }); + + + + xdescribe('32. Augment each element in nested arrays', function() { + + it('should return an array', function() { + expect(Array.isArray(augmentElements([[],[3],[7]], 5))).to.equal(true); + }); + + it('should augment each element with given value', function() { + expect(augmentElements([[],[3],[7]], 5)).to.eql([[5],[3,5],[7,5]]); + expect(augmentElements([[],[3],[7]], null)).to.eql([[null],[3,null],[7,null]]); + expect(augmentElements([[],[3],[7]], '')).to.eql([[''],[3,''],[7,'']]); + }); + + it('should use recursion by calling self', function () { + augmentElements.proxyCallCount = 0; + augmentElements([[],[3],[7]], 5); + expect(augmentElements.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('33. Minimize zeroes', function() { + var input1 = [2,0,0,0,1,4]; + var input2 = [2,0,0,0,1,0,0,4]; + + it('should return an array', function() { + expect(Array.isArray(minimizeZeroes(input1))).to.equal(true); + }); + + it('should remove excess zeroes', function() { + expect(minimizeZeroes(input1)).to.eql([2,0,1,4]); + expect(minimizeZeroes(input2)).to.eql([2,0,1,0,4]); + }); + + it('should use recursion by calling self', function () { + minimizeZeroes.proxyCallCount = 0; + minimizeZeroes(input1); + expect(minimizeZeroes.proxyCallCount).to.be.above(1); + }); + + }); + + + + describe('34. Alternate sign', function() { + var input1 = [2,7,8,3,1,4]; + var input2 = [-2,-7,8,3,-1,4]; + + it('should return an array', function() { + expect(Array.isArray(alternateSign(input1))).to.equal(true); + }); + + it('should remove excess zeroes', function() { + expect(alternateSign(input1)).to.eql([2,-7,8,-3,1,-4]); + expect(alternateSign(input2)).to.eql([2,-7,8,-3,1,-4]); + }); + + it('should use recursion by calling self', function () { + alternateSign.proxyCallCount = 0; + alternateSign(input1); + expect(alternateSign.proxyCallCount).to.be.above(1); + }); + + }); + + + + xdescribe('35. Convert numbers to text', function() { + + it('should return a string', function() { + expect(typeof(numToText("I have 5 dogs and 6 ponies"))).to.equal('string'); + }); + + it('should convert single digits to their word equivalent', function() { + expect(numToText("I have 5 dogs and 6 ponies")).to.eql("I have five dogs and six ponies"); + expect(numToText("It takes 3 men to screw in 1 light bulb")).to.eql("It takes three men to screw in one light bulb"); + }); + + it('should use recursion by calling self', function () { + numToText.proxyCallCount = 0; + numToText("I have 5 dogs and 6 ponies"); + expect(numToText.proxyCallCount).to.be.above(1); + }); + + }); + + }); + + function checkForNativeMethods(runFunction) { + it('should not use the native version of map', function() { + // These spies are set up in testSupport.js + runFunction(); + expect(Array.prototype.map.called).to.equal(false); + }); + } + +}()); From 4101afbbf512d1f33f54468338e4d38c401bb6e8 Mon Sep 17 00:00:00 2001 From: Cain Date: Tue, 27 Nov 2018 21:02:40 -0600 Subject: [PATCH 13/36] (fix) Use proxies for node recursion callCount --- src/recursion.js | 141 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 115 insertions(+), 26 deletions(-) diff --git a/src/recursion.js b/src/recursion.js index 12ca0a3d7..a19d762a8 100644 --- a/src/recursion.js +++ b/src/recursion.js @@ -242,32 +242,121 @@ var mergeSort = function(array) { //----------------------------------- if ((typeof process !== 'undefined') && - (typeof process.versions.node !== 'undefined')) { - module.exports = { - factorial, - sum, - isEven, - sumBelow, - range, - exponent, - powerOfTwo, - reverse, - palindrome, - multiply, - compareStr, - createArray, - reverseArr, - buildList, - countOccurrence, - rMap, - nthFibo, - capitalizeWords, - capitalizeFirst, - letterTally, - compress, - minimizeZeroes, - alternateSign, + (typeof process.versions.node !== 'undefined')) { + + /** + * Due to some node-related issues with spying on recursive functions, + * it isn't possible to test a recursive function like so: + * + * var originalSum = sum; + * sum = sinon.spy(sum); + * + * sum([1 , 2, 3, 4, 5, 6]); + * + * // callCount will always 1 causing, this test to pass in node :( + * expect(sum.callCount).to.be.above(1); + * + * sum = originalSum; + * + * However, we use work around this using proxies! + * If you reassign the function to a proxy with the `apply` trap, + * I can make it increment a `proxyCallCount` property on the function and test that. + * + * MDN Proxies: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy + * MDN Proxy Apply Trap: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply + */ + const createProxy = (func) => { + func.toString = func.toString.bind(func); + + const recursiveFunctionCallCounterHandler = { + apply(target, thisArg, args) { + target.proxyCallCount = target.proxyCallCount ? target.proxyCallCount + 1 : 1; + return target.apply(thisArg, args); + }, }; + + return new Proxy(func, recursiveFunctionCallCounterHandler); + }; + + factorial = createProxy(factorial); + sum = createProxy(sum); + arraySum = createProxy(arraySum); + isEven = createProxy(isEven); + sumBelow = createProxy(sumBelow); + range = createProxy(range); + exponent = createProxy(exponent); + powerOfTwo = createProxy(powerOfTwo); + reverse = createProxy(reverse); + palindrome = createProxy(palindrome); + modulo = createProxy(modulo); + multiply = createProxy(multiply); + divide = createProxy(divide); + gcd = createProxy(gcd); + compareStr = createProxy(compareStr); + createArray = createProxy(createArray); + reverseArr = createProxy(reverseArr); + buildList = createProxy(buildList); + countOccurrence = createProxy(countOccurrence); + rMap = createProxy(rMap); + countKeysInObj = createProxy(countKeysInObj); + countValuesInObj = createProxy(countValuesInObj); + replaceKeysInObj = createProxy(replaceKeysInObj); + fibonacci = createProxy(fibonacci); + nthFibo = createProxy(nthFibo); + capitalizeWords = createProxy(capitalizeWords); + capitalizeFirst = createProxy(capitalizeFirst); + nestedEvenSum = createProxy(nestedEvenSum); + flatten = createProxy(flatten); + letterTally = createProxy(letterTally); + compress = createProxy(compress); + augmentElements = createProxy(augmentElements); + minimizeZeroes = createProxy(minimizeZeroes); + alternateSign = createProxy(alternateSign); + numToText = createProxy(numToText); + tagCount = createProxy(tagCount); + binarySearch = createProxy(binarySearch); + mergeSort = createProxy(mergeSort); + + module.exports = { + factorial, + sum, + arraySum, + isEven, + sumBelow, + range, + exponent, + powerOfTwo, + reverse, + palindrome, + modulo, + multiply, + divide, + gcd, + compareStr, + createArray, + reverseArr, + buildList, + countOccurrence, + rMap, + countKeysInObj, + countValuesInObj, + replaceKeysInObj, + fibonacci, + nthFibo, + capitalizeWords, + capitalizeFirst, + nestedEvenSum, + flatten, + letterTally, + compress, + augmentElements, + minimizeZeroes, + alternateSign, + numToText, + tagCount, + binarySearch, + mergeSort, + }; } -//----------------------------------- \ No newline at end of file +//----------------------------------- From fc0f7a9f7e07a39418fa27cb37d414d75c6c4179 Mon Sep 17 00:00:00 2001 From: Cain Date: Tue, 27 Nov 2018 22:24:52 -0600 Subject: [PATCH 14/36] (cleanup) Change createProxy to createSpyProxy + update wording --- src/recursion.js | 95 +++++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 45 deletions(-) diff --git a/src/recursion.js b/src/recursion.js index a19d762a8..3b622b4af 100644 --- a/src/recursion.js +++ b/src/recursion.js @@ -246,26 +246,31 @@ if ((typeof process !== 'undefined') && /** * Due to some node-related issues with spying on recursive functions, - * it isn't possible to test a recursive function like so: + * it isn't possible to test them with sinon spies like so: * * var originalSum = sum; * sum = sinon.spy(sum); * - * sum([1 , 2, 3, 4, 5, 6]); + * sum([1, 2, 3, 4, 5, 6]); * - * // callCount will always 1 causing, this test to pass in node :( + * // callCount will always 1 causing, this test to always fail in node :( * expect(sum.callCount).to.be.above(1); * * sum = originalSum; * - * However, we use work around this using proxies! - * If you reassign the function to a proxy with the `apply` trap, - * I can make it increment a `proxyCallCount` property on the function and test that. + * However, we can work around this by using proxies! + * If you reassign the function to a proxy and use the `apply` trap, + * you can make a `proxyCallCount` property on the function, + * increment it each time it's called, and then test that instead. + * + * sum.proxyCallCount = 0; + * sum([1, 2, 3, 4, 5, 6]); + * expect(sum.proxyCallCount).to.be.above(1); * * MDN Proxies: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy * MDN Proxy Apply Trap: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply */ - const createProxy = (func) => { + const createSpyProxy = (func) => { func.toString = func.toString.bind(func); const recursiveFunctionCallCounterHandler = { @@ -278,44 +283,44 @@ if ((typeof process !== 'undefined') && return new Proxy(func, recursiveFunctionCallCounterHandler); }; - factorial = createProxy(factorial); - sum = createProxy(sum); - arraySum = createProxy(arraySum); - isEven = createProxy(isEven); - sumBelow = createProxy(sumBelow); - range = createProxy(range); - exponent = createProxy(exponent); - powerOfTwo = createProxy(powerOfTwo); - reverse = createProxy(reverse); - palindrome = createProxy(palindrome); - modulo = createProxy(modulo); - multiply = createProxy(multiply); - divide = createProxy(divide); - gcd = createProxy(gcd); - compareStr = createProxy(compareStr); - createArray = createProxy(createArray); - reverseArr = createProxy(reverseArr); - buildList = createProxy(buildList); - countOccurrence = createProxy(countOccurrence); - rMap = createProxy(rMap); - countKeysInObj = createProxy(countKeysInObj); - countValuesInObj = createProxy(countValuesInObj); - replaceKeysInObj = createProxy(replaceKeysInObj); - fibonacci = createProxy(fibonacci); - nthFibo = createProxy(nthFibo); - capitalizeWords = createProxy(capitalizeWords); - capitalizeFirst = createProxy(capitalizeFirst); - nestedEvenSum = createProxy(nestedEvenSum); - flatten = createProxy(flatten); - letterTally = createProxy(letterTally); - compress = createProxy(compress); - augmentElements = createProxy(augmentElements); - minimizeZeroes = createProxy(minimizeZeroes); - alternateSign = createProxy(alternateSign); - numToText = createProxy(numToText); - tagCount = createProxy(tagCount); - binarySearch = createProxy(binarySearch); - mergeSort = createProxy(mergeSort); + factorial = createSpyProxy(factorial); + sum = createSpyProxy(sum); + arraySum = createSpyProxy(arraySum); + isEven = createSpyProxy(isEven); + sumBelow = createSpyProxy(sumBelow); + range = createSpyProxy(range); + exponent = createSpyProxy(exponent); + powerOfTwo = createSpyProxy(powerOfTwo); + reverse = createSpyProxy(reverse); + palindrome = createSpyProxy(palindrome); + modulo = createSpyProxy(modulo); + multiply = createSpyProxy(multiply); + divide = createSpyProxy(divide); + gcd = createSpyProxy(gcd); + compareStr = createSpyProxy(compareStr); + createArray = createSpyProxy(createArray); + reverseArr = createSpyProxy(reverseArr); + buildList = createSpyProxy(buildList); + countOccurrence = createSpyProxy(countOccurrence); + rMap = createSpyProxy(rMap); + countKeysInObj = createSpyProxy(countKeysInObj); + countValuesInObj = createSpyProxy(countValuesInObj); + replaceKeysInObj = createSpyProxy(replaceKeysInObj); + fibonacci = createSpyProxy(fibonacci); + nthFibo = createSpyProxy(nthFibo); + capitalizeWords = createSpyProxy(capitalizeWords); + capitalizeFirst = createSpyProxy(capitalizeFirst); + nestedEvenSum = createSpyProxy(nestedEvenSum); + flatten = createSpyProxy(flatten); + letterTally = createSpyProxy(letterTally); + compress = createSpyProxy(compress); + augmentElements = createSpyProxy(augmentElements); + minimizeZeroes = createSpyProxy(minimizeZeroes); + alternateSign = createSpyProxy(alternateSign); + numToText = createSpyProxy(numToText); + tagCount = createSpyProxy(tagCount); + binarySearch = createSpyProxy(binarySearch); + mergeSort = createSpyProxy(mergeSort); module.exports = { factorial, From a56687b758578c76df34a283a9f4a7190cfd2848 Mon Sep 17 00:00:00 2001 From: Cain Date: Tue, 27 Nov 2018 23:18:41 -0600 Subject: [PATCH 15/36] (fix) Use plain mocha for travis intead of karma --- .travis.yml | 5 - karma.conf.js | 33 - package-lock.json | 3721 ++------------------------------------------- package.json | 17 +- 4 files changed, 147 insertions(+), 3629 deletions(-) delete mode 100644 karma.conf.js diff --git a/.travis.yml b/.travis.yml index 56abebb1f..fc03e8ec5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,10 @@ language: node_js node_js: - "7" dist: trusty # needs Ubuntu Trusty -sudo: true # needed for Chromium sandbox -addons: - chrome: stable # have Travis install chrome stable. cache: yarn: true directories: - node_modules -before_install: - - google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost & install: - yarn script: diff --git a/karma.conf.js b/karma.conf.js deleted file mode 100644 index f8a81dabc..000000000 --- a/karma.conf.js +++ /dev/null @@ -1,33 +0,0 @@ -const ChromiumRevision = require('puppeteer/package.json').puppeteer.chromium_revision -const Downloader = require('puppeteer/utils/ChromiumDownloader') -const revisionInfo = Downloader.revisionInfo(Downloader.currentPlatform(), ChromiumRevision) - -process.env.CHROME_BIN = revisionInfo.executablePath - -module.exports = function (config) { - config.set({ - frameworks: ['chai', 'mocha', 'sinon-chai', 'sinon'], - files: [ - 'lib/location.js', - { pattern: 'lib/css/mocha.css', included: false, served: true }, - { pattern: 'lib/chai.js', included: false, served: true }, - { pattern: 'lib/mocha.js', included: false, served: true }, - { pattern: 'lib/sinon.js', included: false, served: true }, - { pattern: 'lib/sinon-chai.js', included: false, served: true }, - { pattern: 'lib/cardboard.js', included: false, served: true }, - { pattern: 'lib/testSupport.js', included: false, served: true }, - { pattern: 'lib/jquery.js', included: false, served: true }, - { pattern: 'SpecRunner.html', included: true, served: true }, - { pattern: 'src/recursion.js', included: false, served: true }, - { pattern: 'spec/*.js', included: false, served: true }, - ], - reporters: ['progress'], - port: 9876, - colors: true, - logLevel: config.LOG_INFO, - browsers: ['ChromeHeadless'], - autoWatch: false, - concurrency: Infinity, - globals: {inKarma: true} - }) -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b55546be2..7804ab14c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,3432 +20,270 @@ "array-from": "^2.1.1" } }, - "accepts": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", - "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=", - "dev": true, - "requires": { - "mime-types": "~2.1.11", - "negotiator": "0.6.1" - } - }, - "after": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", - "dev": true - }, - "agent-base": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", - "dev": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, "array-from": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=" }, - "array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arraybuffer.slice": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", - "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=", - "dev": true - }, "assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true - }, - "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", - "dev": true + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, - "base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", - "dev": true - }, - "base64id": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", - "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", - "dev": true - }, - "better-assert": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", - "dev": true, - "requires": { - "callsite": "1.0.0" - } - }, - "binary-extensions": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", - "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", - "dev": true - }, - "blob": { - "version": "0.0.4", - "resolved": "http://registry.npmjs.org/blob/-/blob-0.0.4.tgz", - "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=", - "dev": true - }, - "bluebird": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", - "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", - "dev": true - }, - "body-parser": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", - "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", - "dev": true, - "requires": { - "bytes": "3.0.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "~1.6.3", - "iconv-lite": "0.4.23", - "on-finished": "~2.3.0", - "qs": "6.5.2", - "raw-body": "2.3.3", - "type-is": "~1.6.16" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, - "requires": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true - }, - "buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", - "dev": true - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", - "dev": true + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" }, "chai": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", - "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", - "dev": true, + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", "requires": { - "assertion-error": "^1.0.1", - "check-error": "^1.0.1", - "deep-eql": "^3.0.0", + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", "get-func-name": "^2.0.0", - "pathval": "^1.0.0", - "type-detect": "^4.0.0" + "pathval": "^1.1.0", + "type-detect": "^4.0.5" } }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "colors": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.2.tgz", - "integrity": "sha512-rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ==", - "dev": true - }, - "combine-lists": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz", - "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=", - "dev": true, - "requires": { - "lodash": "^4.5.0" - }, - "dependencies": { - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", - "dev": true - } - } + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" }, "commander": { "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "component-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", - "dev": true - }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "component-inherit": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", - "dev": true + "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "connect": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", - "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", - "dev": true, - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.0", - "parseurl": "~1.3.2", - "utils-merge": "1.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", - "dev": true - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.5.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, "requires": { "ms": "2.0.0" } }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, "deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, "requires": { "type-detect": "^4.0.0" } }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", - "dev": true - }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" }, - "dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", - "dev": true, - "requires": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, - "engine.io": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.3.tgz", - "integrity": "sha1-jef5eJXSDTm4X4ju7nd7K9QrE9Q=", - "dev": true, - "requires": { - "accepts": "1.3.3", - "base64id": "1.0.0", - "cookie": "0.3.1", - "debug": "2.3.3", - "engine.io-parser": "1.3.2", - "ws": "1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "http://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } - } + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" }, - "engine.io-client": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.3.tgz", - "integrity": "sha1-F5jtk0USRkU9TG9jXXogH+lA1as=", - "dev": true, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "2.3.3", - "engine.io-parser": "1.3.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parsejson": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "1.1.2", - "xmlhttprequest-ssl": "1.5.3", - "yeast": "0.1.2" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "http://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, - "engine.io-parser": { - "version": "1.3.2", - "resolved": "http://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz", - "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=", - "dev": true, - "requires": { - "after": "0.8.2", - "arraybuffer.slice": "0.0.6", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.4", - "has-binary": "0.1.7", - "wtf-8": "1.0.0" - } + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", - "dev": true + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, - "es6-promise": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz", - "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==", - "dev": true + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "http://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "dev": true, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { - "es6-promise": "^4.0.3" + "once": "^1.3.0", + "wrappy": "1" } }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" }, - "eventemitter3": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", - "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", - "dev": true + "just-extend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-3.0.0.tgz", + "integrity": "sha512-Fu3T6pKBuxjWT/p4DkqGHFRsysc8OauWr4ZRTY9dIx07Y9O0RkoR5jcv28aeD1vuAwhm3nLkDurwLXoALp4DpQ==" }, - "expand-braces": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz", - "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", - "dev": true, - "requires": { - "array-slice": "^0.2.3", - "array-unique": "^0.2.1", - "braces": "^0.1.2" - }, - "dependencies": { - "braces": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz", - "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=", - "dev": true, - "requires": { - "expand-range": "^0.1.0" - } - }, - "expand-range": { - "version": "0.1.1", - "resolved": "http://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", - "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", - "dev": true, - "requires": { - "is-number": "^0.1.1", - "repeat-string": "^0.2.2" - } - }, - "is-number": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz", - "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=", - "dev": true - }, - "repeat-string": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz", - "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=", - "dev": true - } - } + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } + "lolex": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", + "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==" }, - "expand-range": { - "version": "1.8.2", - "resolved": "http://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { - "fill-range": "^2.1.0" + "brace-expansion": "^1.1.7" } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } + "minimist": { + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { - "is-extglob": "^1.0.0" - } - }, - "extract-zip": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", - "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", - "dev": true, - "requires": { - "concat-stream": "1.6.2", - "debug": "2.6.9", - "mkdirp": "0.5.1", - "yauzl": "2.4.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "finalhandler": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", - "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.3.1", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", - "dev": true - } - } - }, - "follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "dev": true, - "requires": { - "debug": "=3.1.0" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fs-access": { - "version": "1.0.1", - "resolved": "http://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", - "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", - "dev": true, - "requires": { - "null-check": "^1.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.21", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": "^2.1.0" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - }, - "minipass": { - "version": "2.2.4", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "^5.1.1", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.2.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.10.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.0", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.1.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.1.10", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.0.5" - } - }, - "safe-buffer": { - "version": "5.1.1", - "bundled": true, - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.5.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "yallist": { - "version": "3.0.2", - "bundled": true, - "dev": true - } - } - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "dev": true - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "has-binary": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz", - "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=", - "dev": true, - "requires": { - "isarray": "0.0.1" - } - }, - "has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "http-errors": { - "version": "1.6.3", - "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "http-proxy": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", - "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", - "dev": true, - "requires": { - "eventemitter3": "^3.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "https-proxy-agent": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", - "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", - "dev": true, - "requires": { - "agent-base": "^4.1.0", - "debug": "^3.1.0" - } - }, - "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "isbinaryfile": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz", - "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==", - "dev": true, - "requires": { - "buffer-alloc": "^1.2.0" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } - } - }, - "json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", - "dev": true - }, - "just-extend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-3.0.0.tgz", - "integrity": "sha512-Fu3T6pKBuxjWT/p4DkqGHFRsysc8OauWr4ZRTY9dIx07Y9O0RkoR5jcv28aeD1vuAwhm3nLkDurwLXoALp4DpQ==" - }, - "karma": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/karma/-/karma-1.7.1.tgz", - "integrity": "sha512-k5pBjHDhmkdaUccnC7gE3mBzZjcxyxYsYVaqiL2G5AqlfLyBO5nw2VdNK+O16cveEPd/gIOWULH7gkiYYwVNHg==", - "dev": true, - "requires": { - "bluebird": "^3.3.0", - "body-parser": "^1.16.1", - "chokidar": "^1.4.1", - "colors": "^1.1.0", - "combine-lists": "^1.0.0", - "connect": "^3.6.0", - "core-js": "^2.2.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.0", - "expand-braces": "^0.1.1", - "glob": "^7.1.1", - "graceful-fs": "^4.1.2", - "http-proxy": "^1.13.0", - "isbinaryfile": "^3.0.0", - "lodash": "^3.8.0", - "log4js": "^0.6.31", - "mime": "^1.3.4", - "minimatch": "^3.0.2", - "optimist": "^0.6.1", - "qjobs": "^1.1.4", - "range-parser": "^1.2.0", - "rimraf": "^2.6.0", - "safe-buffer": "^5.0.1", - "socket.io": "1.7.3", - "source-map": "^0.5.3", - "tmp": "0.0.31", - "useragent": "^2.1.12" - } - }, - "karma-chai": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/karma-chai/-/karma-chai-0.1.0.tgz", - "integrity": "sha1-vuWtQEAFF4Ea40u5RfdikJEIt5o=", - "dev": true - }, - "karma-chrome-launcher": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", - "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", - "dev": true, - "requires": { - "fs-access": "^1.0.0", - "which": "^1.2.1" - } - }, - "karma-mocha": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-1.3.0.tgz", - "integrity": "sha1-7qrH/8DiAetjxGdEDStpx883eL8=", - "dev": true, - "requires": { - "minimist": "1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "karma-sinon": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/karma-sinon/-/karma-sinon-1.0.5.tgz", - "integrity": "sha1-TjRD8oMP3s/2JNN0cWPxIX2qKpo=" - }, - "karma-sinon-chai": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/karma-sinon-chai/-/karma-sinon-chai-1.3.4.tgz", - "integrity": "sha512-Oatu8tdkfWaSveM809euI6KGcNJRdoXFilz9ozSf+vPwrM73kncu54nsfkLcMqR/iht3PXASAGK9La5oU2xDKQ==", - "requires": { - "lolex": "^1.6.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lodash": { - "version": "3.10.1", - "resolved": "http://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" - }, - "log4js": { - "version": "0.6.38", - "resolved": "http://registry.npmjs.org/log4js/-/log4js-0.6.38.tgz", - "integrity": "sha1-LElBFmldb7JUgJQ9P8hy5mKlIv0=", - "dev": true, - "requires": { - "readable-stream": "~1.0.2", - "semver": "~4.3.3" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, - "lolex": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", - "integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=" - }, - "lru-cache": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.4.tgz", - "integrity": "sha512-EPstzZ23znHUVLKj+lcXO1KvZkrlw+ZirdwvOmnAnA/1PB4ggyXJ77LRkCqkff+ShQ+cqoxCxLQOh4cKITO5iA==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^3.0.2" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", - "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", - "dev": true - }, - "media-typer": { - "version": "0.3.0", - "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", - "dev": true - }, - "mime-types": { - "version": "2.1.21", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", - "dev": true, - "requires": { - "mime-db": "~1.37.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" + "minimist": "0.0.8" } }, "mocha": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", - "dev": true, - "requires": { - "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.5", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "nan": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", - "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, - "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", - "dev": true - }, - "nise": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.6.tgz", - "integrity": "sha512-1GedetLKzmqmgwabuMSqPsT7oumdR77SBpDfNNJhADRIeA3LN/2RVqR4fFqwvzhAqcTef6PPCzQwITE/YQ8S8A==", - "requires": { - "@sinonjs/formatio": "3.0.0", - "just-extend": "^3.0.0", - "lolex": "^2.3.2", - "path-to-regexp": "^1.7.0", - "text-encoding": "^0.6.4" - }, - "dependencies": { - "@sinonjs/formatio": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.0.0.tgz", - "integrity": "sha512-vdjoYLDptCgvtJs57ULshak3iJe4NW3sJ3g36xVDGff5AE8P30S6A093EIEPjdi2noGhfuNOEkbxt3J3awFW1w==", - "requires": { - "@sinonjs/samsam": "2.1.0" - } - }, - "lolex": { - "version": "2.7.5", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", - "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==" - } - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "null-check": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", - "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", - "dev": true - }, - "object-assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", - "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", - "dev": true - }, - "object-component": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", - "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "options": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", - "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "parsejson": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz", - "integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseqs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", - "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseuri": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", - "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", - "requires": { - "isarray": "0.0.1" - } - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true - }, - "progress": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz", - "integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==", - "dev": true - }, - "proxy-from-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", - "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "puppeteer": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-0.11.0.tgz", - "integrity": "sha512-/o8uY6VChG74B1HYBZkLDU6aIekWeOd85wez9YxB9SNbDnFNsUddv2F4xWuhwvQ4ab84vb+1VX4fxs2kBz3u8g==", - "dev": true, - "requires": { - "debug": "^2.6.8", - "extract-zip": "^1.6.5", - "https-proxy-agent": "^2.1.0", - "mime": "^1.3.4", - "progress": "^2.0.0", - "proxy-from-env": "^1.0.0", - "rimraf": "^2.6.1", - "ws": "^3.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", - "dev": true - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - } - } - }, - "qjobs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", - "dev": true - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, - "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", - "dev": true - }, - "raw-body": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", - "dev": true, + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.3", - "iconv-lite": "0.4.23", - "unpipe": "1.0.0" + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" } }, - "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } - } + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, + "nise": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.6.tgz", + "integrity": "sha512-1GedetLKzmqmgwabuMSqPsT7oumdR77SBpDfNNJhADRIeA3LN/2RVqR4fFqwvzhAqcTef6PPCzQwITE/YQ8S8A==", "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" + "@sinonjs/formatio": "3.0.0", + "just-extend": "^3.0.0", + "lolex": "^2.3.2", + "path-to-regexp": "^1.7.0", + "text-encoding": "^0.6.4" }, "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { + "@sinonjs/formatio": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.0.0.tgz", + "integrity": "sha512-vdjoYLDptCgvtJs57ULshak3iJe4NW3sJ3g36xVDGff5AE8P30S6A093EIEPjdi2noGhfuNOEkbxt3J3awFW1w==", "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "@sinonjs/samsam": "2.1.0" } } } }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" + "wrappy": "1" } }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true + "path-is-absolute": { + "version": "1.0.1", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", "requires": { - "glob": "^7.0.5" + "isarray": "0.0.1" } }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safe-regex": { + "pathval": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=" }, "samsam": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==" }, - "semver": { - "version": "4.3.6", - "resolved": "http://registry.npmjs.org/semver/-/semver-4.3.6.tgz", - "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", - "dev": true - }, - "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, "sinon": { - "version": "4.5.0", - "resolved": "http://registry.npmjs.org/sinon/-/sinon-4.5.0.tgz", - "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-5.1.1.tgz", + "integrity": "sha512-h/3uHscbt5pQNxkf7Y/Lb9/OM44YNCicHakcq73ncbrIS8lXg+ZGOZbtuU+/km4YnyiCYfQQEwANaReJz7KDfw==", "requires": { "@sinonjs/formatio": "^2.0.0", - "diff": "^3.1.0", + "diff": "^3.5.0", "lodash.get": "^4.4.2", - "lolex": "^2.2.0", - "nise": "^1.2.0", - "supports-color": "^5.1.0", - "type-detect": "^4.0.5" - }, - "dependencies": { - "lolex": { - "version": "2.7.5", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", - "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==" - } - } - }, - "sinon-chai": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-2.14.0.tgz", - "integrity": "sha512-9stIF1utB0ywNHNT7RgiXbdmen8QDCRsrTjw+G9TgKt1Yexjiv8TOWZ6WHsTPz57Yky3DIswZvEqX8fpuHNDtQ==" - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "socket.io": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.7.3.tgz", - "integrity": "sha1-uK+cq6AJSeVo42nxMn6pvp6iRhs=", - "dev": true, - "requires": { - "debug": "2.3.3", - "engine.io": "1.8.3", - "has-binary": "0.1.7", - "object-assign": "4.1.0", - "socket.io-adapter": "0.5.0", - "socket.io-client": "1.7.3", - "socket.io-parser": "2.3.1" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "http://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } - } - }, - "socket.io-adapter": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz", - "integrity": "sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s=", - "dev": true, - "requires": { - "debug": "2.3.3", - "socket.io-parser": "2.3.1" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "http://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } - } - }, - "socket.io-client": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.3.tgz", - "integrity": "sha1-sw6GqhDV7zVGYBwJzeR2Xjgdo3c=", - "dev": true, - "requires": { - "backo2": "1.0.2", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "2.3.3", - "engine.io-client": "1.8.3", - "has-binary": "0.1.7", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseuri": "0.0.5", - "socket.io-parser": "2.3.1", - "to-array": "0.1.4" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "http://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } - } - }, - "socket.io-parser": { - "version": "2.3.1", - "resolved": "http://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz", - "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=", - "dev": true, - "requires": { - "component-emitter": "1.1.2", - "debug": "2.2.0", - "isarray": "0.0.1", - "json3": "3.3.2" - }, - "dependencies": { - "component-emitter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", - "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=", - "dev": true - }, - "debug": { - "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "ms": { - "version": "0.7.1", - "resolved": "http://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - } - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" + "lolex": "^2.4.2", + "nise": "^1.3.3", + "supports-color": "^5.4.0", + "type-detect": "^4.0.8" } }, "supports-color": { @@ -3461,286 +299,15 @@ "resolved": "http://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=" }, - "tmp": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", - "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.1" - } - }, - "to-array": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", - "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" }, - "type-is": { - "version": "1.6.16", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", - "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.18" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "ultron": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", - "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", - "dev": true - }, - "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } - } - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "useragent": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", - "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==", - "dev": true, - "requires": { - "lru-cache": "4.1.x", - "tmp": "0.0.x" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "ws": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz", - "integrity": "sha1-iiRPoFJAHgjJiGz0SoUYnh/UBn8=", - "dev": true, - "requires": { - "options": ">=0.0.5", - "ultron": "1.0.x" - } - }, - "wtf-8": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wtf-8/-/wtf-8-1.0.0.tgz", - "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=", - "dev": true - }, - "xmlhttprequest-ssl": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", - "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=", - "dev": true - }, - "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", - "dev": true - }, - "yauzl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", - "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", - "dev": true, - "requires": { - "fd-slicer": "~1.0.1" - } - }, - "yeast": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" } } } diff --git a/package.json b/package.json index 0d1c6482b..606f3b097 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "pretest": "npm install", "test": "mocha ./test || :", "posttest": "rm -rf ./test ./node_modules", - "test:travis": "karma start --single-run --browsers ChromeHeadless karma.conf.js" + "test:travis": "mocha ./test --reporter spec" }, "repository": { "type": "git", @@ -23,20 +23,9 @@ "url": "https://github.com/OperationSpark/recursion-prompts/issues" }, "homepage": "https://github.com/OperationSpark/recursion-prompts#readme", - "devDependencies": { + "dependencies": { "chai": "^4.1.2", "mocha": "^5.2.0", - "sinon": "^5.0.10", - "karma": "^1.7.1", - "karma-chai": "^0.1.0", - "karma-chrome-launcher": "^2.2.0", - "karma-mocha": "^1.3.0", - "puppeteer": "^0.11.0" - }, - "dependencies": { - "karma-sinon": "^1.0.5", - "karma-sinon-chai": "^1.3.2", - "sinon": "^4.0.1", - "sinon-chai": "^2.14.0" + "sinon": "^5.0.10" } } From 4d395792b0184e08d7a95e4468793421e2fb5dc2 Mon Sep 17 00:00:00 2001 From: Cain Date: Wed, 28 Nov 2018 17:08:25 -0600 Subject: [PATCH 16/36] Remove pending tests --- test/part1.js | 444 -------------------------------------------------- 1 file changed, 444 deletions(-) diff --git a/test/part1.js b/test/part1.js index 1d1283b4b..d0b831093 100755 --- a/test/part1.js +++ b/test/part1.js @@ -104,8 +104,6 @@ }); - - describe('2. Sum of Integers', function() { it('should return a number', function() { @@ -154,58 +152,6 @@ }); - - - xdescribe('3. Sum Integers in Array', function() { - - it('should return a number', function() { - expect(typeof(arraySum([[1],[2,3],[[4]],5,6]))).to.eql('number'); - }); - - it('should return the sum of an array with nested arrays of non-negative integers', function() { - expect(arraySum([[1],[2,3],[[4]],5,6])).to.eql(21); - expect(arraySum([[12,[[34],[56]],78]])).to.eql(180); - expect(arraySum([3,[0,[34,[7,[18]]]]])).to.eql(62); - }); - - it('should return the sum of an array with nested arrays of negative integers', function() { - expect(arraySum([[-1],[-2,-3],[[-4]],-5,-6])).to.eql(-21); - expect(arraySum([[-12,[[-34],[-56]],-78]])).to.eql(-180); - expect(arraySum([-3,[0,[-34,[-7,[-18]]]]])).to.eql(-62); - }); - - it('should return the sum of an array with nested arrays of mixed non-negative and negative integers', function() { - expect(arraySum([[1],[-2,3],[[-4]],5,-6])).to.eql(-3); - expect(arraySum([[-12,[[34],[-56]],78]])).to.eql(44); - expect(arraySum([3,[0,[-34,[-7,[18]]]]])).to.eql(-20); - }); - - it('should return 0 for empty array', function() { - expect(arraySum([])).to.eql(0); - }); - - it('should accept an array with a single integer', function() { - expect(arraySum([4])).to.eql(4); - expect(arraySum([0])).to.eql(0); - expect(arraySum([-37])).to.eql(-37); - }); - - it('should not mutate the input array', function() { - var input = [[1],[2,3],[[4]],5,6]; - var result = arraySum(input); - expect(input).to.eql([[1],[2,3],[[4]],5,6]); - }); - - it('should use recursion by calling self', function () { - arraySum.proxyCallCount = 0; - arraySum([[1],[2,3],[[4]],5,6]); - expect(arraySum.proxyCallCount).to.be.above(1); - }); - - }); - - - describe('4. Check if Even', function() { it('should return a boolean', function() { @@ -245,8 +191,6 @@ }); - - describe('5. Sum Below', function() { it('should return a number', function() { @@ -278,8 +222,6 @@ }); - - describe('6. Integer Range', function() { it('should return an array', function() { @@ -317,8 +259,6 @@ }); - - describe('7. Compute Exponent', function() { it('should return a number', function() { @@ -366,8 +306,6 @@ }); - - describe('8. Power of Two', function() { it('should return a boolean', function() { @@ -392,8 +330,6 @@ }); - - describe('9. Reverse String', function() { it('should return a string', function() { @@ -421,8 +357,6 @@ }); - - describe('10. Palindrome', function() { it('should return a boolean', function() { @@ -456,44 +390,6 @@ }); - - - xdescribe('11. Modulo', function() { - - it('should return a number', function() { - expect(typeof(modulo(5,2))).to.equal('number'); - expect(typeof(modulo(8,4))).to.equal('number'); - }); - - it("should not use complex math", function() { - expect(modulo.toString()).to.not.contain('*'); - expect(modulo.toString()).to.not.contain('/'); - expect(modulo.toString()).to.not.contain('%'); - expect(modulo.toString()).to.not.contain('Math'); - }); - - it('should return the remainder of two integers', function() { - expect(modulo(2, 1)).to.equal(2 % 1); - expect(modulo(17, 5)).to.equal(17 % 5); - expect(modulo(78, 453)).to.equal(78 % 453); - expect(modulo(-79, 82)).to.equal(-79 % 82); - expect(modulo(-275, -502)).to.equal(-275 % -502); - expect(modulo(-275, -274)).to.equal(-275 % -274); - expect(modulo(-4, 2)).to.equal(-4 % 2); - expect(modulo(0, 32)).to.equal(0 % 32); - expect(modulo(0, 0).toString()).to.equal('NaN'); - }); - - it('should use recursion by calling self', function () { - modulo.proxyCallCount = 0; - modulo(5,2); - expect(modulo.proxyCallCount).to.be.above(1); - }); - - }); - - - describe('12. Multiply', function() { it('should return a number', function() { @@ -526,79 +422,6 @@ }); - - - xdescribe('13. Divide', function() { - - it('should return a number', function() { - expect(typeof(divide(5,2))).to.equal('number'); - expect(typeof(divide(8,4))).to.equal('number'); - }); - - it("should not use complex math", function() { - expect(divide.toString()).to.not.contain('*'); - expect(divide.toString()).to.not.contain('/'); - expect(divide.toString()).to.not.contain('%'); - expect(divide.toString()).to.not.contain('Math'); - }); - - it('should return the quotient of two integers', function() { - expect(divide(2, 1)).to.equal(~~(2 / 1)); - expect(divide(17, 5)).to.equal(~~(17 / 5)); - expect(divide(78, 453)).to.equal(~~(78 / 453)); - expect(divide(-79, 82)).to.equal(~~(-79 / 82)); - expect(divide(-275, -582)).to.equal(~~(-275 / -582)); - expect(divide(0, 32)).to.equal(~~(0 / 32)); - expect(divide(0, 0).toString()).to.equal('NaN'); - }); - - it('should use recursion by calling self', function () { - divide.proxyCallCount = 0; - divide(17, 5); - expect(divide.proxyCallCount).to.be.above(1); - }); - - }); - - - - xdescribe('14. Greatest Common Divisor', function() { - - it('should return a number', function() { - expect(typeof(gcd(4,36))).to.equal('number'); - }); - - it('should return greatest common divisor of two positive integers', function() { - expect(gcd(4,36)).to.equal(4); - expect(gcd(24,88)).to.equal(8); - expect(gcd(339,17)).to.equal(1); - expect(gcd(126,900)).to.equal(18); - }); - - it('should return null for negative integers', function() { - expect(gcd(-4, 2)).to.equal(null); - expect(gcd(-5, 5)).to.equal(null); - expect(gcd(5, -5)).to.equal(null); - expect(gcd(7, -36)).to.equal(null); - expect(gcd(-10, -58)).to.equal(null); - expect(gcd(-92, -5)).to.equal(null); - // expect(gcd(0, 0)).to.equal(null); - // expect(gcd(0, 5)).to.equal(null); - // expect(gcd(5, 0)).to.equal(null); - // expect(gcd(-5, 0)).to.equal(null); - // expect(gcd(0, -5)).to.equal(null); - }); - - it('should use recursion by calling self', function () { - gcd.proxyCallCount = 0; - gcd(17, 5); - expect(gcd.proxyCallCount).to.be.above(1); - }); - - }); - - - describe('15. Compare Strings', function() { it('should return a boolean', function() { @@ -624,8 +447,6 @@ }); - - describe('16. Create array from string', function() { it('should return an array', function() { @@ -647,8 +468,6 @@ }); - - describe('17. Reverse an array', function() { it('should return an array', function() { @@ -670,8 +489,6 @@ }); - - describe('18. Build an array with a given value and length', function() { it('should return an array', function() { @@ -697,8 +514,6 @@ }); - - describe('19. Count value in array', function() { it('should return a number', function() { @@ -725,8 +540,6 @@ }); - - describe('20. Recursive Map', function() { var timesTwo = function(n) { return n * 2; }; @@ -760,156 +573,6 @@ }); - - - xdescribe('21. Count key in object', function() { - var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; - - it('should return a number', function() { - expect(typeof(countKeysInObj(input, 'r'))).to.equal('number'); - expect(typeof(countKeysInObj(input, 'e'))).to.equal('number'); - expect(typeof(countKeysInObj(input, 'p'))).to.equal('number'); - }); - - it('should return the number of occurrences of the property', function() { - expect(countKeysInObj(input, 'e')).to.eql(2); - expect(countKeysInObj(input, 'x')).to.eql(1); - expect(countKeysInObj(input, 'y')).to.eql(2); - expect(countKeysInObj(input, 't')).to.eql(1); - expect(countKeysInObj(input, 'r')).to.eql(1); - expect(countKeysInObj(input, 'p')).to.eql(1); - }); - - it('should use recursion by calling self', function () { - countKeysInObj.proxyCallCount = 0; - countKeysInObj(input, 'e'); - expect(countKeysInObj.proxyCallCount).to.be.above(1); - }); - - }); - - - - xdescribe('22. Count value in object', function() { - var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; - - it('should return a number', function() { - expect(typeof(countValuesInObj(input, 'r'))).to.equal('number'); - expect(typeof(countValuesInObj(input, 'e'))).to.equal('number'); - expect(typeof(countValuesInObj(input, 'p'))).to.equal('number'); - }); - - it('should return the count of the occurrences of the property', function() { - expect(countValuesInObj(input, 'e')).to.eql(1); - expect(countValuesInObj(input, 'x')).to.eql(0); - expect(countValuesInObj(input, 'y')).to.eql(1); - expect(countValuesInObj(input, 't')).to.eql(0); - expect(countValuesInObj(input, 'r')).to.eql(2); - expect(countValuesInObj(input, 'p')).to.eql(0); - }); - - it('should use recursion by calling self', function () { - countValuesInObj.proxyCallCount = 0; - countValuesInObj(input, 'r'); - expect(countValuesInObj.proxyCallCount).to.be.above(1); - }); - - }); - - - - xdescribe('23. Replace keys in object', function() { - - var tallyKeys = function(obj) { - var count = 0; - for (var k in obj) { - if (typeof obj[k] === 'object') { - count += tallyKeys(obj[k]); - } - count++; - } - return count; - }; - - it('should return an object', function() { - var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; - expect(typeof(replaceKeysInObj(input, 'r', 'a'))).to.equal('object'); - expect(typeof(replaceKeysInObj(input, 'e', 0))).to.equal('object'); - }); - - it('should return object containing renamed keys', function() { - var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}}, 'y':'e'}; - var output = replaceKeysInObj(input, 'e', 'f'); - - expect(output.e).to.equal(undefined); - expect(output.f.x).to.equal('y'); - expect(output.t.r.e).to.equal(undefined); - expect(output.t.r.f).to.equal('r'); - expect(output.t.p.y).to.equal('r'); - expect(output.y).to.equal('e'); - - expect(output.hasOwnProperty('e')).to.equal(false); - expect(output.hasOwnProperty('f')).to.equal(true); - expect(output.hasOwnProperty('t')).to.equal(true); - expect(output.hasOwnProperty('y')).to.equal(true); - - expect(output.t.hasOwnProperty('r')).to.equal(true); - expect(output.t.hasOwnProperty('p')).to.equal(true); - - expect(output.t.r.hasOwnProperty('e')).to.equal(false); - expect(output.t.r.hasOwnProperty('f')).to.equal(true); - expect(output.t.p.hasOwnProperty('y')).to.equal(true); - }); - - it('should return object with same number of keys', function () { - var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}}, 'y':'e'}; - var output1 = replaceKeysInObj(input, 'e', 'f'); - var output2 = replaceKeysInObj(output1, 'e', 'f'); - expect(tallyKeys(input)).to.equal(8); - expect(tallyKeys(output1)).to.equal(8); - expect(tallyKeys(output2)).to.equal(8); - }); - - it('should use recursion by calling self', function () { - var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; - replaceKeysInObj.proxyCallCount = 0; - replaceKeysInObj(input, 'r', 'a'); - expect(replaceKeysInObj.proxyCallCount).to.be.above(1); - }); - - }); - - - xdescribe('24. First n Fibonacci', function() { - - it('should return an array', function() { - expect(Array.isArray(fibonacci(5))).to.equal(true); - }); - - it('should return first n Fibonacci numbers where n starts at index 1', function() { - expect(fibonacci(1)).to.eql([0, 1]); - expect(fibonacci(2)).to.eql([0, 1, 1]); - expect(fibonacci(3)).to.eql([0, 1, 1, 2]); - expect(fibonacci(4)).to.eql([0, 1, 1, 2, 3]); - expect(fibonacci(5)).to.eql([0, 1, 1, 2, 3, 5]); - expect(fibonacci(12)).to.eql([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]); - }); - - it('should return null for zero and negative integers', function() { - expect(fibonacci(0)).to.equal(null); - expect(fibonacci(-7)).to.equal(null); - }); - - it('should use recursion by calling self', function () { - fibonacci.proxyCallCount = 0; - fibonacci(5); - expect(fibonacci.proxyCallCount).to.be.above(1); - }); - - }); - - - describe('25. Return nth Fibonacci', function() { it('should return a number', function() { @@ -939,8 +602,6 @@ }); - - describe('26. Capitalize words in array', function() { it('should return an array', function() { @@ -960,8 +621,6 @@ }); - - describe('27. Capitalize first letter of words in array', function() { it('should return an array', function() { @@ -981,58 +640,6 @@ }); - - - xdescribe('28. Sum even numbers in nested objects', function() { - var obj = { - a: 2, - b: {b: 2, bb: {b: 3, bb: {b: 2}}}, - c: {c: {c: 2}, cc: 'ball', ccc: 5}, - d: 1, - e: {e: {e: 2}, ee: 'car'} - }; - - it('should return a number', function() { - expect(typeof(nestedEvenSum(obj))).to.equal('number'); - }); - - it('should sum even numbers', function() { - expect(nestedEvenSum(obj)).to.eql(10); - }); - - it('should use recursion by calling self', function () { - nestedEvenSum.proxyCallCount = 0; - nestedEvenSum(obj); - expect(nestedEvenSum.proxyCallCount).to.be.above(1); - }); - - }); - - - - xdescribe('29. Flatten nested arrays', function() { - - it('should return an array', function() { - expect(Array.isArray(flatten([1,[2],[3,[[4]]],5]))).to.equal(true); - }); - - it('should return flattened array', function() { - expect(flatten([[1],[2,3],[[4]],5,6])).to.eql([1,2,3,4,5,6]); - expect(flatten([[12,[[34],[56]],78]])).to.eql([12,34,56,78]); - expect(flatten([3,[0,[34,[7,[18]]]]])).to.eql([3,0,34,7,18]); - expect(flatten([[1],[2,[],3],[],[[4]],5,6])).to.eql([1,2,3,4,5,6]); - }); - - it('should use recursion by calling self', function () { - flatten.proxyCallCount = 0; - flatten([3,[0,[34,[7,[18]]]]]); - expect(flatten.proxyCallCount).to.be.above(1); - }); - - }); - - - describe('30. Tally letters in string', function() { it('should return an object', function() { @@ -1062,8 +669,6 @@ }); - - describe('31. Eliminate consecutive duplicates', function() { var input1 = [1,2,2,3,4,4,5,5,5]; var input2 = [1,2,2,3,4,4,2,5,5,5,4,4]; @@ -1085,30 +690,6 @@ }); - - - xdescribe('32. Augment each element in nested arrays', function() { - - it('should return an array', function() { - expect(Array.isArray(augmentElements([[],[3],[7]], 5))).to.equal(true); - }); - - it('should augment each element with given value', function() { - expect(augmentElements([[],[3],[7]], 5)).to.eql([[5],[3,5],[7,5]]); - expect(augmentElements([[],[3],[7]], null)).to.eql([[null],[3,null],[7,null]]); - expect(augmentElements([[],[3],[7]], '')).to.eql([[''],[3,''],[7,'']]); - }); - - it('should use recursion by calling self', function () { - augmentElements.proxyCallCount = 0; - augmentElements([[],[3],[7]], 5); - expect(augmentElements.proxyCallCount).to.be.above(1); - }); - - }); - - - describe('33. Minimize zeroes', function() { var input1 = [2,0,0,0,1,4]; var input2 = [2,0,0,0,1,0,0,4]; @@ -1130,8 +711,6 @@ }); - - describe('34. Alternate sign', function() { var input1 = [2,7,8,3,1,4]; var input2 = [-2,-7,8,3,-1,4]; @@ -1152,28 +731,6 @@ }); }); - - - - xdescribe('35. Convert numbers to text', function() { - - it('should return a string', function() { - expect(typeof(numToText("I have 5 dogs and 6 ponies"))).to.equal('string'); - }); - - it('should convert single digits to their word equivalent', function() { - expect(numToText("I have 5 dogs and 6 ponies")).to.eql("I have five dogs and six ponies"); - expect(numToText("It takes 3 men to screw in 1 light bulb")).to.eql("It takes three men to screw in one light bulb"); - }); - - it('should use recursion by calling self', function () { - numToText.proxyCallCount = 0; - numToText("I have 5 dogs and 6 ponies"); - expect(numToText.proxyCallCount).to.be.above(1); - }); - - }); - }); function checkForNativeMethods(runFunction) { @@ -1183,5 +740,4 @@ expect(Array.prototype.map.called).to.equal(false); }); } - }()); From 2d5eb31a9544d9f206656a0e48734c5d15dd1c07 Mon Sep 17 00:00:00 2001 From: Cain Date: Wed, 28 Nov 2018 17:15:11 -0600 Subject: [PATCH 17/36] Add where students work in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dce05f6b1..7cfbf0521 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Recursion Prompts -- This is a repository of prompts to be solved using recursion +- This is a repository of prompts to be solved using recursion inside of `src/recursion.js` - Please refrain from sharing solutions - Try to solve prompts first using pseudocode - This repo requires that the overall function itself is called recursively and pays no attention to subroutines called recursively. From 28b163c7b6ef33c320f3cf803e276288f4ce2fa1 Mon Sep 17 00:00:00 2001 From: Cain Watson Date: Mon, 10 Dec 2018 16:50:37 -0600 Subject: [PATCH 18/36] (chore) Remve old os tool setup --- package.json | 5 +---- test/mocha.opts | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) delete mode 100644 test/mocha.opts diff --git a/package.json b/package.json index 606f3b097..71b241ff8 100644 --- a/package.json +++ b/package.json @@ -8,10 +8,7 @@ "test": "test" }, "scripts": { - "pretest": "npm install", - "test": "mocha ./test || :", - "posttest": "rm -rf ./test ./node_modules", - "test:travis": "mocha ./test --reporter spec" + "test": "mocha ./test --reporter spec" }, "repository": { "type": "git", diff --git a/test/mocha.opts b/test/mocha.opts deleted file mode 100644 index 5639158f5..000000000 --- a/test/mocha.opts +++ /dev/null @@ -1 +0,0 @@ ---reporter json From 32fc0f93cb2b95ea9f37b9621db8eb6f9e3ab067 Mon Sep 17 00:00:00 2001 From: Cain Watson Date: Mon, 10 Dec 2018 16:58:26 -0600 Subject: [PATCH 19/36] (chore) Use yarn test in for travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index fc03e8ec5..fd2b7e557 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,6 @@ cache: install: - yarn script: - - yarn test:travis + - yarn test notifications: webhooks: https://greenlight.operationspark.org/api/v2/webhooks/travisci From 260265dac335f1f36101324f6777baa8f0eee8a4 Mon Sep 17 00:00:00 2001 From: Cain Watson Date: Sat, 26 Jan 2019 08:53:44 -0600 Subject: [PATCH 20/36] fix: Not destructuring for c9 node version --- test/part1.js | 82 +++++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/test/part1.js b/test/part1.js index d0b831093..b860bdf2e 100755 --- a/test/part1.js +++ b/test/part1.js @@ -2,47 +2,47 @@ 'use strict'; const sinon = require('sinon'); - const { expect } = require('chai'); - const { - factorial, - sum, - arraySum, - isEven, - sumBelow, - range, - exponent, - powerOfTwo, - reverse, - palindrome, - modulo, - multiply, - divide, - gcd, - compareStr, - createArray, - reverseArr, - buildList, - countOccurrence, - rMap, - countKeysInObj, - countValuesInObj, - replaceKeysInObj, - fibonacci, - nthFibo, - capitalizeWords, - capitalizeFirst, - nestedEvenSum, - flatten, - letterTally, - compress, - augmentElements, - minimizeZeroes, - alternateSign, - numToText, - tagCount, - binarySearch, - mergeSort, - } = require('../src/recursion'); + const expect = require('chai').expect; + const functions = require('../src/recursion'); + + const factorial = functions.factorial; + const sum = functions.sum; + const arraySum = functions.arraySum; + const isEven = functions.isEven; + const sumBelow = functions.sumBelow; + const range = functions.range; + const exponent = functions.exponent; + const powerOfTwo = functions.powerOfTwo; + const reverse = functions.reverse; + const palindrome = functions.palindrome; + const modulo = functions.modulo; + const multiply = functions.multiply; + const divide = functions.divide; + const gcd = functions.gcd; + const compareStr = functions.compareStr; + const createArray = functions.createArray; + const reverseArr = functions.reverseArr; + const buildList = functions.buildList; + const countOccurrence = functions.countOccurrence; + const rMap = functions.rMap; + const countKeysInObj = functions.countKeysInObj; + const countValuesInObj = functions.countValuesInObj; + const replaceKeysInObj = functions.replaceKeysInObj; + const fibonacci = functions.fibonacci; + const nthFibo = functions.nthFibo; + const capitalizeWords = functions.capitalizeWords; + const capitalizeFirst = functions.capitalizeFirst; + const nestedEvenSum = functions.nestedEvenSum; + const flatten = functions.flatten; + const letterTally = functions.letterTally; + const compress = functions.compress; + const augmentElements = functions.augmentElements; + const minimizeZeroes = functions.minimizeZeroes; + const alternateSign = functions.alternateSign; + const numToText = functions.numToText; + const tagCount = functions.tagCount; + const binarySearch = functions.binarySearch; + const mergeSort = functions.mergeSort; describe('Exercises in Recursion in Recursion in Recursion in...', function() { From 1e5805256ec741a0c364bef896a9c168f53859ad Mon Sep 17 00:00:00 2001 From: Andy Nguyen Date: Mon, 9 Sep 2019 13:21:51 -0500 Subject: [PATCH 21/36] Fix #35 to run test instead of showing as pending Fix #35 to run test instead of showing as pending --- spec/part1.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/part1.js b/spec/part1.js index f2ec9ba33..713e94a4e 100755 --- a/spec/part1.js +++ b/spec/part1.js @@ -1147,7 +1147,7 @@ - xdescribe('35. Convert numbers to text', function() { + describe('35. Convert numbers to text', function() { it('should return a string', function() { expect(typeof(numToText("I have 5 dogs and 6 ponies"))).to.equal('string'); From e0c4dc084d7b349f228b87027aecf7d0d89ff72a Mon Sep 17 00:00:00 2001 From: Andy Nguyen Date: Mon, 9 Sep 2019 13:24:58 -0500 Subject: [PATCH 22/36] update to run prompt 35 update to run prompt 35 as it says on the directions. --- test/part1.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/test/part1.js b/test/part1.js index b860bdf2e..f1c2d635e 100755 --- a/test/part1.js +++ b/test/part1.js @@ -43,6 +43,7 @@ const tagCount = functions.tagCount; const binarySearch = functions.binarySearch; const mergeSort = functions.mergeSort; + const numToText = functions.numToText; describe('Exercises in Recursion in Recursion in Recursion in...', function() { @@ -732,6 +733,29 @@ }); }); + + describe('35. Convert numbers to text', function() { + + it('should return a string', function() { + expect(typeof(numToText("I have 5 dogs and 6 ponies"))).to.equal('string'); + }); + + it('should convert single digits to their word equivalent', function() { + expect(numToText("I have 5 dogs and 6 ponies")).to.eql("I have five dogs and six ponies"); + expect(numToText("It takes 3 men to screw in 1 light bulb")).to.eql("It takes three men to screw in one light bulb"); + }); + + it('should use recursion by calling self', function () { + var originalNumToText = numToText; + numToText = sinon.spy(numToText); + numToText("I have 5 dogs and 6 ponies"); + expect(numToText.callCount).to.be.above(1); + numToText = originalNumToText; + }); + + }); + + }); function checkForNativeMethods(runFunction) { it('should not use the native version of map', function() { From ed13b1428510a2817c7640e26be87dbc551064a8 Mon Sep 17 00:00:00 2001 From: Andy Nguyen Date: Thu, 12 Sep 2019 14:50:38 -0500 Subject: [PATCH 23/36] remove extra declaration of `numToText` --- test/part1.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/part1.js b/test/part1.js index f1c2d635e..13ee80c3d 100755 --- a/test/part1.js +++ b/test/part1.js @@ -43,7 +43,6 @@ const tagCount = functions.tagCount; const binarySearch = functions.binarySearch; const mergeSort = functions.mergeSort; - const numToText = functions.numToText; describe('Exercises in Recursion in Recursion in Recursion in...', function() { From 73f66c2a1c3efe939b3d4c9924440450806682e9 Mon Sep 17 00:00:00 2001 From: andyn190 Date: Thu, 12 Sep 2019 14:53:22 -0500 Subject: [PATCH 24/36] fix test file --- test/part1.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/part1.js b/test/part1.js index 13ee80c3d..73c08e9c2 100755 --- a/test/part1.js +++ b/test/part1.js @@ -754,8 +754,6 @@ }); - }); - function checkForNativeMethods(runFunction) { it('should not use the native version of map', function() { // These spies are set up in testSupport.js From bda8877adf90ab29856a7a709a3ab87301e14901 Mon Sep 17 00:00:00 2001 From: andyn190 Date: Thu, 12 Sep 2019 14:55:43 -0500 Subject: [PATCH 25/36] fix const assignment for numToText --- test/part1.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/part1.js b/test/part1.js index 73c08e9c2..abbada5a2 100755 --- a/test/part1.js +++ b/test/part1.js @@ -39,10 +39,10 @@ const augmentElements = functions.augmentElements; const minimizeZeroes = functions.minimizeZeroes; const alternateSign = functions.alternateSign; - const numToText = functions.numToText; const tagCount = functions.tagCount; const binarySearch = functions.binarySearch; const mergeSort = functions.mergeSort; + let numToText = functions.numToText; describe('Exercises in Recursion in Recursion in Recursion in...', function() { From 628487e36e6a0a89980f7ed7c5f4b537773dc5f2 Mon Sep 17 00:00:00 2001 From: andyn190 Date: Thu, 12 Sep 2019 15:02:14 -0500 Subject: [PATCH 26/36] fix proxy for numToText --- test/part1.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/part1.js b/test/part1.js index abbada5a2..c53a7fc07 100755 --- a/test/part1.js +++ b/test/part1.js @@ -745,11 +745,9 @@ }); it('should use recursion by calling self', function () { - var originalNumToText = numToText; - numToText = sinon.spy(numToText); + numToText.proxyCallCount = 0 numToText("I have 5 dogs and 6 ponies"); - expect(numToText.callCount).to.be.above(1); - numToText = originalNumToText; + expect(numToText.proxyCallCount).to.be.above(1); }); }); From 7abc2e1c85d64c963f6697fcb5ccbc326d263f47 Mon Sep 17 00:00:00 2001 From: RyGuy-Coder <54914530+RyGuy-Coder@users.noreply.github.com> Date: Sun, 7 Feb 2021 10:08:12 -0600 Subject: [PATCH 27/36] Update recursion.js --- src/recursion.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/recursion.js b/src/recursion.js index 3b622b4af..691d0ac99 100644 --- a/src/recursion.js +++ b/src/recursion.js @@ -65,6 +65,7 @@ var modulo = function(x, y) { // 12. Write a function that multiplies two numbers without using the * operator or // JavaScript's Math object. +// ATTENTION DO NOT LEAVE COMMENTS IN THIS FUNCTION. The test is looking for any ('/'). var multiply = function(x, y) { }; From f6eed8af1e0cc7040a9661df6e6c245db1aee3c3 Mon Sep 17 00:00:00 2001 From: Gage Date: Thu, 12 Oct 2023 15:58:43 -0500 Subject: [PATCH 28/36] got 3 problems done --- src/recursion.js | 119 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 81 insertions(+), 38 deletions(-) diff --git a/src/recursion.js b/src/recursion.js index 691d0ac99..b51a46473 100644 --- a/src/recursion.js +++ b/src/recursion.js @@ -4,32 +4,75 @@ // denoted by n!, is the product of all positive integers less than or equal to n. // Example: 5! = 5 x 4 x 3 x 2 x 1 = 120 // factorial(5); // 120 -var factorial = function(n) { +var factorial = function (n, total = 1) { + //check if n is equal to 1 + if (n === 0) { + //return total + return total; + //check if n is less than 0 + } else if (n < 0) { + //return null + return null; + } + //set total to be equal to itself times n + total *= n; + //return the function with n equaling itself mines 1 and the current total + return factorial(n - 1, total); }; // 2. Compute the sum of an array of integers. // Example: sum([1, 2, 3, 4, 5, 6]); // 21 -var sum = function(array) { +var sum = function (array, add = 0, num = 0) { + //check if arr.length equal to num + if (array.length === num) { + //return sum + return add; + }; + //set add to equal itself plus the current value in array + add += array[num]; + //return the function with the same array, updated add, num plus one + return sum(array, add, num + 1); }; // 3. Sum all numbers in an array containing nested arrays. // Example: arraySum([1,[2,3],[[4]],5]); // 15 -var arraySum = function(array) { +var arraySum = function (array) { }; // 4. Check if a number is even. -var isEven = function(n) { -}; +var isEven = function (n) { + //check if n is equal to zero or one + if (n === 0) { + //return true + return true; + } else if (n === 1) { + //return false + return false; + } + + //check if n is a postive number + if (n < 0) { + //change n to be postive + n *= -1; + //return function with postive n + return isEven(n); + //run if n is postive + } else { + //return function with n mines 2 + return isEven(n - 2); + } +} + // 5. Sum all integers below a given integer. // sumBelow(10); // 45 // sumBelow(7); // 21 -var sumBelow = function(n) { +var sumBelow = function (n) { }; // 6. Get the integers in range (x, y). // Example: range(2, 9); // [3, 4, 5, 6, 7, 8] -var range = function(x, y) { +var range = function (x, y) { }; // 7. Compute the exponent of a number. @@ -37,22 +80,22 @@ var range = function(x, y) { // 8^2 = 8 x 8 = 64. Here, 8 is the base and 2 is the exponent. // Example: exponent(4,3); // 64 // https://www.khanacademy.org/computing/computer-science/algorithms/recursive-algorithms/a/computing-powers-of-a-number -var exponent = function(base, exp) { +var exponent = function (base, exp) { }; // 8. Determine if a number is a power of two. // powerOfTwo(1); // true // powerOfTwo(16); // true // powerOfTwo(10); // false -var powerOfTwo = function(n) { +var powerOfTwo = function (n) { }; // 9. Write a function that accepts a string a reverses it. -var reverse = function(string) { +var reverse = function (string) { }; // 10. Write a function that determines if a string is a palindrome. -var palindrome = function(string) { +var palindrome = function (string) { }; // 11. Write a function that returns the remainder of x divided by y without using the @@ -60,18 +103,18 @@ var palindrome = function(string) { // modulo(5,2) // 1 // modulo(17,5) // 2 // modulo(22,6) // 4 -var modulo = function(x, y) { +var modulo = function (x, y) { }; // 12. Write a function that multiplies two numbers without using the * operator or // JavaScript's Math object. // ATTENTION DO NOT LEAVE COMMENTS IN THIS FUNCTION. The test is looking for any ('/'). -var multiply = function(x, y) { +var multiply = function (x, y) { }; // 13. Write a function that divides two numbers without using the / operator or // JavaScript's Math object. -var divide = function(x, y) { +var divide = function (x, y) { }; // 14. Find the greatest common divisor (gcd) of two positive numbers. The GCD of two @@ -79,7 +122,7 @@ var divide = function(x, y) { // Example: gcd(4,36); // 4 // http://www.cse.wustl.edu/~kjg/cse131/Notes/Recursion/recursion.html // https://www.khanacademy.org/computing/computer-science/cryptography/modarithmetic/a/the-euclidean-algorithm -var gcd = function(x, y) { +var gcd = function (x, y) { }; // 15. Write a function that compares each character of two strings and returns true if @@ -87,12 +130,12 @@ var gcd = function(x, y) { // compareStr('house', 'houses') // false // compareStr('', '') // true // compareStr('tomato', 'tomato') // true -var compareStr = function(str1, str2) { +var compareStr = function (str1, str2) { }; // 16. Write a function that accepts a string and creates an array where each letter // occupies an index of the array. -var createArray = function(str){ +var createArray = function (str) { }; // 17. Reverse the order of an array @@ -102,37 +145,37 @@ var reverseArr = function (array) { // 18. Create a new array with a given value and length. // buildList(0,5) // [0,0,0,0,0] // buildList(7,3) // [7,7,7] -var buildList = function(value, length) { +var buildList = function (value, length) { }; // 19. Count the occurence of a value inside a list. // countOccurrence([2,7,4,4,1,4], 4) // 3 // countOccurrence([2,'banana',4,4,1,'banana'], 'banana') // 2 -var countOccurrence = function(array, value) { +var countOccurrence = function (array, value) { }; // 20. Write a recursive version of map. // rMap([1,2,3], timesTwo); // [2,4,6] -var rMap = function(array, callback) { +var rMap = function (array, callback) { }; // 21. Write a function that counts the number of times a key occurs in an object. // var testobj = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; // countKeysInObj(testobj, 'r') // 1 // countKeysInObj(testobj, 'e') // 2 -var countKeysInObj = function(obj, key) { +var countKeysInObj = function (obj, key) { }; // 22. Write a function that counts the number of times a value occurs in an object. // var testobj = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'}; // countValuesInObj(testobj, 'r') // 2 // countValuesInObj(testobj, 'e') // 1 -var countValuesInObj = function(obj, value) { +var countValuesInObj = function (obj, value) { }; // 23. Find all keys in an object (and nested objects) by a provided name and rename // them to a provided new name while preserving the value stored at that key. -var replaceKeysInObj = function(obj, key, newKey) { +var replaceKeysInObj = function (obj, key, newKey) { }; // 24. Get the first n Fibonacci numbers. In the Fibonacci Sequence, each subsequent @@ -140,7 +183,7 @@ var replaceKeysInObj = function(obj, key, newKey) { // Example: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34..... // fibonacci(5); // [0, 1, 1, 2, 3, 5] // Note: The 0 is not counted. -var fibonacci = function(n) { +var fibonacci = function (n) { }; // 25. Return the Fibonacci number located at index n of the Fibonacci sequence. @@ -148,18 +191,18 @@ var fibonacci = function(n) { // nthFibo(5); // 5 // nthFibo(7); // 13 // nthFibo(3); // 2 -var nthFibo = function(n) { +var nthFibo = function (n) { }; // 26. Given an array of words, return a new array containing each word capitalized. // var words = ['i', 'am', 'learning', 'recursion']; // capitalizedWords(words); // ['I', 'AM', 'LEARNING', 'RECURSION'] -var capitalizeWords = function(input) { +var capitalizeWords = function (input) { }; // 27. Given an array of strings, capitalize the first letter of each index. // capitalizeFirst(['car', 'poop', 'banana']); // ['Car', 'Poop', 'Banana'] -var capitalizeFirst = function(array) { +var capitalizeFirst = function (array) { }; // 28. Return the sum of all even numbers in an object containing nested objects. @@ -171,17 +214,17 @@ var capitalizeFirst = function(array) { // e: {e: {e: 2}, ee: 'car'} // }; // nestedEvenSum(obj1); // 10 -var nestedEvenSum = function(obj) { +var nestedEvenSum = function (obj) { }; // 29. Flatten an array containing nested arrays. // Example: flatten([1,[2],[3,[[4]]],5]); // [1,2,3,4,5] -var flatten = function(arrays) { +var flatten = function (arrays) { }; // 30. Given a string, return an object containing tallies of each letter. // letterTally('potato'); // {'p':1, 'o':2, 't':2, 'a':1} -var letterTally = function(str, obj) { +var letterTally = function (str, obj) { }; // 31. Eliminate consecutive duplicates in a list. If the list contains repeated @@ -189,51 +232,51 @@ var letterTally = function(str, obj) { // elements should not be changed. // Example: compress([1, 2, 2, 3, 4, 4, 5, 5, 5]) // [1, 2, 3, 4, 5] // Example: compress([1, 2, 2, 3, 4, 4, 2, 5, 5, 5, 4, 4]) // [1, 2, 3, 4, 2, 5, 4] -var compress = function(list) { +var compress = function (list) { }; // 32. Augment every element in a list with a new value where each element is an array // itself. // Example: augmentElements([[],[3],[7]], 5); // [[5],[3,5],[7,5]] -var augmentElements = function(array, aug) { +var augmentElements = function (array, aug) { }; // 33. Reduce a series of zeroes to a single 0. // minimizeZeroes([2,0,0,0,1,4]) // [2,0,1,4] // minimizeZeroes([2,0,0,0,1,0,0,4]) // [2,0,1,0,4] -var minimizeZeroes = function(array) { +var minimizeZeroes = function (array) { }; // 34. Alternate the numbers in an array between positive and negative regardless of // their original sign. The first number in the index always needs to be positive. // alternateSign([2,7,8,3,1,4]) // [2,-7,8,-3,1,-4] // alternateSign([-2,-7,8,3,-1,4]) // [2,-7,8,-3,1,-4] -var alternateSign = function(array) { +var alternateSign = function (array) { }; // 35. Given a string, return a string with digits converted to their word equivalent. // Assume all numbers are single digits (less than 10). // numToText("I have 5 dogs and 6 ponies"); // "I have five dogs and six ponies" -var numToText = function(str) { +var numToText = function (str) { }; // *** EXTRA CREDIT *** // 36. Return the number of times a tag occurs in the DOM. -var tagCount = function(tag, node) { +var tagCount = function (tag, node) { }; // 37. Write a function for binary search. // Sample array: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] // console.log(binarySearch(5)) will return '5' -var binarySearch = function(array, target, min, max) { +var binarySearch = function (array, target, min, max) { }; // 38. Write a merge sort function. // Sample array: [34,7,23,32,5,62] // Sample output: [5,7,23,32,34,62] -var mergeSort = function(array) { +var mergeSort = function (array) { }; From 02bcdbbfa3c7474561264dbcb6538d3c42dda4ff Mon Sep 17 00:00:00 2001 From: Omar Barakat Date: Thu, 12 Oct 2023 16:01:45 -0500 Subject: [PATCH 29/36] aaaa --- src/recursion.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/recursion.js b/src/recursion.js index 691d0ac99..200c8dcb4 100644 --- a/src/recursion.js +++ b/src/recursion.js @@ -1,5 +1,5 @@ // Solve all of the following prompts using recursion. - +//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA // 1. Calculate the factorial of a number. The factorial of a non-negative integer n, // denoted by n!, is the product of all positive integers less than or equal to n. // Example: 5! = 5 x 4 x 3 x 2 x 1 = 120 From 3cb8444f56182cdbc4c69031be1f867b1101b7a0 Mon Sep 17 00:00:00 2001 From: Omar Barakat Date: Thu, 12 Oct 2023 16:25:57 -0500 Subject: [PATCH 30/36] finished 5, working on 6 --- src/recursion.js | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/recursion.js b/src/recursion.js index 7b15879ed..956f1d58d 100644 --- a/src/recursion.js +++ b/src/recursion.js @@ -1,5 +1,4 @@ // Solve all of the following prompts using recursion. -//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA // 1. Calculate the factorial of a number. The factorial of a non-negative integer n, // denoted by n!, is the product of all positive integers less than or equal to n. // Example: 5! = 5 x 4 x 3 x 2 x 1 = 120 @@ -67,12 +66,46 @@ var isEven = function (n) { // 5. Sum all integers below a given integer. // sumBelow(10); // 45 // sumBelow(7); // 21 -var sumBelow = function (n) { +var sumBelow = function (n, sum = 0) { + + //add up all numbers below a given number, for example + // 10 = 9 + 8 + 7... + + //check if n = 0 + + if (n === 0) { + return sum + } + if (n < 0) { + + // if n is negative + n += 1 + sum += n + + return sumBelow(n, sum) + + } else { + //sets n to one number below it + n -= 1 + //adds n to the sum + sum += n + //does the same thing again until n = 0 + return sumBelow(n, sum) + } + }; // 6. Get the integers in range (x, y). // Example: range(2, 9); // [3, 4, 5, 6, 7, 8] -var range = function (x, y) { +var range = function (x, y, arr = []) { + +//check if the last value of arr is y-1 or y+1 +//check if x > y or if x < y +//check if x or y are positive +// check if x = y or if x and y are next to eachother + + + }; // 7. Compute the exponent of a number. From 6a3ef44a37c6a8b587a6d7d163e4ff85dc5056b8 Mon Sep 17 00:00:00 2001 From: Omar Barakat Date: Fri, 13 Oct 2023 16:28:23 -0500 Subject: [PATCH 31/36] worked on todo 7 --- src/recursion.js | 58 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/src/recursion.js b/src/recursion.js index 956f1d58d..3305d4952 100644 --- a/src/recursion.js +++ b/src/recursion.js @@ -98,13 +98,37 @@ var sumBelow = function (n, sum = 0) { // 6. Get the integers in range (x, y). // Example: range(2, 9); // [3, 4, 5, 6, 7, 8] var range = function (x, y, arr = []) { + //check if there are any integers between the numbers + if (x === y) { + return arr + } else if (x - 1 === y) { + return arr + } else if (x + 1 === y) { + return arr + } -//check if the last value of arr is y-1 or y+1 -//check if x > y or if x < y -//check if x or y are positive -// check if x = y or if x and y are next to eachother - - + //checks if x is negative + if (x < 0) { + //checks if the negative number goes to a positive number + if (x < y) { + arr.push(x + 1) + return range(x + 1, y, arr) + } else { + arr.push(x - 1) + return range(x - 1, y, arr) + } + } else { + //for when x is positive + if (x < y) { + arr.push(x + 1) + return range(x + 1, y, arr) + } + //checks if the nuber goes down from x + else { + arr.push(x - 1) + return range(x - 1, y, arr) + } + } }; @@ -113,7 +137,27 @@ var range = function (x, y, arr = []) { // 8^2 = 8 x 8 = 64. Here, 8 is the base and 2 is the exponent. // Example: exponent(4,3); // 64 // https://www.khanacademy.org/computing/computer-science/algorithms/recursive-algorithms/a/computing-powers-of-a-number -var exponent = function (base, exp) { +var exponent = function (base, exp, tot = 1, count = 0) { + + + if (exp === count) { + if (exp < 0) { + + base = 1 / tot + + return base + } else { + return tot + } + } + + tot *= base + + return exponent(base, exp, tot, count + 1) + + + + }; // 8. Determine if a number is a power of two. From 861a54997435ddef2aa56fccc2c03acd45dd32d4 Mon Sep 17 00:00:00 2001 From: Gage Date: Mon, 16 Oct 2023 13:59:27 -0500 Subject: [PATCH 32/36] update --- src/recursion.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/recursion.js b/src/recursion.js index b51a46473..e74990a36 100644 --- a/src/recursion.js +++ b/src/recursion.js @@ -1,5 +1,5 @@ // Solve all of the following prompts using recursion. - +// use git push origin master // 1. Calculate the factorial of a number. The factorial of a non-negative integer n, // denoted by n!, is the product of all positive integers less than or equal to n. // Example: 5! = 5 x 4 x 3 x 2 x 1 = 120 From 2a8d1b68103bcce46863dfebf90b7e9973e4276e Mon Sep 17 00:00:00 2001 From: Gage Date: Mon, 16 Oct 2023 16:15:47 -0500 Subject: [PATCH 33/36] got 3 problems done --- src/recursion.js | 86 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 70 insertions(+), 16 deletions(-) diff --git a/src/recursion.js b/src/recursion.js index 07a73742d..8138fb37a 100644 --- a/src/recursion.js +++ b/src/recursion.js @@ -139,41 +139,95 @@ var range = function (x, y, arr = []) { // Example: exponent(4,3); // 64 // https://www.khanacademy.org/computing/computer-science/algorithms/recursive-algorithms/a/computing-powers-of-a-number var exponent = function (base, exp, tot = 1, count = 0) { - - + //check if exp is equal to count if (exp === count) { + //check if exp is negative if (exp < 0) { - - base = 1 / tot - - return base + //return tot divided by one + return 1 / tot + //run if false } else { + //return tot return tot } } - + //set tot equal to itself times base tot *= base - - return exponent(base, exp, tot, count + 1) - - - - + //check if exp is negative + if (exp < 0) { + // return the function with base, exp, tot, and count mines one + return exponent(base, exp, tot, count - 1) + //run if false + } else { + // return the function with base, exp, tot, and count pulse one + return exponent(base, exp, tot, count + 1) + } }; // 8. Determine if a number is a power of two. // powerOfTwo(1); // true // powerOfTwo(16); // true // powerOfTwo(10); // false -var powerOfTwo = function (n) { +var powerOfTwo = function (n, check = 1) { + //check if n is equal to check + if (n === check) { + //return true + return true; + //check if check is greater than n + } else if (check > n) { + //return false + return false + } + //return the function with n and check times two + return powerOfTwo(n, check * 2); }; // 9. Write a function that accepts a string a reverses it. -var reverse = function (string) { +var reverse = function (string, arr = [], newString = '') { + //check if string length is the same as newString length + if (string.length === newString.length) { + //return new string + return newString; + } + //check if arr has any values + if (arr.length === 0) { + //put each chacter in the string into arr + arr = string.split(""); + } + //add the last chacter in newString and remove it from arr + newString += arr.pop(); + //return the function with string, arr, and newString + return reverse(string, arr, newString); }; // 10. Write a function that determines if a string is a palindrome. -var palindrome = function (string) { +var palindrome = function (string, noSpace = false) { + //ccheck if the length os zero or one + if (string.length === 0 || string.length === 1) { + //return true + return true; + } + //check if noSpace is false + if (noSpace === false) { + //set string to be a string with no spaces and captile chacter + string = string.replace(/ /g, '') + string = string.toLowerCase(); + //set noSpace to be true + noSpace = true; + } + //check if the first and last chacter are true + if (string[0] === string[string.length - 1]) { + //create a variable that equal to the string with the frist and last chacter remove + let str = string.slice(1); + str = str.slice(0, (str.length - 1)) + //return the string with the str and noSpace + return palindrome(str, noSpace); + //run if false + } else { + //return false + return false; + } + }; // 11. Write a function that returns the remainder of x divided by y without using the From 38b6564fd75c11259fa24d21b8a9aca9579f4d7b Mon Sep 17 00:00:00 2001 From: Gage Date: Tue, 17 Oct 2023 16:24:50 -0500 Subject: [PATCH 34/36] workd on two more problems --- src/recursion.js | 52 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/src/recursion.js b/src/recursion.js index 8138fb37a..8e1573875 100644 --- a/src/recursion.js +++ b/src/recursion.js @@ -202,7 +202,7 @@ var reverse = function (string, arr = [], newString = '') { // 10. Write a function that determines if a string is a palindrome. var palindrome = function (string, noSpace = false) { - //ccheck if the length os zero or one + //check if the length os zero or one if (string.length === 0 || string.length === 1) { //return true return true; @@ -241,7 +241,29 @@ var modulo = function (x, y) { // 12. Write a function that multiplies two numbers without using the * operator or // JavaScript's Math object. // ATTENTION DO NOT LEAVE COMMENTS IN THIS FUNCTION. The test is looking for any ('/'). -var multiply = function (x, y) { +var multiply = function (x, y, value = 0, count = 0) { + if (count === y) { + return value; + } else if (x === 0 || y === 0) { + return 0 + } else if (y === 1) { + return x; + } + + + if (x > 0 && y > 0) { + value = value + x; + count = count + 1; + } else if (x < 0 && y > 0) { + value = value + x; + count = count + 1; + } else if (x < 0 && y < 0) { + value = value + (x - x - x); + count = count - 1; + } + + + return multiply(x, y, value, count) }; // 13. Write a function that divides two numbers without using the / operator or @@ -262,7 +284,31 @@ var gcd = function (x, y) { // compareStr('house', 'houses') // false // compareStr('', '') // true // compareStr('tomato', 'tomato') // true -var compareStr = function (str1, str2) { +var compareStr = function (str1, str2, arr1 = 'none', arr2 = 'none') { + //check if arr1 and arr2 length are both zero + if (arr1.length === 0 && arr2.length === 0) { + //return zero + return true; + } + //check if arr1 is equal to a string of 'none' + if (arr1 === 'none') { + //set arr1 to be an array of chacters from str1 + arr1 = str1.split(""); + //set arr2 to be an array of chacters from str2 + arr2 = str2.split(""); + } + //check if the first value from arr1 and arr2 ar the same + if (arr1[0] === arr2[0]) { + //remove the first value from arr1 and arr2 + arr1.shift(); + arr2.shift(); + //return the function with str1, str2 arr1, and arr2 + return compareStr(str1, str2, arr1, arr2); + //run if false + } else { + //return false + return false; + } }; // 16. Write a function that accepts a string and creates an array where each letter From 2c034700f13c08e6571a29551383629e7b3b982f Mon Sep 17 00:00:00 2001 From: Gage Date: Wed, 18 Oct 2023 14:42:01 -0500 Subject: [PATCH 35/36] completed 3 more problems --- src/recursion.js | 72 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 9 deletions(-) diff --git a/src/recursion.js b/src/recursion.js index 8e1573875..d20a25b9e 100644 --- a/src/recursion.js +++ b/src/recursion.js @@ -313,28 +313,82 @@ var compareStr = function (str1, str2, arr1 = 'none', arr2 = 'none') { // 16. Write a function that accepts a string and creates an array where each letter // occupies an index of the array. -var createArray = function (str) { +var createArray = function (str, arr = []) { + //check if string length is zero + if (str.length === 0) { + //return arr + return arr + } + //push the first chacter in the str into arr + arr.push(str[0]); + //remove the first chacter + let newStr = str.slice(1) + console.log(newStr) + //return function with newStr and arr + return createArray(newStr, arr); }; // 17. Reverse the order of an array -var reverseArr = function (array) { +var reverseArr = function (array, arr = []) { + //check if array length is equal to zero + if (array.length === 0) { + //return arr + return arr; + } + //push the first value of array into arr + arr.unshift(array[0]); + //remove the first value of array + array.shift(); + //return function with array and arr + return reverseArr(array, arr); }; // 18. Create a new array with a given value and length. // buildList(0,5) // [0,0,0,0,0] // buildList(7,3) // [7,7,7] -var buildList = function (value, length) { +var buildList = function (value, length, array = []) { + //check if length is equal to array length + if (length === array.length) { + //return array + return array; + } + //push the value into array + array.push(value); + //return the function with value, length, and array + return buildList(value, length, array) }; -// 19. Count the occurence of a value inside a list. -// countOccurrence([2,7,4,4,1,4], 4) // 3 -// countOccurrence([2,'banana',4,4,1,'banana'], 'banana') // 2 -var countOccurrence = function (array, value) { -}; +//19.count the occurrence of a value inside a list +//countOccurrence([2,7,4,4,1,4], 4) return 3 +var countOccurrence = function (array, value, total = 0) { + //check if array length is zero + if (array.length === 0) { + //return total + return total + } + //check if first value in array is equal to the given value + if (value === array[0]) { + //increase total value + total++ + } + //remove the first value of array + array.shift(); + //return the function with array, value, total + return countOccurrence(array, value, total) +} // 20. Write a recursive version of map. // rMap([1,2,3], timesTwo); // [2,4,6] -var rMap = function (array, callback) { +var rMap = function (array, callback, arr = []) { + //check if array length is zero + if (array.length === arr.length) { + //return arr + return arr + } + //push the fist value in arr after runing it through the callback + arr.push(callback(array[arr.length])) + //return the function with array, callback, and arr + return rMap(array, callback, arr); }; // 21. Write a function that counts the number of times a key occurs in an object. From f8e93c6b9aa8d1feea8c49f40540d21128ae5c5d Mon Sep 17 00:00:00 2001 From: Omar Barakat Date: Wed, 18 Oct 2023 15:51:54 -0500 Subject: [PATCH 36/36] finished todo 30 --- src/recursion.js | 83 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 5 deletions(-) diff --git a/src/recursion.js b/src/recursion.js index d20a25b9e..00883cc93 100644 --- a/src/recursion.js +++ b/src/recursion.js @@ -415,7 +415,8 @@ var replaceKeysInObj = function (obj, key, newKey) { // Example: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34..... // fibonacci(5); // [0, 1, 1, 2, 3, 5] // Note: The 0 is not counted. -var fibonacci = function (n) { +var fibonacci = function (n, fib) { + }; // 25. Return the Fibonacci number located at index n of the Fibonacci sequence. @@ -423,18 +424,70 @@ var fibonacci = function (n) { // nthFibo(5); // 5 // nthFibo(7); // 13 // nthFibo(3); // 2 -var nthFibo = function (n) { +var nthFibo = function (n, index = 'none', fib = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144], count = 0) { + + //the default value for index + if (index !== 'none') { + return index + } else if (n < 0) { + return null + } //if the given value is a negative number, return null + + if (n === count) { + index = fib[0] + return index + } // if n is equal to the count, set the index to the first value of fib and return the index + + + + fib.shift() + //deletes the first index in fib + count++ + //increases count by 1 + + return nthFibo(n, index, fib, count) + //loops again }; // 26. Given an array of words, return a new array containing each word capitalized. // var words = ['i', 'am', 'learning', 'recursion']; // capitalizedWords(words); // ['I', 'AM', 'LEARNING', 'RECURSION'] -var capitalizeWords = function (input) { +var capitalizeWords = function (input, arr = [], count = 0) { + + //checks if the new array is equal to the original array, if it is, then return the new array + if (arr.length === input.length) { + return arr + } + + arr.push(input[count].toUpperCase()) + //pushes the current index to the new array in uppercase + + return capitalizeWords(input, arr, count + 1) + //loops again + }; // 27. Given an array of strings, capitalize the first letter of each index. // capitalizeFirst(['car', 'poop', 'banana']); // ['Car', 'Poop', 'Banana'] -var capitalizeFirst = function (array) { +var capitalizeFirst = function (array, arr = [], count = 0) { + + //checks if the new array is equal to the original array, if it is, then return the new array + if (arr.length === array.length) { + return arr + } + + var firstLetter = array[count][0].toUpperCase() + //takes the first letter of the current string + var firstString = array[count].slice(1) + //takes the rest of the words + + + arr.push(firstLetter + firstString) + //combines the now uppercase letter with the rest of the string and pushes to the new array + + return capitalizeFirst(array, arr, count + 1) + //loops again + }; // 28. Return the sum of all even numbers in an object containing nested objects. @@ -456,7 +509,27 @@ var flatten = function (arrays) { // 30. Given a string, return an object containing tallies of each letter. // letterTally('potato'); // {'p':1, 'o':2, 't':2, 'a':1} -var letterTally = function (str, obj) { +var letterTally = function (str, obj = {}) { + + if (str.length === 0) { + return obj + } + //if the string is empty, returns the object + + + if (obj[str[0]]) { + obj[str[0]] += 1 + } else { + obj[str[0]] = 1 + } + //if there is already a key with that letter, it will add onto it, if not, it makes a new key with the number 1 + + var newStr = str.slice(1) + //removes the first letter + + return letterTally(newStr, obj) + //loops again + }; // 31. Eliminate consecutive duplicates in a list. If the list contains repeated