diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..a94a81aa --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "lab-es6-javascript-koans", + "lockfileVersion": 2, + "requires": true, + "packages": {} +} diff --git a/spec/koans.js b/spec/koans.js index 89beb153..d720331f 100644 --- a/spec/koans.js +++ b/spec/koans.js @@ -8,31 +8,37 @@ describe('`let` restricts the scope of the variable to the current block - ', () describe('`let` vs. `var`.', () => { it('`var` works as usual, it does not restricts scope', () => { if (true) { - /*You should add your code in here*/ + varX = true } - // expect(varX).toBe(true); + expect(varX).toBe(true); }); it('`let` restricts scope to inside the block', () => { - /*var or const? letX = false*/ + const letX = false + if (true) { - /*var or const? letX = true*/ + const letX = true + } - //expect(letX).toBe(false); + expect(letX).toBe(false); }); it('`var` does not restricts scope to inside the block in `for` loops', () => { - /*var or let? counter = 100*/ - /*for (var or let? counter = 1; counter < 50; counter++){}*/ + let counter = 100 + for (let counter = 1; counter < 50; counter++) { + return counter + } - //expect(counter).toBe(50); + expect(counter).toBe(50); }); it('`let` restricts scope to inside the block also in `for` loops', () => { - /*var or let? counter = 100*/ - /*for (var or let? counter = 1; counter < 50; counter++){}*/ + let counter = 100 + for (let counter = 1; counter < 50; counter++) { + return counter + } - //expect(counter).toBe(100); + expect(counter).toBe(100); }); }); @@ -42,39 +48,40 @@ describe('`const` is like `let` plus read-only. ', () => { describe('scalar values are read-only', () => { it('number are read-only', () => { - // const constNum = 0; + const constNum = 0; // constNum = 1; - //expect(constNum).toBe(0); + expect(constNum).toBe(0); }); it('string are read-only', () => { - // const constString = "I am a const"; - // constString = "Cant change you?"; + const constString = "I am a const"; + // constString = "Cant change you?"; - //expect(constString).toBe("I am a const"); + expect(constString).toBe("I am a const"); }); }); - /*var, let or const? notChangeable = 23;*/ + const notChangeable = 23; it('const scope leaks too', () => { - //expect(notChangeable).toBe(23); + expect(notChangeable).toBe(23); }); describe('complex types are NOT fully read-only', () => { it('arrays is not fully read-only', () => { const arr = [42, 23]; + arr.unshift(0) - //expect(arr[0]).toBe(0); + expect(arr[0]).toBe(0); }); it('objects are not fully read-only', () => { - const obj = {x: 1}; - - //expect(obj.x).toBe(2); + const obj = { x: 1 }; + obj.x = 2 + expect(obj.x).toBe(2); }); }); @@ -83,56 +90,56 @@ describe('`const` is like `let` plus read-only. ', () => { describe('`string.includes()` finds string within another string. ', () => { - describe('find a single character', function() { - it('in a three char string', function() { - /* const searchString = ???? */ - //expect('xyz'.includes(searchString)).toBe(true); + describe('find a single character', function () { + it('in a three char string', function () { + const searchString = 'xyz' + expect('xyz'.includes(searchString)).toBe(true); }); - it('reports false if character was not found', function() { - /* const expected = ????*/; - //expect('xyz'.includes('abc')).toBe(expected); + it('reports false if character was not found', function () { + const expected = false; + expect('xyz'.includes('abc')).toBe(expected); }); }); - describe('find a string', function() { - it('that matches exactly', function() { - /* const findSome = .... => 'xyz'.includes();*/ - //expect(findSome('xyz')).toBe(true); + describe('find a string', function () { + it('that matches exactly', function () { + const findSome = () => 'xyz'.includes('xyz'); + expect(findSome('xyz')).toBe(true); }); }); - describe('search for an empty string, is always true', function() { - it('in an empty string', function() { - /* .... */ - //expect(''.includes(x)).toBe(true); + describe('search for an empty string, is always true', function () { + it('in an empty string', function () { + const x = '' + expect(''.includes(x)).toBe(true); }); - it('in `abc`', function() { - /* .... */ - //expect('abc'.includes(x)).toBe(true); + it('in `abc`', function () { + const x = 'abc' + expect('abc'.includes(x)).toBe(true); }); }); - describe('takes a position from where to start searching', function() { - it('does not find `a` after position 1 in `abc`', function() { - /*....*/ - //expect('abc'.includes('a', position)).toBe(false); + describe('takes a position from where to start searching', function () { + it('does not find `a` after position 1 in `abc`', function () { + let position = 1 + expect('abc'.includes('a', position)).toBe(false); }); - it('even the position gets coerced', function() { - /*const findAtPosition = (pos) => 'xyz'.includes(?????);*/ - //expect(findAtPosition('2')).toBe(true); + it('even the position gets coerced', function () { + const findAtPosition = (pos) => 'xyz'.includes('z', pos); + expect(findAtPosition('2')).toBe(true); }); - describe('invalid positions get converted to 0', function() { - it('e.g. `undefined`', function() { - /*const findAtPosition = (pos) => 'xyz'.includes(?????); */ - //expect(findAtPosition(void 0)).toBe(true); + describe('invalid positions get converted to 0', function () { + it('e.g. `undefined`', function () { + const findAtPosition = (pos) => 'xyz'.includes('', pos); + expect(findAtPosition(void 0)).toBe(true); }); - it('negative numbers', function() { - /*const findAtPosition = (pos) => 'xyz'.includes(????); */ - //expect(findAtPosition(-2)).toBe(true); + it('negative numbers', function () { + const findAtPosition = (pos) => 'xyz'.includes('xyz', pos); + expect(findAtPosition(-2)).toBe(true); }); - it('NaN', function() { - /* const findAtPosition = (pos) => 'xyz'.includes(?????); */ - //expect(findAtPosition(NaN)).toBe(true); + it('NaN', function () { + const findAtPosition = (pos) => 'xyz'.includes('xyz', pos); + expect(findAtPosition(NaN)).toBe(true); }); }); }); @@ -141,10 +148,10 @@ describe('`string.includes()` finds string within another string. ', () => { describe('a template string, is wrapped in ` (backticks) instead of \' or ". ', () => { - describe('by default, behaves like a normal string', function() { - it('just surrounded by backticks', function() { - /*let str = ??????*/ - //expect(str).toEqual('like a string'); + describe('by default, behaves like a normal string', function () { + it('just surrounded by backticks', function () { + let str = 'like a string' + expect(str).toEqual('like a string'); }); }); @@ -152,33 +159,33 @@ describe('a template string, is wrapped in ` (backticks) instead of \' or ". ', let x = 42; let y = 23; - describe('can evaluate variables, which are wrapped in "${" and "}"', function() { + describe('can evaluate variables, which are wrapped in "${" and "}"', function () { - it('e.g. a simple variable "${x}" just gets evaluated', function() { - let evaluated = `x=x` - //expect(evaluated).toBe('x=' + x); + it('e.g. a simple variable "${x}" just gets evaluated', function () { + let evaluated = `x=` + x + expect(evaluated).toBe('x=' + x); }); - it('multiple variables get evaluated too', function() { - var evaluated = `x+y`; - //expect(evaluated).toBe(x + '+' + y); + it('multiple variables get evaluated too', function () { + var evaluated = x + `+` + y; + expect(evaluated).toBe(x + '+' + y); }); }); - describe('can evaluate any expression, wrapped inside "${...}"', function() { + describe('can evaluate any expression, wrapped inside "${...}"', function () { - it('all inside "${...}" gets evaluated', function() { - var evaluated = Number(`x+y`); - //expect(evaluated).toBe(x+y); + it('all inside "${...}" gets evaluated', function () { + var evaluated = Number(`${x + y}`); + expect(evaluated).toBe(x + y); }); - it('inside "${...}" can also be a function call', function() { - function getSchool(){ + it('inside "${...}" can also be a function call', function () { + function getSchool() { return 'Ironhack'; } - var evaluated = `getSchool()`; - //expect(evaluated).toBe('Ironhack'); + var evaluated = `${getSchool()}`; + expect(evaluated).toBe('Ironhack'); }); }); @@ -190,14 +197,15 @@ describe('The object literal allows for new shorthands. ', () => { const x = 1; const y = 2; + describe('with variables', () => { it('the short version for `{y: y}` is {y}', () => { - /*.....*/ - //expect(short).toEqual({y: y}); + let short = { y } + expect(short).toEqual({ y: y }); }); it('works with multiple variables too', () => { - /*.....*/ - //expect(short).toEqual({x: x, y: y}); + let short = { x, y } + expect(short).toEqual({ x: x, y: y }); }); }); @@ -206,13 +214,13 @@ describe('The object literal allows for new shorthands. ', () => { const func = () => func; it('using the name only uses it as key', () => { - /*.......*/ - //expect(short).toEqual({func: func}); + let short = { func } + expect(short).toEqual({ func: func }); }); it('a different key must be given explicitly, just like before ES6', () => { - /*.......*/ - //expect(short).toEqual({otherKey: func}); + let short = { otherKey: func } + expect(short).toEqual({ otherKey: func }); }); }); @@ -221,28 +229,28 @@ describe('The object literal allows for new shorthands. ', () => { describe('destructuring arrays makes shorter code. ', () => { it('extract value from array, e.g. extract 0 into x like so `let [x] = [0];`', () => { - let firstValue = [1]; - //expect(firstValue).toEqual(1); + let [firstValue] = [1]; + expect(firstValue).toEqual(1); }); it('swap two variables, in one operation', () => { let [x, y] = ['ax', 'why']; - [x, y] = [x, y]; - //expect([x, y]).toEqual(['why', 'ax']); + [x, y] = [y, x]; + expect([x, y]).toEqual(['why', 'ax']); }); it('leading commas', () => { const all = ['ax', 'why', 'zet']; - const [z] = all; - //expect(z).toEqual('zet'); + const [, , z] = all; + expect(z).toEqual('zet'); }); it('extract from nested arrays', () => { const user = [['Some', 'One'], 23]; - const [firstName, surname, age] = user; + const [[firstName, surname], age] = user; const expected = 'Some One = 23 years'; - //expect(`${firstName} ${surname} = ${age} years`).toEqual(expected); + expect(`${firstName} ${surname} = ${age} years`).toEqual(expected); }); it('chained assignments', () => { @@ -269,29 +277,29 @@ describe('destructuring also works on strings. ', () => { describe('destructuring objects. ', () => { it('is simple', () => { - const x = {x: 1}; + const x = { x: 1 }; //expect(x).toEqual(1); }); describe('nested', () => { it('multiple objects', () => { - const magic = {first: 23, second: 42}; + const magic = { first: 23, second: 42 }; /*const first, second = ??????*/ //expect(second).toEqual(42); }); it('object and array', () => { - const {z:x} = {z: [23, 42]}; + const { z: x } = { z: [23, 42] }; //expect(x).toEqual(42); }); it('array and object', () => { - const lang = [null, [{env: 'browser', lang: 'ES6'}]]; + const lang = [null, [{ env: 'browser', lang: 'ES6' }]]; //expect(lang).toEqual('ES6'); }); }); describe('interesting', () => { it('missing refs become undefined', () => { - const z = {x: 1, y: 2}; + const z = { x: 1, y: 2 }; //expect(z).toEqual(void 0); }); }); @@ -306,17 +314,17 @@ describe('destructuring can also have default values. ', () => { }); it('for a missing value', () => { - const [a,b,c] = [1,,3]; + const [a, b, c] = [1, , 3]; //expect(b).toEqual(2); }); it('in an object', () => { - const [a, b] = [{a: 1}]; + const [a, b] = [{ a: 1 }]; //expect(b).toEqual(2); }); it('if the value is undefined', () => { - const {a, b} = {a: 1, b: void 0}; + const { a, b } = { a: 1, b: void 0 }; //expect(b).toEqual(2); }); @@ -334,20 +342,20 @@ describe('destructuring can also have default values. ', () => { describe('arrow functions. ', () => { - it('are shorter to write', function() { + it('are shorter to write', function () { let func = () => { /*........*/ }; // expect(func()).toBe('I am func'); }); - it('a single expression, without curly braces returns too', function() { + it('a single expression, without curly braces returns too', function () { /*let func = () => .........;*/ //expect(func()).toBe('I return too'); }); it('one parameter can be written without parens', () => { - /* let func = ........;*/ + /* let func = ........;*/ //expect(func(25)).toEqual(24) }); @@ -357,7 +365,7 @@ describe('arrow functions. ', () => { }); it('body needs parens to return an object', () => { - let func = () => {iAm: 'an object'} + let func = () => { iAm: 'an object' } // expect(func()).toEqual({iAm: 'an object'}); }); @@ -370,20 +378,20 @@ describe('arrow functions. ', () => { } getArgumentsFunction() { - return function() { return arguments; }; /*or here*/ + return function () { return arguments; }; /*or here*/ } } describe('arrow functions have lexical `this`, no dynamic `this`', () => { - it('bound at definition time, use `=>` ', function() { + it('bound at definition time, use `=>` ', function () { let bound = new LexicallyBound(); let fn = bound.getFunction(); //expect(fn()).toBe(bound); }); - it('can NOT bind a different context', function() { + it('can NOT bind a different context', function () { let bound = new LexicallyBound(); let fn = bound.getFunction(); let anotherObj = {}; @@ -392,7 +400,7 @@ describe('arrow functions. ', () => { //expect(fn.call(anotherObj)).toBe(expected); }); - it('`arguments` doesnt work inside arrow functions', function() { + it('`arguments` doesnt work inside arrow functions', function () { let bound = new LexicallyBound(); let fn = bound.getArgumentsFunction(); @@ -411,7 +419,7 @@ describe('destructuring function parameters. ', () => { //expect(id).toEqual(42); //expect(name).toEqual('Wolfram'); }; - const user = {name: 'Wolfram', id: 42}; + const user = { name: 'Wolfram', id: 42 }; fn(user); }); @@ -419,7 +427,7 @@ describe('destructuring function parameters. ', () => { const fn = ([]) => { //expect(name).toEqual('Alice'); }; - const users = [{name: 'nobody'}, {name: 'Alice', id: 42}]; + const users = [{ name: 'nobody' }, { name: 'Alice', id: 42 }]; fn(users); }); }); @@ -434,7 +442,7 @@ describe('destructuring function parameters. ', () => { }); it('for a missing array value', () => { - const defaultUser = {id: 23, name: 'Joe'}; + const defaultUser = { id: 23, name: 'Joe' }; const fn = ([user]) => { //expect(user).toEqual(defaultUser); }; @@ -442,7 +450,7 @@ describe('destructuring function parameters. ', () => { }); it('mix of parameter types', () => { - const fn = (id, [arr], {obj}) => { + const fn = (id, [arr], { obj }) => { //expect(id).toEqual(1); //expect(arr).toEqual(2); //expect(obj).toEqual(3); @@ -455,28 +463,28 @@ describe('destructuring function parameters. ', () => { describe('assign object property values to new variables while destructuring. ', () => { - describe('for simple objects', function() { + describe('for simple objects', function () { it('use a colon after the property name, like so `propertyName: newName`', () => { - const {x} = {x: 1}; + const { x } = { x: 1 }; //expect(y).toEqual(1); }); it('assign a new name and give it a default value using `= `', () => { - const {x} = {y: 23}; + const { x } = { y: 23 }; //expect(y).toEqual(42); }); }); - describe('for function parameter names', function() { + describe('for function parameter names', function () { it('do it the same way, with a colon behind it', () => { - const fn = ({x}) => { - //expect(y).toEqual(1); + const fn = ({ x }) => { + //expect(y).toEqual(1); }; - fn({x: 1}); + fn({ x: 1 }); }); it('giving it a default value is possible too, like above', () => { - const fn = ({x}) => { + const fn = ({ x }) => { //expect(y).toEqual(3); }; fn({}); @@ -500,26 +508,26 @@ describe('rest with destructuring', () => { describe('spread with arrays. ', () => { - it('extracts each array item', function() { + it('extracts each array item', function () { const [] = [...[1, 2]]; //expect(a).toEqual(1); //expect(b).toEqual(2); }); - it('in combination with rest', function() { + it('in combination with rest', function () { const [a, b, ...rest] = [...[0, 1, 2, 3, 4, 5]]; //expect(a).toEqual(1); //expect(b).toEqual(2); //expect(rest).toEqual([3, 4, 5]); }); - it('spreading into the rest', function() { - const [...rest] = [...[,1, 2, 3, 4, 5]]; + it('spreading into the rest', function () { + const [...rest] = [...[, 1, 2, 3, 4, 5]]; //expect(rest).toEqual([1, 2, 3, 4, 5]); }); describe('used as function parameter', () => { - it('prefix with `...` to spread as function params', function() { + it('prefix with `...` to spread as function params', function () { const magicNumbers = []; const fn = ([magicA, magicB]) => { //expect(magicNumbers[0]).toEqual(magicA); @@ -532,13 +540,13 @@ describe('spread with arrays. ', () => { describe('spread with strings', () => { - it('simply spread each char of a string', function() { + it('simply spread each char of a string', function () { const [b, a] = ['ba']; //expect(a).toEqual('a'); //expect(b).toEqual('b'); }); - it('works anywhere inside an array (must not be last)', function() { + it('works anywhere inside an array (must not be last)', function () { const letters = ['a', 'bcd', 'e', 'f']; //expect(letters.length).toEqual(6); }); @@ -548,7 +556,7 @@ describe('spread with strings', () => { describe('class creation', () => { - it('is as simple as `class XXX {}`', function() { + it('is as simple as `class XXX {}`', function () { let TestClass = {}; // const instance = new TestClass(); @@ -556,12 +564,12 @@ describe('class creation', () => { }); it('class is block scoped', () => { - class Inside {} - { class Inside {} } + class Inside { } + { class Inside { } } //expect(typeof Inside).toBe('undefined'); }); - it('special method is `constructor`', function() { + it('special method is `constructor`', function () { class User { constructor(id) { @@ -572,7 +580,7 @@ describe('class creation', () => { //expect(user.id).toEqual(42); }); - it('defining a method is simple', function() { + it('defining a method is simple', function () { class User { } @@ -581,10 +589,10 @@ describe('class creation', () => { //expect(notATester.writesTests()).toBe(false); }); - it('multiple methods need no commas (opposed to object notation)', function() { + it('multiple methods need no commas (opposed to object notation)', function () { class User { wroteATest() { this.everWroteATest = true; } - isLazy() { } + isLazy() { } } const tester = new User();