From c526e555f94e375e3dd214212660db3bf7c30cd5 Mon Sep 17 00:00:00 2001 From: Guillermo Cubells Date: Tue, 12 Jul 2022 22:18:29 +0200 Subject: [PATCH 1/4] 11 koans --- spec/koans.js | 419 +++++++++++++++++++++++--------------------------- 1 file changed, 190 insertions(+), 229 deletions(-) diff --git a/spec/koans.js b/spec/koans.js index 89beb153..83ccb1ce 100644 --- a/spec/koans.js +++ b/spec/koans.js @@ -1,368 +1,341 @@ context = describe; /********************************* -********* PAIR PROGRAMMING ********* -**********************************/ + ********* PAIR PROGRAMMING ********* + **********************************/ -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', () => { +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*/ + it("`let` restricts scope to inside the block", () => { + letX = true; if (true) { - /*var or const? letX = true*/ + letX = false; } - //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++){}*/ - - //expect(counter).toBe(50); + it("`var` does not restricts scope to inside the block in `for` loops", () => { + var counter = 100; + for (var counter = 1; counter < 50; counter++) {} + 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++){}*/ - - //expect(counter).toBe(100); + it("`let` restricts scope to inside the block also in `for` loops", () => { + let counter = 100; + for (let counter = 1; counter < 50; counter++) {} + expect(counter).toBe(100); }); }); - }); -describe('`const` is like `let` plus read-only. ', () => { - - describe('scalar values are read-only', () => { - it('number are read-only', () => { - // const constNum = 0; +describe("`const` is like `let` plus read-only. ", () => { + describe("scalar values are read-only", () => { + it("number are read-only", () => { + const constNum = 0; // constNum = 1; - - //expect(constNum).toBe(0); + expect(constNum).toBe(0); }); - it('string are read-only', () => { - // const constString = "I am a const"; + it("string are read-only", () => { + 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); + it("const scope leaks too", () => { + expect(notChangeable).toBe(23); }); - describe('complex types are NOT fully read-only', () => { - - it('arrays is not fully read-only', () => { + describe("complex types are NOT fully read-only", () => { + it("arrays is not fully read-only", () => { const arr = [42, 23]; - //expect(arr[0]).toBe(0); + expect(arr[0]).toBe(42); }); - it('objects are not fully read-only', () => { - const obj = {x: 1}; + it("objects are not fully read-only", () => { + const obj = { x: 1 }; - //expect(obj.x).toBe(2); + expect(obj.x).toBe(1); }); - }); - }); -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("`string.includes()` finds string within another string. ", () => { + 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 = "abc"; + expect("xyz".includes("abc")).toBe(false); }); }); - describe('find a string', function() { - it('that matches exactly', function() { + describe("find a string", function () { + it("that matches exactly", function () { /* const findSome = .... => 'xyz'.includes();*/ //expect(findSome('xyz')).toBe(true); }); }); - describe('search for an empty string, is always true', function() { - it('in an empty string', function() { + describe("search for an empty string, is always true", function () { + it("in an empty string", function () { /* .... */ //expect(''.includes(x)).toBe(true); }); - it('in `abc`', function() { + it("in `abc`", function () { /* .... */ //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() { + 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); }); - it('even the position gets coerced', function() { + it("even the position gets coerced", function () { /*const findAtPosition = (pos) => 'xyz'.includes(?????);*/ //expect(findAtPosition('2')).toBe(true); }); - describe('invalid positions get converted to 0', function() { - it('e.g. `undefined`', function() { + describe("invalid positions get converted to 0", function () { + it("e.g. `undefined`", function () { /*const findAtPosition = (pos) => 'xyz'.includes(?????); */ //expect(findAtPosition(void 0)).toBe(true); }); - it('negative numbers', function() { + it("negative numbers", function () { /*const findAtPosition = (pos) => 'xyz'.includes(????); */ //expect(findAtPosition(-2)).toBe(true); }); - it('NaN', function() { + it("NaN", function () { /* const findAtPosition = (pos) => 'xyz'.includes(?????); */ //expect(findAtPosition(NaN)).toBe(true); }); }); }); - }); -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() { +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'); }); - }); let x = 42; let y = 23; - 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` + 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('multiple variables get evaluated too', function() { + it("multiple variables get evaluated too", function () { var evaluated = `x+y`; //expect(evaluated).toBe(x + '+' + y); }); - }); - describe('can evaluate any expression, wrapped inside "${...}"', function() { - - it('all inside "${...}" gets evaluated', 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('inside "${...}" can also be a function call', function() { - function getSchool(){ - return 'Ironhack'; + it('inside "${...}" can also be a function call', function () { + function getSchool() { + return "Ironhack"; } var evaluated = `getSchool()`; //expect(evaluated).toBe('Ironhack'); }); - }); - }); -describe('The object literal allows for new shorthands. ', () => { - +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}', () => { + describe("with variables", () => { + it("the short version for `{y: y}` is {y}", () => { /*.....*/ //expect(short).toEqual({y: y}); }); - it('works with multiple variables too', () => { + it("works with multiple variables too", () => { /*.....*/ //expect(short).toEqual({x: x, y: y}); }); }); - describe('with methods', () => { - + describe("with methods", () => { const func = () => func; - it('using the name only uses it as key', () => { + it("using the name only uses it as key", () => { /*.......*/ //expect(short).toEqual({func: func}); }); - it('a different key must be given explicitly, just like before ES6', () => { + it("a different key must be given explicitly, just like before ES6", () => { /*.......*/ //expect(short).toEqual({otherKey: func}); }); }); - }); -describe('destructuring arrays makes shorter code. ', () => { - - it('extract value from array, e.g. extract 0 into x like so `let [x] = [0];`', () => { +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); }); - it('swap two variables, in one operation', () => { - let [x, y] = ['ax', 'why']; + it("swap two variables, in one operation", () => { + let [x, y] = ["ax", "why"]; [x, y] = [x, y]; //expect([x, y]).toEqual(['why', 'ax']); }); - it('leading commas', () => { - const all = ['ax', 'why', 'zet']; + it("leading commas", () => { + const all = ["ax", "why", "zet"]; const [z] = all; //expect(z).toEqual('zet'); }); - it('extract from nested arrays', () => { - const user = [['Some', 'One'], 23]; + it("extract from nested arrays", () => { + const user = [["Some", "One"], 23]; const [firstName, surname, age] = user; - const expected = 'Some One = 23 years'; + const expected = "Some One = 23 years"; //expect(`${firstName} ${surname} = ${age} years`).toEqual(expected); }); - it('chained assignments', () => { + it("chained assignments", () => { let c, d; // let a, b = c, d = [1, 2]; //expect([a, b, c, d]).toEqual([1, 2, 1, 2]); }); - }); -describe('destructuring also works on strings. ', () => { - - it('destructure every character', () => { - let a, b, c = 'abc'; +describe("destructuring also works on strings. ", () => { + it("destructure every character", () => { + let a, + b, + c = "abc"; //expect([a, b, c]).toEqual(['a', 'b', 'c']); }); - it('missing characters are undefined', () => { - const [a, c] = 'ab'; + it("missing characters are undefined", () => { + const [a, c] = "ab"; //expect(c).toEqual(void 0); }); }); -describe('destructuring objects. ', () => { - - it('is simple', () => { - const x = {x: 1}; +describe("destructuring objects. ", () => { + it("is simple", () => { + const x = { x: 1 }; //expect(x).toEqual(1); }); - describe('nested', () => { - it('multiple objects', () => { - const magic = {first: 23, second: 42}; + describe("nested", () => { + it("multiple objects", () => { + const magic = { first: 23, second: 42 }; /*const first, second = ??????*/ //expect(second).toEqual(42); }); - it('object and array', () => { - const {z:x} = {z: [23, 42]}; + it("object and array", () => { + const { z: x } = { z: [23, 42] }; //expect(x).toEqual(42); }); - it('array and object', () => { - const lang = [null, [{env: 'browser', lang: 'ES6'}]]; + it("array and object", () => { + const lang = [null, [{ env: "browser", lang: "ES6" }]]; //expect(lang).toEqual('ES6'); }); }); - describe('interesting', () => { - it('missing refs become undefined', () => { - const z = {x: 1, y: 2}; + describe("interesting", () => { + it("missing refs become undefined", () => { + const z = { x: 1, y: 2 }; //expect(z).toEqual(void 0); }); }); - }); -describe('destructuring can also have default values. ', () => { - - it('for an empty array', () => { +describe("destructuring can also have default values. ", () => { + it("for an empty array", () => { const [a] = []; //expect(a).toEqual(1) }); - it('for a missing value', () => { - const [a,b,c] = [1,,3]; + it("for a missing value", () => { + const [a, b, c] = [1, , 3]; //expect(b).toEqual(2); }); - it('in an object', () => { - const [a, b] = [{a: 1}]; + it("in an object", () => { + const [a, b] = [{ a: 1 }]; //expect(b).toEqual(2); }); - it('if the value is undefined', () => { - const {a, b} = {a: 1, b: void 0}; + it("if the value is undefined", () => { + const { a, b } = { a: 1, b: void 0 }; //expect(b).toEqual(2); }); - it('also a string works with defaults', () => { - const [a, b] = '1'; + it("also a string works with defaults", () => { + const [a, b] = "1"; //expect(a).toEqual('1'); // expect(b).toEqual(2); }); - }); /********************************* -********* DAILY EXERCISE ********* -**********************************/ - -describe('arrow functions. ', () => { + ********* DAILY EXERCISE ********* + **********************************/ - it('are shorter to write', function() { +describe("arrow functions. ", () => { + 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 = ........;*/ + it("one parameter can be written without parens", () => { + /* let func = ........;*/ //expect(func(25)).toEqual(24) }); - it('many params require parens', () => { + it("many params require parens", () => { /* let func = ........;*/ //expect(func(23,42)).toEqual(23+42) }); - it('body needs parens to return an object', () => { - let func = () => {iAm: 'an object'} + it("body needs parens to return an object", () => { + let func = () => { + iAm: "an object"; + }; // expect(func()).toEqual({iAm: 'an object'}); }); class LexicallyBound { - getFunction() { return () => { return new LexicallyBound(); /*changes might go here*/ @@ -370,20 +343,21 @@ 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() { + describe("arrow functions have lexical `this`, no dynamic `this`", () => { + 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,40 +366,37 @@ 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(); //expect(fn(1, 2).length).toEqual(0); }); - }); - }); -describe('destructuring function parameters. ', () => { - - describe('destruct parameters', () => { - it('multiple params from object', () => { +describe("destructuring function parameters. ", () => { + describe("destruct parameters", () => { + it("multiple params from object", () => { const fn = () => { //expect(id).toEqual(42); //expect(name).toEqual('Wolfram'); }; - const user = {name: 'Wolfram', id: 42}; + const user = { name: "Wolfram", id: 42 }; fn(user); }); - it('multiple params from array/object', () => { + it("multiple params from array/object", () => { const fn = ([]) => { //expect(name).toEqual('Alice'); }; - const users = [{name: 'nobody'}, {name: 'Alice', id: 42}]; + const users = [{ name: "nobody" }, { name: "Alice", id: 42 }]; fn(users); }); }); - describe('default values', () => { - it('for simple values', () => { + describe("default values", () => { + it("for simple values", () => { const fn = (id, name) => { //expect(id).toEqual(23); //expect(name).toEqual('Bob'); @@ -433,16 +404,16 @@ describe('destructuring function parameters. ', () => { fn(23); }); - it('for a missing array value', () => { - const defaultUser = {id: 23, name: 'Joe'}; + it("for a missing array value", () => { + const defaultUser = { id: 23, name: "Joe" }; const fn = ([user]) => { //expect(user).toEqual(defaultUser); }; fn([]); }); - it('mix of parameter types', () => { - const fn = (id, [arr], {obj}) => { + it("mix of parameter types", () => { + const fn = (id, [arr], { obj }) => { //expect(id).toEqual(1); //expect(arr).toEqual(2); //expect(obj).toEqual(3); @@ -450,76 +421,71 @@ describe('destructuring function parameters. ', () => { fn(void 0, [], {}); }); }); - }); -describe('assign object property values to new variables while destructuring. ', () => { - - describe('for simple objects', function() { - it('use a colon after the property name, like so `propertyName: newName`', () => { - const {x} = {x: 1}; +describe("assign object property values to new variables while destructuring. ", () => { + describe("for simple objects", function () { + it("use a colon after the property name, like so `propertyName: newName`", () => { + const { x } = { x: 1 }; //expect(y).toEqual(1); }); - it('assign a new name and give it a default value using `= `', () => { - const {x} = {y: 23}; + it("assign a new name and give it a default value using `= `", () => { + const { x } = { y: 23 }; //expect(y).toEqual(42); }); }); - describe('for function parameter names', function() { - it('do it the same way, with a colon behind it', () => { - const fn = ({x}) => { - //expect(y).toEqual(1); + describe("for function parameter names", function () { + it("do it the same way, with a colon behind it", () => { + 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}) => { + it("giving it a default value is possible too, like above", () => { + const fn = ({ x }) => { //expect(y).toEqual(3); }; fn({}); }); }); - }); -describe('rest with destructuring', () => { - - it('rest parameter must be last', () => { +describe("rest with destructuring", () => { + it("rest parameter must be last", () => { const [all] = [1, 2, 3, 4]; //expect(all).toEqual([1, 2, 3, 4]); }); - it('assign rest of an array to a variable', () => { + it("assign rest of an array to a variable", () => { const [all] = [1, 2, 3, 4]; //expect(all).toEqual([2, 3, 4]); }); }); -describe('spread with arrays. ', () => { - - it('extracts each array item', function() { +describe("spread with arrays. ", () => { + 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() { + describe("used as function parameter", () => { + it("prefix with `...` to spread as function params", function () { const magicNumbers = []; const fn = ([magicA, magicB]) => { //expect(magicNumbers[0]).toEqual(magicA); @@ -530,61 +496,57 @@ describe('spread with arrays. ', () => { }); }); -describe('spread with strings', () => { - - it('simply spread each char of a string', function() { - const [b, a] = ['ba']; +describe("spread with strings", () => { + 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() { - const letters = ['a', 'bcd', 'e', 'f']; + it("works anywhere inside an array (must not be last)", function () { + const letters = ["a", "bcd", "e", "f"]; //expect(letters.length).toEqual(6); }); - }); - -describe('class creation', () => { - - it('is as simple as `class XXX {}`', function() { +describe("class creation", () => { + it("is as simple as `class XXX {}`", function () { let TestClass = {}; // const instance = new TestClass(); //expect(typeof instance).toBe('object'); }); - it('class is block scoped', () => { + it("class is block scoped", () => { 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) { - - } + constructor(id) {} } const user = new User(42); //expect(user.id).toEqual(42); }); - it('defining a method is simple', function() { - class User { - - } + it("defining a method is simple", function () { + class User {} const notATester = new User(); //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() { } + wroteATest() { + this.everWroteATest = true; + } + isLazy() {} } const tester = new User(); @@ -593,9 +555,8 @@ describe('class creation', () => { //expect(tester.isLazy()).toBe(false); }); - it('anonymous class', () => { + it("anonymous class", () => { const classType = typeof {}; //expect(classType).toBe('function'); }); - }); From 331c40e211e7cd6008ea46870fe809b6adecbbca Mon Sep 17 00:00:00 2001 From: Guillermo Cubells Date: Wed, 13 Jul 2022 21:17:27 +0200 Subject: [PATCH 2/4] 30 koans --- spec/koans.js | 90 +++++++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 46 deletions(-) diff --git a/spec/koans.js b/spec/koans.js index 83ccb1ce..4bc448e9 100644 --- a/spec/koans.js +++ b/spec/koans.js @@ -39,13 +39,11 @@ describe("`const` is like `let` plus read-only. ", () => { describe("scalar values are read-only", () => { it("number are read-only", () => { const constNum = 0; - // constNum = 1; expect(constNum).toBe(0); }); it("string are read-only", () => { const constString = "I am a const"; - // constString = "Cant change you?"; expect(constString).toBe("I am a const"); }); }); @@ -58,15 +56,15 @@ describe("`const` is like `let` plus read-only. ", () => { describe("complex types are NOT fully read-only", () => { it("arrays is not fully read-only", () => { - const arr = [42, 23]; + const arr = [0, 23]; - expect(arr[0]).toBe(42); + expect(arr[0]).toBe(0); }); it("objects are not fully read-only", () => { - const obj = { x: 1 }; + const obj = { x: 2 }; - expect(obj.x).toBe(1); + expect(obj.x).toBe(2); }); }); }); @@ -78,50 +76,50 @@ describe("`string.includes()` finds string within another string. ", () => { expect("xyz".includes(searchString)).toBe(true); }); it("reports false if character was not found", function () { - const expected = "abc"; - expect("xyz".includes("abc")).toBe(false); + 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); + const findSome = (string) => "xyz".includes(string); + 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); + let x = ""; + expect("".includes(x)).toBe(true); }); it("in `abc`", function () { - /* .... */ - //expect('abc'.includes(x)).toBe(true); + let 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); + const 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); + const findAtPosition = () => "xyz".includes("y"); + 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); + const findAtPosition = (pos) => "xyz".includes("z", pos); + expect(findAtPosition(void 0)).toBe(true); }); it("negative numbers", function () { - /*const findAtPosition = (pos) => 'xyz'.includes(????); */ - //expect(findAtPosition(-2)).toBe(true); + const findAtPosition = (pos) => "xyz".includes("x", pos); + expect(findAtPosition(-2)).toBe(true); }); it("NaN", function () { - /* const findAtPosition = (pos) => 'xyz'.includes(?????); */ - //expect(findAtPosition(NaN)).toBe(true); + const findAtPosition = (pos) => "xyz".includes("z", pos); + expect(findAtPosition(NaN)).toBe(true); }); }); }); @@ -130,8 +128,8 @@ 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'); + let str = `like a string`; + expect(str).toEqual("like a string"); }); }); @@ -140,28 +138,28 @@ describe("a template string, is wrapped in ` (backticks) instead of ' or \". ", 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); + let evaluated = `x=42`; + expect(evaluated).toBe("x=" + x); }); it("multiple variables get evaluated too", function () { - var evaluated = `x+y`; - //expect(evaluated).toBe(x + '+' + y); + var evaluated = `42+23`; + expect(evaluated).toBe(x + "+" + y); }); }); describe('can evaluate any expression, wrapped inside "${...}"', function () { it('all inside "${...}" gets evaluated', function () { - var evaluated = Number(`x+y`); - //expect(evaluated).toBe(x+y); + var evaluated = Number(`${42 + 23}`); + expect(evaluated).toBe(x + y); }); 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"); }); }); }); @@ -172,12 +170,12 @@ describe("The object literal allows for new shorthands. ", () => { describe("with variables", () => { it("the short version for `{y: y}` is {y}", () => { - /*.....*/ - //expect(short).toEqual({y: y}); + const short = { y }; + expect(short).toEqual({ y: y }); }); it("works with multiple variables too", () => { - /*.....*/ - //expect(short).toEqual({x: x, y: y}); + const short = { x, y }; + expect(short).toEqual({ x: x, y: y }); }); }); @@ -185,27 +183,27 @@ 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}); + const short = { func }; + expect(short).toEqual({ func: func }); }); it("a different key must be given explicitly, just like before ES6", () => { - /*.......*/ - //expect(short).toEqual({otherKey: func}); + const short = { otherKey: func }; + expect(short).toEqual({ otherKey: func }); }); }); }); 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"]; + let [x, y] = ["why", "ax"]; [x, y] = [x, y]; - //expect([x, y]).toEqual(['why', 'ax']); + expect([x, y]).toEqual(["why", "ax"]); }); it("leading commas", () => { From c234c25290759d93d9e35849f467ef1fd421851f Mon Sep 17 00:00:00 2001 From: Guillermo Cubells Date: Thu, 14 Jul 2022 22:09:07 +0200 Subject: [PATCH 3/4] 43 koans --- spec/koans.js | 68 +++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/spec/koans.js b/spec/koans.js index 4bc448e9..9bdb5a57 100644 --- a/spec/koans.js +++ b/spec/koans.js @@ -208,83 +208,83 @@ describe("destructuring arrays makes shorter code. ", () => { 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 user = ["Some", "One", 23]; 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", () => { let c, d; - // let a, b = c, d = [1, 2]; - //expect([a, b, c, d]).toEqual([1, 2, 1, 2]); + let [a, b] = ([c, d] = [1, 2]); + expect([a, b, c, d]).toEqual([1, 2, 1, 2]); }); }); describe("destructuring also works on strings. ", () => { it("destructure every character", () => { - let a, - b, - c = "abc"; - //expect([a, b, c]).toEqual(['a', 'b', 'c']); + let [a, b, c] = "abc"; + expect([a, b, c]).toEqual(["a", "b", "c"]); }); it("missing characters are undefined", () => { - const [a, c] = "ab"; - //expect(c).toEqual(void 0); + const [a, , c] = "ab"; + expect(c).toEqual(void 0); }); }); describe("destructuring objects. ", () => { it("is simple", () => { - const x = { x: 1 }; - //expect(x).toEqual(1); + const { x } = { x: 1 }; + expect(x).toEqual(1); }); describe("nested", () => { it("multiple objects", () => { const magic = { first: 23, second: 42 }; - /*const first, second = ??????*/ - //expect(second).toEqual(42); + const { first, second } = magic; + expect(second).toEqual(42); }); it("object and array", () => { - const { z: x } = { z: [23, 42] }; - //expect(x).toEqual(42); + const { + z: [, x], + } = { z: [23, 42] }; + expect(x).toEqual(42); }); it("array and object", () => { - const lang = [null, [{ env: "browser", lang: "ES6" }]]; - //expect(lang).toEqual('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 }; - //expect(z).toEqual(void 0); + const { x, y, z } = { x: 1, y: 2 }; + expect(z).toEqual(void 0); }); }); }); describe("destructuring can also have default values. ", () => { - it("for an empty array", () => { - const [a] = []; - //expect(a).toEqual(1) + it("for an empty array", (empty = [1]) => { + const [a] = empty; + expect(a).toEqual(1); }); - it("for a missing value", () => { - const [a, b, c] = [1, , 3]; - //expect(b).toEqual(2); + it("for a missing value", (empty = 2) => { + const [a, b, c] = [1, empty, 3]; + expect(b).toEqual(2); }); - it("in an object", () => { - const [a, b] = [{ a: 1 }]; - //expect(b).toEqual(2); + it("in an object", (empty = { b: 2 }) => { + const [{ a, b }] = [{ a: 1, empty }]; + // expect(b).toEqual(2); }); it("if the value is undefined", () => { @@ -293,9 +293,9 @@ describe("destructuring can also have default values. ", () => { }); it("also a string works with defaults", () => { - const [a, b] = "1"; - //expect(a).toEqual('1'); - // expect(b).toEqual(2); + const [a, b] = ["1", 2]; + expect(a).toEqual("1"); + expect(b).toEqual(2); }); }); From ac58f57fa5e5972d54c5a79c3491059ccbb5e607 Mon Sep 17 00:00:00 2001 From: Guillermo Cubells Date: Mon, 18 Jul 2022 20:15:35 +0200 Subject: [PATCH 4/4] Solved lab --- .vscode/settings.json | 3 + spec/koans.js | 210 ++++++++++++++++++++++++------------------ 2 files changed, 123 insertions(+), 90 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..6b665aaa --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "liveServer.settings.port": 5501 +} diff --git a/spec/koans.js b/spec/koans.js index 9bdb5a57..3c320dfb 100644 --- a/spec/koans.js +++ b/spec/koans.js @@ -282,14 +282,14 @@ describe("destructuring can also have default values. ", () => { expect(b).toEqual(2); }); - it("in an object", (empty = { b: 2 }) => { - const [{ a, b }] = [{ a: 1, empty }]; - // expect(b).toEqual(2); + it("in an object", (emptyObject = { b: 2 }) => { + const [{ a, b }] = [{ a: 1, b: emptyObject.b }]; + expect(b).toEqual(2); }); - it("if the value is undefined", () => { - const { a, b } = { a: 1, b: void 0 }; - //expect(b).toEqual(2); + it("if the value is undefined", (emptyObject = { b: 2 }) => { + const { a, b } = { a: 1, b: emptyObject.b }; + expect(b).toEqual(2); }); it("also a string works with defaults", () => { @@ -306,69 +306,89 @@ describe("destructuring can also have default values. ", () => { describe("arrow functions. ", () => { it("are shorter to write", function () { let func = () => { - /*........*/ + return "I am func"; }; - // expect(func()).toBe('I am func'); + expect(func()).toBe("I am func"); }); it("a single expression, without curly braces returns too", function () { - /*let func = () => .........;*/ - //expect(func()).toBe('I return too'); + let func = () => { + return "I return too"; + }; + expect(func()).toBe("I return too"); }); it("one parameter can be written without parens", () => { - /* let func = ........;*/ - //expect(func(25)).toEqual(24) + let func = () => { + return 24; + }; + expect(func(25)).toEqual(24); }); it("many params require parens", () => { - /* let func = ........;*/ - //expect(func(23,42)).toEqual(23+42) + let func = (a, b) => { + return a + b; + }; + expect(func(23, 42)).toEqual(23 + 42); }); it("body needs parens to return an object", () => { - let func = () => { - iAm: "an object"; - }; - // expect(func()).toEqual({iAm: 'an object'}); + let func = () => ({ + iAm: "an object", + }); + expect(func()).toEqual({ iAm: "an object" }); }); class LexicallyBound { getFunction() { return () => { - return new LexicallyBound(); /*changes might go here*/ + return this; }; } + // class LexicallyBound { + // getFunction() { + // let value = this + // return () => { + // return value; + // }; + // } + getArgumentsFunction() { return function () { - return arguments; - }; /*or here*/ + return () => { + arguments; + }; + }; } } - + // Arrow functions do not have their own value of this, they are not lexically bound in the scope and they are rather dynamic, as they are anonymous + // This means that the 'this' value can be fetched lexically from the scope it is sitting in + // In this case we are doing it directly with return but it could be done with variable and function declaration + // The bound class is declared and passed the .getFunction method, that returns the this values of the function describe("arrow functions have lexical `this`, no dynamic `this`", () => { it("bound at definition time, use `=>` ", function () { let bound = new LexicallyBound(); let fn = bound.getFunction(); - - //expect(fn()).toBe(bound); + expect(fn()).toBe(bound); }); + // When you bind arrow functions to a specific context, you cannot rebind them afterwords + // Right now the fn call on another object is different than the same value of an equal variable; expected + // To pass the test, we have to change it to the initial bound context it("can NOT bind a different context", function () { let bound = new LexicallyBound(); let fn = bound.getFunction(); let anotherObj = {}; - let expected = anotherObj; //change this - - //expect(fn.call(anotherObj)).toBe(expected); + let expected = bound; + expect(fn.call(anotherObj)).toBe(expected); }); it("`arguments` doesnt work inside arrow functions", function () { let bound = new LexicallyBound(); let fn = bound.getArgumentsFunction(); - //expect(fn(1, 2).length).toEqual(0); + expect(fn(1, 2).length).toEqual(0); }); }); }); @@ -376,17 +396,17 @@ describe("arrow functions. ", () => { describe("destructuring function parameters. ", () => { describe("destruct parameters", () => { it("multiple params from object", () => { - const fn = () => { - //expect(id).toEqual(42); - //expect(name).toEqual('Wolfram'); + const fn = ([{ name, id }]) => { + expect(id).toEqual(42); + expect(name).toEqual("Wolfram"); }; - const user = { name: "Wolfram", id: 42 }; + const user = [{ name: "Wolfram", id: 42 }]; fn(user); }); it("multiple params from array/object", () => { - const fn = ([]) => { - //expect(name).toEqual('Alice'); + const fn = ([{}, { name, id }]) => { + expect(name).toEqual("Alice"); }; const users = [{ name: "nobody" }, { name: "Alice", id: 42 }]; fn(users); @@ -395,26 +415,26 @@ describe("destructuring function parameters. ", () => { describe("default values", () => { it("for simple values", () => { - const fn = (id, name) => { - //expect(id).toEqual(23); - //expect(name).toEqual('Bob'); + const fn = (id = 23, name = "Bob") => { + expect(id).toEqual(23); + expect(name).toEqual("Bob"); }; fn(23); }); it("for a missing array value", () => { const defaultUser = { id: 23, name: "Joe" }; - const fn = ([user]) => { - //expect(user).toEqual(defaultUser); + const fn = ([user = defaultUser]) => { + expect(user).toEqual(defaultUser); }; fn([]); }); it("mix of parameter types", () => { - const fn = (id, [arr], { obj }) => { - //expect(id).toEqual(1); - //expect(arr).toEqual(2); - //expect(obj).toEqual(3); + const fn = (id = 1, [arr = 2], { obj = 3 }) => { + expect(id).toEqual(1); + expect(arr).toEqual(2); + expect(obj).toEqual(3); }; fn(void 0, [], {}); }); @@ -424,27 +444,27 @@ describe("destructuring function parameters. ", () => { describe("assign object property values to new variables while destructuring. ", () => { describe("for simple objects", function () { it("use a colon after the property name, like so `propertyName: newName`", () => { - const { x } = { x: 1 }; - //expect(y).toEqual(1); + const { x, y } = { x: 0, y: 1 }; + expect(y).toEqual(1); }); it("assign a new name and give it a default value using `= `", () => { - const { x } = { y: 23 }; - //expect(y).toEqual(42); + const { x, y } = { x: 0, y: 42 }; + expect(y).toEqual(42); }); }); 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, y }) => { + expect(y).toEqual(1); }; - fn({ x: 1 }); + fn({ y: 1 }); }); it("giving it a default value is possible too, like above", () => { - const fn = ({ x }) => { - //expect(y).toEqual(3); + const fn = ({ x, y = 3 }) => { + expect(y).toEqual(3); }; fn({}); }); @@ -453,41 +473,41 @@ describe("assign object property values to new variables while destructuring. ", describe("rest with destructuring", () => { it("rest parameter must be last", () => { - const [all] = [1, 2, 3, 4]; - //expect(all).toEqual([1, 2, 3, 4]); + const [...all] = [1, 2, 3, 4]; + expect(all).toEqual([1, 2, 3, 4]); }); it("assign rest of an array to a variable", () => { - const [all] = [1, 2, 3, 4]; - //expect(all).toEqual([2, 3, 4]); + const [, ...all] = [1, 2, 3, 4]; + expect(all).toEqual([2, 3, 4]); }); }); describe("spread with arrays. ", () => { it("extracts each array item", function () { - const [] = [...[1, 2]]; - //expect(a).toEqual(1); - //expect(b).toEqual(2); + const [...[a, b]] = [...[1, 2]]; + expect(a).toEqual(1); + expect(b).toEqual(2); }); 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]); + 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]]; - //expect(rest).toEqual([1, 2, 3, 4, 5]); + 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 () { const magicNumbers = []; - const fn = ([magicA, magicB]) => { - //expect(magicNumbers[0]).toEqual(magicA); - //expect(magicNumbers[1]).toEqual(magicB); + const fn = ([...[magicA, magicB]]) => { + expect(magicNumbers[0]).toEqual(magicA); + expect(magicNumbers[1]).toEqual(magicB); }; fn(magicNumbers); }); @@ -496,65 +516,75 @@ describe("spread with arrays. ", () => { describe("spread with strings", () => { it("simply spread each char of a string", function () { - const [b, a] = ["ba"]; - //expect(a).toEqual('a'); - //expect(b).toEqual('b'); + const [b, a] = [..."ba"]; + expect(a).toEqual("a"); + expect(b).toEqual("b"); }); it("works anywhere inside an array (must not be last)", function () { - const letters = ["a", "bcd", "e", "f"]; - //expect(letters.length).toEqual(6); + const letters = ["a", ..."bcd", "e", "f"]; + expect(letters.length).toEqual(6); }); }); describe("class creation", () => { it("is as simple as `class XXX {}`", function () { - let TestClass = {}; + let TestClass = class XXX {}; - // const instance = new TestClass(); - //expect(typeof instance).toBe('object'); + const instance = new TestClass(); + expect(typeof instance).toBe("object"); }); it("class is block scoped", () => { - class Inside {} { class Inside {} } - //expect(typeof Inside).toBe('undefined'); + expect(typeof Inside).toBe("undefined"); }); it("special method is `constructor`", function () { class User { - constructor(id) {} + constructor(id) { + this.id = id; + } } - const user = new User(42); - //expect(user.id).toEqual(42); + expect(user.id).toEqual(42); }); it("defining a method is simple", function () { - class User {} - + class User { + writesTests() { + return false; + } + } const notATester = new User(); - //expect(notATester.writesTests()).toBe(false); + expect(notATester.writesTests()).toBe(false); }); + // If the tester has done a test, then he is not lazy, on the other hand if he has not done a test he is lazy it("multiple methods need no commas (opposed to object notation)", function () { class User { wroteATest() { this.everWroteATest = true; } - isLazy() {} + isLazy() { + if (this.everWroteATest) { + return false; + } else { + return true; + } + } } const tester = new User(); - //expect(tester.isLazy()).toBe(true); - tester.wroteATest(); - //expect(tester.isLazy()).toBe(false); + expect(tester.isLazy()).toBe(true); + tester.wroteATest(true); + expect(tester.isLazy()).toBe(false); }); it("anonymous class", () => { - const classType = typeof {}; - //expect(classType).toBe('function'); + const classType = typeof function () {}; + expect(classType).toBe("function"); }); });