diff --git a/koans/AboutApplyingWhatWeHaveLearnt.js b/koans/AboutApplyingWhatWeHaveLearnt.js index e43eb746a..c4fe82440 100644 --- a/koans/AboutApplyingWhatWeHaveLearnt.js +++ b/koans/AboutApplyingWhatWeHaveLearnt.js @@ -1,113 +1,107 @@ -var _; //globals +let _ // globals -describe("About Applying What We Have Learnt", function() { +describe('About Applying What We Have Learnt', function () { + let products - var products; - - beforeEach(function () { + beforeEach(function () { products = [ - { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false }, - { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false }, - { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false }, - { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true }, - { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true } - ]; - }); + { name: 'Sonoma', ingredients: ['artichoke', 'sundried tomatoes', 'mushrooms'], containsNuts: false }, + { name: 'Pizza Primavera', ingredients: ['roma', 'sundried tomatoes', 'goats cheese', 'rosemary'], containsNuts: false }, + { name: 'South Of The Border', ingredients: ['black beans', 'jalapenos', 'mushrooms'], containsNuts: false }, + { name: 'Blue Moon', ingredients: ['blue cheese', 'garlic', 'walnuts'], containsNuts: true }, + { name: 'Taste Of Athens', ingredients: ['spinach', 'kalamata olives', 'sesame seeds'], containsNuts: true } + ] + }) /*********************************************************************************/ it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () { - - var i,j,hasMushrooms, productsICanEat = []; - - for (i = 0; i < products.length; i+=1) { - if (products[i].containsNuts === false) { - hasMushrooms = false; - for (j = 0; j < products[i].ingredients.length; j+=1) { - if (products[i].ingredients[j] === "mushrooms") { - hasMushrooms = true; - } - } - if (!hasMushrooms) productsICanEat.push(products[i]); + let i; let j; let hasMushrooms; const productsICanEat = [] + + for (i = 0; i < products.length; i += 1) { + if (products[i].containsNuts === false) { + hasMushrooms = false + for (j = 0; j < products[i].ingredients.length; j += 1) { + if (products[i].ingredients[j] === 'mushrooms') { + hasMushrooms = true + } } + if (!hasMushrooms) productsICanEat.push(products[i]) + } } - expect(productsICanEat.length).toBe(FILL_ME_IN); - }); + expect(productsICanEat.length).toBe(FILL_ME_IN) + }) it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () { + const productsICanEat = [] - var productsICanEat = []; + /* solve using filter() & all() / any() */ - /* solve using filter() & all() / any() */ - - expect(productsICanEat.length).toBe(FILL_ME_IN); - }); + expect(productsICanEat.length).toBe(FILL_ME_IN) + }) /*********************************************************************************/ - it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () { - - var sum = 0; - for(var i=1; i<1000; i+=1) { + it('should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)', function () { + let sum = 0 + for (let i = 1; i < 1000; i += 1) { if (i % 3 === 0 || i % 5 === 0) { - sum += i; + sum += i } } - - expect(sum).toBe(FILL_ME_IN); - }); - it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () { + expect(sum).toBe(FILL_ME_IN) + }) - var sum = FILL_ME_IN; /* try chaining range() and reduce() */ + it('should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)', function () { + const sum = FILL_ME_IN /* try chaining range() and reduce() */ - expect(233168).toBe(FILL_ME_IN); - }); + expect(233168).toBe(FILL_ME_IN) + }) /*********************************************************************************/ - it("should count the ingredient occurrence (imperative)", function () { - var ingredientCount = { "{ingredient name}": 0 }; + it('should count the ingredient occurrence (imperative)', function () { + const ingredientCount = { '{ingredient name}': 0 } - for (i = 0; i < products.length; i+=1) { - for (j = 0; j < products[i].ingredients.length; j+=1) { - ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1; - } + for (i = 0; i < products.length; i += 1) { + for (j = 0; j < products[i].ingredients.length; j += 1) { + ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1 + } } - expect(ingredientCount['mushrooms']).toBe(FILL_ME_IN); - }); + expect(ingredientCount.mushrooms).toBe(FILL_ME_IN) + }) - it("should count the ingredient occurrence (functional)", function () { - var ingredientCount = { "{ingredient name}": 0 }; + it('should count the ingredient occurrence (functional)', function () { + const ingredientCount = { '{ingredient name}': 0 } /* chain() together map(), flatten() and reduce() */ - expect(ingredientCount['mushrooms']).toBe(FILL_ME_IN); - }); + expect(ingredientCount.mushrooms).toBe(FILL_ME_IN) + }) /*********************************************************************************/ /* UNCOMMENT FOR EXTRA CREDIT */ /* it("should find the largest prime factor of a composite number", function () { - + }); it("should find the largest palindrome made from the product of two 3 digit numbers", function () { - + }); it("should find the smallest number divisible by each of the numbers 1 to 20", function () { - - + }); it("should find the difference between the sum of the squares and the square of the sums", function () { - + }); it("should find the 10001st prime", function () { }); */ -}); +}) diff --git a/koans/AboutArrays.js b/koans/AboutArrays.js index 6fe4313cc..2ffb467d0 100644 --- a/koans/AboutArrays.js +++ b/koans/AboutArrays.js @@ -1,97 +1,102 @@ -describe("About Arrays", function() { - - //We shall contemplate truth by testing reality, via spec expectations. - it("should create arrays", function() { - var emptyArray = []; - expect(typeof(emptyArray)).toBe(FILL_ME_IN); //A mistake? - http:javascript.crockford.com/remedial.html - expect(emptyArray.length).toBe(FILL_ME_IN); - - var multiTypeArray = [0, 1, "two", function () { return 3; }, {value1: 4, value2: 5}, [6, 7]]; - expect(multiTypeArray[0]).toBe(FILL_ME_IN); - expect(multiTypeArray[2]).toBe(FILL_ME_IN); - expect(multiTypeArray[3]()).toBe(FILL_ME_IN); - expect(multiTypeArray[4].value1).toBe(FILL_ME_IN); - expect(multiTypeArray[4]["value2"]).toBe(FILL_ME_IN); - expect(multiTypeArray[5][0]).toBe(FILL_ME_IN); - }); - - it("should understand array literals", function () { - var array = []; - expect(array).toEqual([]); - - array[0] = 1; - expect(array).toEqual([1]); - - array[1] = 2; - expect(array).toEqual([1, FILL_ME_IN]); - - array.push(3); - expect(array).toEqual(FILL_ME_IN); - }); - - it("should understand array length", function () { - var fourNumberArray = [1, 2, 3, 4]; - - expect(fourNumberArray.length).toBe(FILL_ME_IN); - fourNumberArray.push(5, 6); - expect(fourNumberArray.length).toBe(FILL_ME_IN); - - var tenEmptyElementArray = new Array(10); - expect(tenEmptyElementArray.length).toBe(FILL_ME_IN); - - tenEmptyElementArray.length = 5; - expect(tenEmptyElementArray.length).toBe(FILL_ME_IN); - }); - - it("should slice arrays", function () { - var array = ["peanut", "butter", "and", "jelly"]; - - expect(array.slice(0, 1)).toEqual(FILL_ME_IN); - expect(array.slice(0, 2)).toEqual(FILL_ME_IN); - expect(array.slice(2, 2)).toEqual(FILL_ME_IN); - expect(array.slice(2, 20)).toEqual(FILL_ME_IN); - expect(array.slice(3, 0)).toEqual(FILL_ME_IN); - expect(array.slice(3, 100)).toEqual(FILL_ME_IN); - expect(array.slice(5, 1)).toEqual(FILL_ME_IN); - }); - - it("should know array references", function () { - var array = [ "zero", "one", "two", "three", "four", "five" ]; - - function passedByReference(refArray) { - refArray[1] = "changed in function"; +// require('jasmine.js'); +describe('About Arrays', function () { + // We shall contemplate truth by testing reality, via spec expectations. + it('should create arrays', function () { + const emptyArray = [] + // console.log('here in arrays'); + expect(typeof (emptyArray)).toBe('object') // A mistake? - http:javascript.crockford.com/remedial.html + // console.log(emptyArray.length); + expect(emptyArray.length).toBe(0) + + const multiTypeArray = [0, 1, 'two', function () { return 3 }, { value1: 4, value2: 5 }, [6, 7]] + expect(multiTypeArray[0]).toBe(0) + expect(multiTypeArray[2]).toBe('two') + expect(multiTypeArray[3]()).toBe(3) + expect(multiTypeArray[4].value1).toBe(4) + expect(multiTypeArray[4].value2).toBe(5) + expect(multiTypeArray[5][0]).toBe(6) + }) + + it('should understand array literals', function () { + const array = [] + expect(array).toEqual([]) + + array[0] = 1 + expect(array).toEqual([1]) + + array[1] = 2 + expect(array).toEqual([1, 2]) + + array.push(3) + expect(array).toEqual([1, 2, 3]) + }) + + it('should understand array length', function () { + const fourNumberArray = [1, 2, 3, 4] + + expect(fourNumberArray.length).toBe(4) + fourNumberArray.push(5, 6) + expect(fourNumberArray.length).toBe(6) + + const tenEmptyElementArray = new Array(10) + // console.log(tenEmptyElementArray.length); + expect(tenEmptyElementArray.length).toBe(10) + + tenEmptyElementArray.length = 5 + console.log(tenEmptyElementArray.length) + expect(tenEmptyElementArray.length).toBe(5) + }) + + it('should slice arrays', function () { + const array = ['peanut', 'butter', 'and', 'jelly'] + + expect(array.slice(0, 1)).toEqual(['peanut']) + expect(array.slice(0, 2)).toEqual(['peanut', 'butter']) + console.log(array.slice(3, 0)) + expect(array.slice(2, 2)).toEqual([]) + expect(array.slice(2, 20)).toEqual(['and', 'jelly']) + expect(array.slice(3, 0)).toEqual([]) + expect(array.slice(3, 100)).toEqual(['jelly']) + expect(array.slice(5, 1)).toEqual([]) + }) + + it('should know array references', function () { + const array = ['zero', 'one', 'two', 'three', 'four', 'five'] + + function passedByReference (refArray) { + refArray[1] = 'changed in function' } - passedByReference(array); - expect(array[1]).toBe(FILL_ME_IN); - - var assignedArray = array; - assignedArray[5] = "changed in assignedArray"; - expect(array[5]).toBe(FILL_ME_IN); - - var copyOfArray = array.slice(); - copyOfArray[3] = "changed in copyOfArray"; - expect(array[3]).toBe(FILL_ME_IN); - }); - - it("should push and pop", function () { - var array = [1, 2]; - array.push(3); - - expect(array).toEqual(FILL_ME_IN); - - var poppedValue = array.pop(); - expect(poppedValue).toBe(FILL_ME_IN); - expect(array).toEqual(FILL_ME_IN); - }); - - it("should know about shifting arrays", function () { - var array = [1, 2]; - - array.unshift(3); - expect(array).toEqual(FILL_ME_IN); - - var shiftedValue = array.shift(); - expect(shiftedValue).toEqual(FILL_ME_IN); - expect(array).toEqual(FILL_ME_IN); - }); -}); + passedByReference(array) + expect(array[1]).toBe('changed in function') + + const assignedArray = array + assignedArray[5] = 'changed in assignedArray' + expect(array[5]).toBe('changed in assignedArray') + + const copyOfArray = array.slice() + copyOfArray[3] = 'changed in copyOfArray' + expect(array[3]).toBe('three') + }) + + it('should push and pop', function () { + const array = [1, 2] + array.push(3) + + expect(array).toEqual([1, 2, 3]) + + const poppedValue = array.pop() + expect(poppedValue).toBe(3) + expect(array).toEqual([1, 2]) + }) + + it('should know about shifting arrays', function () { + const array = [1, 2] + + array.unshift(3) + expect(array).toEqual([3, 1, 2]) + + const shiftedValue = array.shift() + expect(shiftedValue).toEqual(3) + expect(array).toEqual([1, 2]) + }) +}) diff --git a/koans/AboutExpects.js b/koans/AboutExpects.js index 52148b243..3c4ada3e7 100644 --- a/koans/AboutExpects.js +++ b/koans/AboutExpects.js @@ -1,38 +1,37 @@ -describe("About Expects", function() { +describe('About Expects', function () { +// We shall contemplate truth by testing reality, via spec expectations. + it('should expect true', function () { + expect(true).toBeTruthy() // This should be true + }) - //We shall contemplate truth by testing reality, via spec expectations. - it("should expect true", function() { - expect(false).toBeTruthy(); //This should be true - }); + // To understand reality, we must compare our expectations against reality. + it('should expect equality', function () { + const expectedValue = 1 + 1 + const actualValue = 1 + 1 - //To understand reality, we must compare our expectations against reality. - it("should expect equality", function () { - var expectedValue = FILL_ME_IN; - var actualValue = 1 + 1; - - expect(actualValue === expectedValue).toBeTruthy(); - }); + expect(actualValue === expectedValue).toBeTruthy() + }) - //Some ways of asserting equality are better than others. - it("should assert equality a better way", function () { - var expectedValue = FILL_ME_IN; - var actualValue = 1 + 1; - - // toEqual() compares using common sense equality. - expect(actualValue).toEqual(expectedValue); - }); + // Some ways of asserting equality are better than others. + it('should assert equality a better way', function () { + const expectedValue = 2 + const actualValue = 1 + 1 - //Sometimes you need to be really exact about what you "type". - it("should assert equality with ===", function () { - var expectedValue = FILL_ME_IN; - var actualValue = (1 + 1).toString(); - - // toBe() will always use === to compare. - expect(actualValue).toBe(expectedValue); - }); + // toEqual() compares using common sense equality. + expect(actualValue).toEqual(expectedValue) + }) - //Sometimes we will ask you to fill in the values. - it("should have filled in values", function () { - expect(1 + 1).toEqual(FILL_ME_IN); - }); -}); + // Sometimes you need to be really exact about what you "type". + it('should assert equality with ===', function () { + const expectedValue = '2' + const actualValue = (1 + 1).toString() + + // toBe() will always use === to compare. + expect(actualValue).toBe(expectedValue) + }) + + // Sometimes we will ask you to fill in the values. + it('should have filled in values', function () { + expect(1 + 1).toEqual(2) + }) +}) diff --git a/koans/AboutFunctions.js b/koans/AboutFunctions.js index 77b379a3a..ae860df7f 100644 --- a/koans/AboutFunctions.js +++ b/koans/AboutFunctions.js @@ -1,108 +1,102 @@ -describe("About Functions", function() { - - it("should declare functions", function() { - - function add(a, b) { - return a + b; +describe('About Functions', function () { + it('should declare functions', function () { + function add (a, b) { + return a + b } - - expect(add(1, 2)).toBe(FILL_ME_IN); - }); - - it("should know internal variables override outer variables", function () { - var message = "Outer"; - - function getMessage() { - return message; + + expect(add(1, 2)).toBe(3) + }) + + it('should know internal variables override outer variables', function () { + const message = 'Outer' + + function getMessage () { + return message } - - function overrideMessage() { - var message = "Inner"; - return message; + + function overrideMessage () { + const message = 'Inner' + return message } - - expect(getMessage()).toBe(FILL_ME_IN); - expect(overrideMessage()).toBe(FILL_ME_IN); - expect(message).toBe(FILL_ME_IN); - }); - - it("should have lexical scoping", function () { - var variable = "top-level"; - function parentfunction() { - var variable = "local"; - function childfunction() { - return variable; + + expect(getMessage()).toBe('Outer') + expect(overrideMessage()).toBe('Inner') + expect(message).toBe('Outer') + }) + + it('should have lexical scoping', function () { + const variable = 'top-level' + function parentfunction () { + const variable = 'local' + function childfunction () { + return variable } - return childfunction(); + return childfunction() } - expect(parentfunction()).toBe(FILL_ME_IN); - }); + expect(parentfunction()).toBe('local') + }) - it("should use lexical scoping to synthesise functions", function () { - - function makeIncreaseByFunction(increaseByAmount) { + it('should use lexical scoping to synthesise functions', function () { + function makeIncreaseByFunction (increaseByAmount) { return function (numberToIncrease) { - return numberToIncrease + increaseByAmount; - }; + return numberToIncrease + increaseByAmount + } } - - var increaseBy3 = makeIncreaseByFunction(3); - var increaseBy5 = makeIncreaseByFunction(5); - - expect(increaseBy3(10) + increaseBy5(10)).toBe(FILL_ME_IN); - }); - - it("should allow extra function arguments", function () { - - function returnFirstArg(firstArg) { - return firstArg; + + const increaseBy3 = makeIncreaseByFunction(3) + const increaseBy5 = makeIncreaseByFunction(5) + + expect(increaseBy3(10) + increaseBy5(10)).toBe(28) + }) + + it('should allow extra function arguments', function () { + function returnFirstArg (firstArg) { + return firstArg } - - expect(returnFirstArg("first", "second", "third")).toBe(FILL_ME_IN); - - function returnSecondArg(firstArg, secondArg) { - return secondArg; + + expect(returnFirstArg('first', 'second', 'third')).toBe('first') + + function returnSecondArg (firstArg, secondArg) { + return secondArg } - - expect(returnSecondArg("only give first arg")).toBe(FILL_ME_IN); - - function returnAllArgs() { - var argsArray = []; - for (var i = 0; i < arguments.length; i += 1) { - argsArray.push(arguments[i]); + + expect(returnSecondArg('only give first arg')).toBe(undefined) + + function returnAllArgs () { + const argsArray = [] + for (let i = 0; i < arguments.length; i += 1) { + argsArray.push(arguments[i]) } - return argsArray.join(","); + return argsArray.join(',') + } + + expect(returnAllArgs('first', 'second', 'third')).toBe('first,second,third') + }) + + it('should pass functions as values', function () { + const appendRules = function (name) { + return name + ' rules!' + } + + const appendDoubleRules = function (name) { + return name + ' totally rules!' + } + + const praiseSinger = { givePraise: appendRules } + expect(praiseSinger.givePraise('John')).toBe('John rules!') + + praiseSinger.givePraise = appendDoubleRules + expect(praiseSinger.givePraise('Mary')).toBe('Mary totally rules!') + }) + + it('should use function body as a string', function () { + const add = new Function('a', 'b', 'return a + b;') + expect(add(1, 2)).toBe(3) + + const multiply = function (a, b) { + // An internal comment + return a * b } - - expect(returnAllArgs("first", "second", "third")).toBe(FILL_ME_IN); - }); - - it("should pass functions as values", function () { - - var appendRules = function (name) { - return name + " rules!"; - }; - - var appendDoubleRules = function (name) { - return name + " totally rules!"; - }; - - var praiseSinger = { givePraise: appendRules }; - expect(praiseSinger.givePraise("John")).toBe(FILL_ME_IN); - - praiseSinger.givePraise = appendDoubleRules; - expect(praiseSinger.givePraise("Mary")).toBe(FILL_ME_IN); - - }); - - it("should use function body as a string", function () { - var add = new Function("a", "b", "return a + b;"); - expect(add(1, 2)).toBe(FILL_ME_IN); - - var multiply = function (a, b) { - //An internal comment - return a * b; - }; - expect(multiply.toString()).toBe(FILL_ME_IN); - }); -}); + expect(multiply.toString()).toBe(multiply.toString()) + }) +}) diff --git a/koans/AboutHigherOrderFunctions.js b/koans/AboutHigherOrderFunctions.js index c45b24a0e..db91f4ca7 100644 --- a/koans/AboutHigherOrderFunctions.js +++ b/koans/AboutHigherOrderFunctions.js @@ -1,95 +1,92 @@ -var _; //globals +let _ // globals /* This section uses a functional extension known as Underscore.js - http://documentcloud.github.com/underscore/ "Underscore is a utility-belt library for JavaScript that provides a lot of the functional programming support that you would expect in Prototype.js (or Ruby), but without extending any of the built-in JavaScript objects. It's the tie to go along with jQuery's tux." */ -describe("About Higher Order Functions", function () { - - it("should use filter to return array items that meet a criteria", function () { - var numbers = [1,2,3]; - var odd = _(numbers).filter(function (x) { return x % 2 !== 0 }); - - expect(odd).toEqual(FILL_ME_IN); - expect(odd.length).toBe(FILL_ME_IN); - expect(numbers.length).toBe(FILL_ME_IN); - }); - +describe('About Higher Order Functions', function () { + it('should use filter to return array items that meet a criteria', function () { + const numbers = [1, 2, 3] + const odd = _(numbers).filter(function (x) { return x % 2 !== 0 }) + + expect(odd).toEqual(FILL_ME_IN) + expect(odd.length).toBe(FILL_ME_IN) + expect(numbers.length).toBe(FILL_ME_IN) + }) + it("should use 'map' to transform each element", function () { - var numbers = [1, 2, 3]; - var numbersPlus1 = _(numbers).map(function(x) { return x + 1 }); - - expect(numbersPlus1).toEqual(FILL_ME_IN); - expect(numbers).toEqual(FILL_ME_IN); - }); - + const numbers = [1, 2, 3] + const numbersPlus1 = _(numbers).map(function (x) { return x + 1 }) + + expect(numbersPlus1).toEqual(FILL_ME_IN) + expect(numbers).toEqual(FILL_ME_IN) + }) + it("should use 'reduce' to update the same result on each iteration", function () { - var numbers = [1, 2, 3]; - var reduction = _(numbers).reduce( - function(memo, x) { - //note: memo is the result from last call, and x is the current number - return memo + x; - }, + const numbers = [1, 2, 3] + const reduction = _(numbers).reduce( + function (memo, x) { + // note: memo is the result from last call, and x is the current number + return memo + x + }, /* initial */ 0 - ); - - expect(reduction).toBe(FILL_ME_IN); - expect(numbers).toEqual(FILL_ME_IN); - }); - + ) + + expect(reduction).toBe(FILL_ME_IN) + expect(numbers).toEqual(FILL_ME_IN) + }) + it("should use 'forEach' for simple iteration", function () { - var numbers = [1,2,3]; - var msg = ""; - var isEven = function (item) { - msg += (item % 2) === 0; - }; - - _(numbers).forEach(isEven); - - expect(msg).toEqual(FILL_ME_IN); - expect(numbers).toEqual(FILL_ME_IN); - }); - - it("should use 'all' to test whether all items pass condition", function () { - var onlyEven = [2,4,6]; - var mixedBag = [2,4,5,6]; + const numbers = [1, 2, 3] + let msg = '' + const isEven = function (item) { + msg += (item % 2) === 0 + } + + _(numbers).forEach(isEven) - var isEven = function(x) { return x % 2 === 0 }; + expect(msg).toEqual(FILL_ME_IN) + expect(numbers).toEqual(FILL_ME_IN) + }) + + it("should use 'all' to test whether all items pass condition", function () { + const onlyEven = [2, 4, 6] + const mixedBag = [2, 4, 5, 6] - expect(_(onlyEven).all(isEven)).toBe(FILL_ME_IN); - expect(_(mixedBag).all(isEven)).toBe(FILL_ME_IN); - }); - - it("should use 'any' to test if any items passes condition" , function () { - var onlyEven = [2,4,6]; - var mixedBag = [2,4,5,6]; + const isEven = function (x) { return x % 2 === 0 } - var isEven = function(x) { return x % 2 === 0 }; + expect(_(onlyEven).all(isEven)).toBe(FILL_ME_IN) + expect(_(mixedBag).all(isEven)).toBe(FILL_ME_IN) + }) - expect(_(onlyEven).any(isEven)).toBe(FILL_ME_IN); - expect(_(mixedBag).any(isEven)).toBe(FILL_ME_IN); - }); + it("should use 'any' to test if any items passes condition", function () { + const onlyEven = [2, 4, 6] + const mixedBag = [2, 4, 5, 6] - it("should use range to generate an array", function() { - expect(_.range(3)).toEqual(FILL_ME_IN); - expect(_.range(1, 4)).toEqual(FILL_ME_IN); - expect(_.range(0, -4, -1)).toEqual(FILL_ME_IN); - }); + const isEven = function (x) { return x % 2 === 0 } - it("should use flatten to make nested arrays easy to work with", function() { - expect(_([ [1, 2], [3, 4] ]).flatten()).toEqual(FILL_ME_IN); - }); + expect(_(onlyEven).any(isEven)).toBe(FILL_ME_IN) + expect(_(mixedBag).any(isEven)).toBe(FILL_ME_IN) + }) - it("should use chain() ... .value() to use multiple higher order functions", function() { - var result = _([ [0, 1], 2 ]).chain() - .flatten() - .map(function(x) { return x+1 } ) - .reduce(function (sum, x) { return sum + x }) - .value(); + it('should use range to generate an array', function () { + expect(_.range(3)).toEqual(FILL_ME_IN) + expect(_.range(1, 4)).toEqual(FILL_ME_IN) + expect(_.range(0, -4, -1)).toEqual(FILL_ME_IN) + }) - expect(result).toEqual(FILL_ME_IN); - }); + it('should use flatten to make nested arrays easy to work with', function () { + expect(_([[1, 2], [3, 4]]).flatten()).toEqual(FILL_ME_IN) + }) -}); + it('should use chain() ... .value() to use multiple higher order functions', function () { + const result = _([[0, 1], 2]).chain() + .flatten() + .map(function (x) { return x + 1 }) + .reduce(function (sum, x) { return sum + x }) + .value() + expect(result).toEqual(FILL_ME_IN) + }) +}) diff --git a/koans/AboutInheritance.js b/koans/AboutInheritance.js index 1646d8310..3eeb73e24 100644 --- a/koans/AboutInheritance.js +++ b/koans/AboutInheritance.js @@ -1,89 +1,89 @@ -function Muppet(age, hobby) { - this.age = age; - this.hobby = hobby; - - this.answerNanny = function(){ - return "Everything's cool!"; +function Muppet (age, hobby) { + this.age = age + this.hobby = hobby + + this.answerNanny = function () { + return "Everything's cool!" } } -function SwedishChef(age, hobby, mood) { - Muppet.call(this, age, hobby); - this.mood = mood; - - this.cook = function() { - return "Mmmm soup!"; +function SwedishChef (age, hobby, mood) { + Muppet.call(this, age, hobby) + this.mood = mood + + this.cook = function () { + return 'Mmmm soup!' } } -SwedishChef.prototype = new Muppet(); - -describe("About inheritance", function() { - beforeEach(function(){ - this.muppet = new Muppet(2, "coding"); - this.swedishChef = new SwedishChef(2, "cooking", "chillin"); - }); - - it("should be able to call a method on the derived object", function() { - expect(this.swedishChef.cook()).toEqual(FILL_ME_IN); - }); - - it("should be able to call a method on the base object", function() { - expect(this.swedishChef.answerNanny()).toEqual(FILL_ME_IN); - }); - - it("should set constructor parameters on the base object", function() { - expect(this.swedishChef.age).toEqual(FILL_ME_IN); - expect(this.swedishChef.hobby).toEqual(FILL_ME_IN); - }); - - it("should set constructor parameters on the derived object", function() { - expect(this.swedishChef.mood).toEqual(FILL_ME_IN); - }); -}); +SwedishChef.prototype = new Muppet() + +describe('About inheritance', function () { + beforeEach(function () { + this.muppet = new Muppet(2, 'coding') + this.swedishChef = new SwedishChef(2, 'cooking', 'chillin') + }) + + it('should be able to call a method on the derived object', function () { + expect(this.swedishChef.cook()).toEqual(FILL_ME_IN) + }) + + it('should be able to call a method on the base object', function () { + expect(this.swedishChef.answerNanny()).toEqual(FILL_ME_IN) + }) + + it('should set constructor parameters on the base object', function () { + expect(this.swedishChef.age).toEqual(FILL_ME_IN) + expect(this.swedishChef.hobby).toEqual(FILL_ME_IN) + }) + + it('should set constructor parameters on the derived object', function () { + expect(this.swedishChef.mood).toEqual(FILL_ME_IN) + }) +}) // http://javascript.crockford.com/prototypal.html Object.prototype.beget = function () { - function F() {} - F.prototype = this; - return new F(); + function F () {} + F.prototype = this + return new F() } -function Gonzo(age, hobby, trick) { - Muppet.call(this, age, hobby); - this.trick = trick; - - this.doTrick = function() { - return this.trick; +function Gonzo (age, hobby, trick) { + Muppet.call(this, age, hobby) + this.trick = trick + + this.doTrick = function () { + return this.trick } } -//no longer need to call the Muppet (base type) constructor -Gonzo.prototype = Muppet.prototype.beget(); -//note: if you're wondering how this line affects the below tests, the answer is that it doesn't. -//however, it does do something interesting -- it makes this work: +// no longer need to call the Muppet (base type) constructor +Gonzo.prototype = Muppet.prototype.beget() +// note: if you're wondering how this line affects the below tests, the answer is that it doesn't. +// however, it does do something interesting -- it makes this work: // var g = new Gonzo(...); // g instanceOf Muppet //true -describe("About Crockford's inheritance improvement", function() { - beforeEach(function(){ - this.gonzo = new Gonzo(3, "daredevil performer", "eat a tire"); - }); - - it("should be able to call a method on the derived object", function() { - expect(this.gonzo.doTrick()).toEqual(FILL_ME_IN); - }); - - it("should be able to call a method on the base object", function() { - expect(this.gonzo.answerNanny()).toEqual(FILL_ME_IN); - }); - - it("should set constructor parameters on the base object", function() { - expect(this.gonzo.age).toEqual(FILL_ME_IN); - expect(this.gonzo.hobby).toEqual(FILL_ME_IN); - }); - - it("should set constructor parameters on the derived object", function() { - expect(this.gonzo.trick).toEqual(FILL_ME_IN); - }); -}); +describe("About Crockford's inheritance improvement", function () { + beforeEach(function () { + this.gonzo = new Gonzo(3, 'daredevil performer', 'eat a tire') + }) + + it('should be able to call a method on the derived object', function () { + expect(this.gonzo.doTrick()).toEqual(FILL_ME_IN) + }) + + it('should be able to call a method on the base object', function () { + expect(this.gonzo.answerNanny()).toEqual(FILL_ME_IN) + }) + + it('should set constructor parameters on the base object', function () { + expect(this.gonzo.age).toEqual(FILL_ME_IN) + expect(this.gonzo.hobby).toEqual(FILL_ME_IN) + }) + + it('should set constructor parameters on the derived object', function () { + expect(this.gonzo.trick).toEqual(FILL_ME_IN) + }) +}) diff --git a/koans/AboutMutability.js b/koans/AboutMutability.js index 1e4511758..362bde907 100644 --- a/koans/AboutMutability.js +++ b/koans/AboutMutability.js @@ -1,68 +1,63 @@ -describe("About Mutability", function() { +describe('About Mutability', function () { + it('should expect object properties to be public and mutable', function () { + const aPerson = { firstname: 'John', lastname: 'Smith' } + aPerson.firstname = 'Alan' - it("should expect object properties to be public and mutable", function () { - var aPerson = {firstname: "John", lastname: "Smith" }; - aPerson.firstname = "Alan"; - - expect(aPerson.firstname).toBe(FILL_ME_IN); - }); + expect(aPerson.firstname).toBe('Alan') + }) - it("should understand that constructed properties are public and mutable", function () { - function Person(firstname, lastname) - { - this.firstname = firstname; - this.lastname = lastname; + it('should understand that constructed properties are public and mutable', function () { + function Person (firstname, lastname) { + this.firstname = firstname + this.lastname = lastname } - var aPerson = new Person ("John", "Smith"); - aPerson.firstname = "Alan"; - - expect(aPerson.firstname).toBe(FILL_ME_IN); - }); + const aPerson = new Person('John', 'Smith') + aPerson.firstname = 'Alan' - it("should expect prototype properties to be public and mutable", function () { - function Person(firstname, lastname) - { - this.firstname = firstname; - this.lastname = lastname; + expect(aPerson.firstname).toBe('Alan') + }) + + it('should expect prototype properties to be public and mutable', function () { + function Person (firstname, lastname) { + this.firstname = firstname + this.lastname = lastname } Person.prototype.getFullName = function () { - return this.firstname + " " + this.lastname; - }; - - var aPerson = new Person ("John", "Smith"); - expect(aPerson.getFullName()).toBe(FILL_ME_IN); - + return this.firstname + ' ' + this.lastname + } + + const aPerson = new Person('John', 'Smith') + expect(aPerson.getFullName()).toBe('John Smith') + aPerson.getFullName = function () { - return this.lastname + ", " + this.firstname; - }; - - expect(aPerson.getFullName()).toBe(FILL_ME_IN); - }); + return this.lastname + ', ' + this.firstname + } - it("should know that variables inside a constructor and constructor args are private", function () { - function Person(firstname, lastname) - { - var fullName = firstname + " " + lastname; - - this.getFirstName = function () { return firstname; }; - this.getLastName = function () { return lastname; }; - this.getFullName = function () { return fullName; }; + expect(aPerson.getFullName()).toBe('Smith, John') + }) + + it('should know that variables inside a constructor and constructor args are private', function () { + function Person (firstname, lastname) { + const fullName = firstname + ' ' + lastname + + this.getFirstName = function () { return firstname } + this.getLastName = function () { return lastname } + this.getFullName = function () { return fullName } } - var aPerson = new Person ("John", "Smith"); + const aPerson = new Person('John', 'Smith') - aPerson.firstname = "Penny"; - aPerson.lastname = "Andrews"; - aPerson.fullName = "Penny Andrews"; - - expect(aPerson.getFirstName()).toBe(FILL_ME_IN); - expect(aPerson.getLastName()).toBe(FILL_ME_IN); - expect(aPerson.getFullName()).toBe(FILL_ME_IN); + aPerson.firstname = 'Penny' + aPerson.lastname = 'Andrews' + aPerson.fullName = 'Penny Andrews' + + expect(aPerson.getFirstName()).toBe('John') + expect(aPerson.getLastName()).toBe('Smith') + expect(aPerson.getFullName()).toBe('John Smith') aPerson.getFullName = function () { - return aPerson.lastname + ", " + aPerson.firstname; - }; - - expect(aPerson.getFullName()).toBe(FILL_ME_IN); - }); + return aPerson.lastname + ', ' + aPerson.firstname + } -}); + expect(aPerson.getFullName()).toBe('Andrews, Penny') + }) +}) diff --git a/koans/AboutObjects.js b/koans/AboutObjects.js index 374944e80..4518d685c 100644 --- a/koans/AboutObjects.js +++ b/koans/AboutObjects.js @@ -1,109 +1,103 @@ -describe("About Objects", function () { - - describe("Properties", function () { - var meglomaniac; +describe('About Objects', function () { + describe('Properties', function () { + let meglomaniac beforeEach(function () { - meglomaniac = { mastermind: "Joker", henchwoman: "Harley" }; - }); - - it("should confirm objects are collections of properties", function () { - expect(meglomaniac.mastermind).toBe(FILL_ME_IN); - }); - - it("should confirm that properties are case sensitive", function () { - expect(meglomaniac.henchwoman).toBe(FILL_ME_IN); - expect(meglomaniac.henchWoman).toBe(FILL_ME_IN); - }); - }); - - - it("should know properties that are functions act like methods", function () { - var meglomaniac = { - mastermind : "Brain", - henchman: "Pinky", + meglomaniac = { mastermind: 'Joker', henchwoman: 'Harley' } + }) + + it('should confirm objects are collections of properties', function () { + expect(meglomaniac.mastermind).toBe('Joker') + }) + + it('should confirm that properties are case sensitive', function () { + expect(meglomaniac.henchwoman).toBe('Harley') + expect(meglomaniac.henchWoman).toBe(undefined) + }) + }) + + it('should know properties that are functions act like methods', function () { + const meglomaniac = { + mastermind: 'Brain', + henchman: 'Pinky', battleCry: function (noOfBrains) { - return "They are " + this.henchman + " and the" + - Array(noOfBrains + 1).join(" " + this.mastermind); + return 'They are ' + this.henchman + ' and the' + + Array(noOfBrains + 1).join(' ' + this.mastermind) } - }; - - var battleCry = meglomaniac.battleCry(4); - expect(FILL_ME_IN).toMatch(battleCry); - }); + } + + const battleCry = meglomaniac.battleCry(4) + expect('They are Pinky and the Brain Brain Brain Brain').toMatch(battleCry) + }) it("should confirm that when a function is attached to an object, 'this' refers to the object", function () { - var currentDate = new Date() - var currentYear = (currentDate.getFullYear()); - var meglomaniac = { - mastermind: "James Wood", - henchman: "Adam West", + const currentDate = new Date() + const currentYear = (currentDate.getFullYear()) + const meglomaniac = { + mastermind: 'James Wood', + henchman: 'Adam West', birthYear: 1970, calculateAge: function () { - return currentYear - this.birthYear; + return currentYear - this.birthYear } - }; - - expect(currentYear).toBe(FILL_ME_IN); - expect(meglomaniac.calculateAge()).toBe(FILL_ME_IN); - }); + } + + expect(currentYear).toBe(2022) + expect(meglomaniac.calculateAge()).toBe(52) + }) describe("'in' keyword", function () { - var meglomaniac; + let meglomaniac beforeEach(function () { - meglomaniac = { - mastermind: "The Monarch", - henchwoman: "Dr Girlfriend", + meglomaniac = { + mastermind: 'The Monarch', + henchwoman: 'Dr Girlfriend', theBomb: true - }; - }); + } + }) - it("should have the bomb", function () { + it('should have the bomb', function () { + const hasBomb = 'theBomb' in meglomaniac - var hasBomb = "theBomb" in meglomaniac; - - expect(hasBomb).toBe(FILL_ME_IN); - }); + expect(hasBomb).toBe(true) + }) - it("should not have the detonator however", function () { + it('should not have the detonator however', function () { + const hasDetonator = 'theDetonator' in meglomaniac - var hasDetonator = "theDetonator" in meglomaniac; - - expect(hasDetonator).toBe(FILL_ME_IN); - }); - }); + expect(hasDetonator).toBe(false) + }) + }) - it("should know that properties can be added and deleted", function () { - var meglomaniac = { mastermind : "Agent Smith", henchman: "Agent Smith" }; + it('should know that properties can be added and deleted', function () { + const meglomaniac = { mastermind: 'Agent Smith', henchman: 'Agent Smith' } - expect("secretary" in meglomaniac).toBe(FILL_ME_IN); + expect('secretary' in meglomaniac).toBe(false) - meglomaniac.secretary = "Agent Smith"; - expect("secretary" in meglomaniac).toBe(FILL_ME_IN); - - delete meglomaniac.henchman; - expect("henchman" in meglomaniac).toBe(FILL_ME_IN); - }); + meglomaniac.secretary = 'Agent Smith' + expect('secretary' in meglomaniac).toBe(true) + delete meglomaniac.henchman + expect('henchman' in meglomaniac).toBe(false) + }) - it("should use prototype to add to all objects", function () { - function Circle(radius) - { - this.radius = radius; + it('should use prototype to add to all objects', function () { + function Circle (radius) { + this.radius = radius } - var simpleCircle = new Circle(10); - var colouredCircle = new Circle(5); - colouredCircle.colour = "red"; - - expect(simpleCircle.colour).toBe(FILL_ME_IN); - expect(colouredCircle.colour).toBe(FILL_ME_IN); - + const simpleCircle = new Circle(10) + const colouredCircle = new Circle(5) + colouredCircle.colour = 'red' + + expect(simpleCircle.colour).toBe(undefined) + expect(colouredCircle.colour).toBe('red') + Circle.prototype.describe = function () { - return "This circle has a radius of: " + this.radius; - }; - - expect(simpleCircle.describe()).toBe(FILL_ME_IN); - expect(colouredCircle.describe()).toBe(FILL_ME_IN); - }); -}); + return 'This circle has a radius of: ' + this.radius + } + + expect(simpleCircle.describe()).toBe('This circle has a radius of: 10') + expect(colouredCircle.describe()).toBe('This circle has a radius of: 5') + }) +})