Last active
October 1, 2019 00:24
-
-
Save Chett23/3f4c30da15a1056e97478062c0441b53 to your computer and use it in GitHub Desktop.
ES6 Katas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This gist is to save my work on the ES6 Katas. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 10: destructuring - array | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
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]; | |
assert.strictEqual(firstValue, 1); | |
}); | |
it('get the last item from array', () => { | |
let [,,lastValue] = [1, 2, 3]; | |
assert.strictEqual(lastValue, 3); | |
}); | |
it('swap two variables, in one operation', () => { | |
let [x, y] = ['ax', 'why']; | |
[x, y] = [y, x]; | |
assert.deepEqual([x, y], ['why', 'ax']); | |
}); | |
it('leading commas', () => { | |
const all = ['ax', 'why', 'zet']; | |
const [,,z] = all; | |
assert.equal(z, 'zet'); | |
}); | |
it('extract from nested arrays', () => { | |
const user = [['Some', 'One'], 23]; | |
const [[firstName, surname], age] = user; | |
const expected = 'Some One = 23 years'; | |
assert.equal(`${firstName} ${surname} = ${age} years`, expected); | |
}); | |
it('chained assignments', () => { | |
let c, d; | |
let [a, b] = [c, d] = [1, 2]; | |
assert.deepEqual([a, b, c, d], [1, 2, 1, 2]); | |
}); | |
it('in for-of loop', () => { | |
for (var [a, b] of [[1, 2]]) {} | |
assert.deepEqual([a, b], [1, 2]); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 11: destructuring - string | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('Destructuring also works on strings', () => { | |
it('destructure every character, just as if the string was an array', () => { | |
let [a, b, c] = 'abc'; | |
assert.deepEqual([a, b, c], ['a', 'b', 'c']); | |
}); | |
it('missing characters are undefined', () => { | |
const [a, ,c] = 'ab'; | |
assert.equal(c, void 0); | |
}); | |
it('unicode character work too', () => { | |
const [,space, coffee] = 'a ☕'; | |
assert.equal(coffee, '\u{2615}'); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 12: destructuring - object | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('Destructure objects', () => { | |
it('by surrounding the left-hand variable with `{}`', () => { | |
const {x} = {x: 1}; | |
assert.equal(x, 1); | |
}); | |
describe('nested', () => { | |
it('multiple objects', () => { | |
const magic = {first: 23, second: 42}; | |
const {second} = magic; | |
assert.equal(second, 42); | |
}); | |
it('object and array', () => { | |
const {z:[,x]} = {z: [23, 42]}; | |
assert.equal(x, 42); | |
}); | |
it('array and object', () => { | |
const [,[{lang}]] = [null, [{env: 'browser', lang: 'ES6'}]]; | |
assert.equal(lang, 'ES6'); | |
}); | |
}); | |
describe('interesting', () => { | |
it('missing refs become undefined', () => { | |
const {z} = {x: 1}; | |
assert.equal(z, void 0); | |
}); | |
it('destructure from builtins (string)', () => { | |
const {substr} = String(1); | |
assert.equal(substr, String.prototype.substr); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 13: destructuring - defaults | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('When destructuring you can also provide default values', () => { | |
it('just assign a default value, like so `a=1`', () => { | |
const [a=1] = []; | |
assert.equal(a, 1); | |
}); | |
it('for a missing value', () => { | |
const [,b=2] = [1,,3]; | |
assert.equal(b, 2); | |
}); | |
it('in an object', () => { | |
const {a, b=2} = {a: 1}; | |
assert.equal(b, 2); | |
}); | |
it('if the value is undefined', () => { | |
const {a, b=2} = {a: 1, b: void 0}; | |
assert.strictEqual(b, 2); | |
}); | |
it('also a string works with defaults', () => { | |
const [a,b=2] = '1'; | |
assert.equal(a, '1'); | |
assert.equal(b, 2); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 14: destructuring - parameters | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('Destructuring function parameters', () => { | |
describe('destruct parameters', () => { | |
it('multiple params from object', () => { | |
const fn = ({id, name}) => { | |
assert.equal(id, 42); | |
assert.equal(name, 'Wolfram'); | |
}; | |
const user = {name: 'Wolfram', id: 42}; | |
fn(user); | |
}); | |
it('multiple params from array/object', () => { | |
const fn = ([,{name}]) => { | |
assert.equal(name, 'Alice'); | |
}; | |
const users = [{name: 'nobody'}, {name: 'Alice', id: 42}]; | |
fn(users); | |
}); | |
}); | |
describe('default values', () => { | |
it('for simple values', () => { | |
const fn = (id, name='Bob') => { | |
assert.strictEqual(id, 23); | |
assert.strictEqual(name, 'Bob'); | |
}; | |
fn(23); | |
}); | |
it('for a missing array value', () => { | |
const defaultUser = {id: 23, name: 'Joe'}; | |
const fn = ([user={id:23,name:'Joe'}]) => { | |
assert.deepEqual(user, defaultUser); | |
}; | |
fn([]); | |
}); | |
it('mix of parameter types', () => { | |
const fn = (id=1, [arr=2], {obj=3}) => { | |
assert.equal(id, 1); | |
assert.equal(arr, 2); | |
assert.equal(obj, 3); | |
}; | |
fn(void 0, [], {}); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 15: destructuring - assign | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
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: y} = {x: 1}; | |
assert.equal(y, 1); | |
}); | |
it('assign a new name and give it a default value using `= <default value>`', () => { | |
const {x: y=42} = {y: 23}; | |
assert.equal(y, 42); | |
}); | |
}); | |
describe('for function parameter names', function() { | |
it('do it the same way, with a colon behind it', () => { | |
const fn = ({x: y}) => { | |
assert.equal(y, 1); | |
}; | |
fn({x: 1}); | |
}); | |
it('giving it a default value is possible too, like above', () => { | |
const fn = ({x: y=3}) => { | |
assert.equal(y, 3); | |
}; | |
fn({}); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 16: object-literal - computed properties | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('Object literal properties may be computed values', () => { | |
it('a computed property `x` needs to be surrounded by `[]`', () => { | |
const propertyName = 'x'; | |
const obj = {[propertyName]: 1}; | |
assert.equal(obj.x, 1); | |
}); | |
it('can also get a function assigned', () => { | |
const key = 'func'; | |
const obj = {[key](){return 'seven'}}; | |
assert.equal(obj.func(), 'seven'); | |
}); | |
it('the key may also be the result of a function call', () => { | |
const getName = () => 'propertyName'; | |
const obj = {[getName()]() {return 'seven'}}; | |
assert.equal(obj.propertyName(), 'seven'); | |
}); | |
it('the key can also be constructed by an expression', () => { | |
const what = 'tyName'; | |
const obj = {['proper' + what]: null}; | |
assert('propertyName' in obj); | |
}); | |
it('accessor keys can be computed names too', () => { | |
const obj = { | |
get ['key']() {return 1}, | |
}; | |
assert.equal(obj.key, 1); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 17: unicode - in strings | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('Unicode in strings', () => { | |
it('are prefixed with `\\u` (one backslash and u)', () => { | |
const nuclear = '\u2622'; | |
assert.equal(nuclear, '☢'); | |
}); | |
it('value is 4 bytes/digits', () => { | |
const nuclear = '\u2622'; | |
assert.equal(`no more ${nuclear}`, 'no more ☢'); | |
}); | |
it('even "normal" character`s values can be written as hexadecimal unicode', () => { | |
const nuclear = `\u006E\u006F more \u2622`; | |
assert.equal(nuclear, 'no more ☢'); | |
}); | |
it('curly braces may surround the value', () => { | |
const nuclear = `\u{006E}\u006F more \u2622`; | |
assert.equal(nuclear, 'no more ☢'); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 18: rest - as-parameter | |
// To do: make all tests pass, leave the assert lines unchanged! | |
describe('Rest parameters in functions', () => { | |
it('must be the last parameter', () => { | |
const fn = (...rest) => { | |
assert.deepEqual([1, 2], rest); | |
}; | |
fn(1, 2); | |
}); | |
it('can be used to get all other parameters', () => { | |
const fn = (firstParam, secondParam, ...rest) => { | |
assert.deepEqual([3,4], rest); | |
}; | |
fn(null, 2, 3, 4); | |
}); | |
it('makes `arguments` obsolete', () => { | |
const fn = (...args) => { | |
assert.deepEqual([42, 'twenty three', 'win'], args); | |
}; | |
fn(42, 'twenty three', 'win'); | |
}); | |
it('eliminate `arguments`!!!', () => { | |
const fn = (...rest) => rest; | |
const [firstArg, ...rest] = fn(1, 2, 3); | |
assert.deepEqual([2, 3], rest); | |
}); | |
}); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 19: rest - with-destructuring | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('Rest parameters with destructuring', () => { | |
it('must be last', () => { | |
const [...all] = [1, 2, 3, 4]; | |
assert.deepEqual(all, [1, 2, 3, 4]); | |
}); | |
it('assign rest of an array to a variable', () => { | |
const [last, ...all] = [1, 2, 3, 4]; | |
assert.deepEqual(all, [2, 3, 4]); | |
}); | |
// the following are actually using `spread` ... oops, to be fixed #TODO | |
it('concat differently', () => { | |
const theEnd = [3, 4]; | |
const allInOne = [1, 2, ...theEnd]; | |
assert.deepEqual(allInOne, [1, 2, 3, 4]); | |
}); | |
it('`apply` made simple, even for constructors', () => { | |
const theDate = [2015, 1, 1]; | |
const date = new Date(...theDate); | |
assert.deepEqual(new Date(2015, 1, 1), date); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 1: template strings - basics | |
// To do: make all tests pass, leave the asserts unchanged! | |
// Follow the hints of the failure messages! | |
describe('A template string, is wrapped in ` (backticks) instead of \' or "', function() { | |
describe('by default, behaves like a normal string', function() { | |
it('just surrounded by backticks', function() { | |
// var str had nothing within the backticks | |
var str = `like a string`; | |
assert.equal(str, `like a string`); | |
}); | |
}); | |
var x = 42; | |
var y = 23; | |
describe('can evaluate variables, which are wrapped in "${" and "}"', function() { | |
it('e.g. a simple variable "${x}" just gets evaluated', function() { | |
var evaluated = `x=${x}`; | |
assert.equal(evaluated, 'x=' + x); | |
}); | |
it('multiple variables get evaluated too', function() { | |
var evaluated = `${ x }+${ y }`; | |
assert.equal(evaluated, x + '+' + y); | |
}); | |
}); | |
describe('can evaluate any expression, wrapped inside "${...}"', function() { | |
it('all inside "${...}" gets evaluated', function() { | |
var evaluated = `${ x + y }`; | |
assert.equal(evaluated, x+y); | |
}); | |
it('inside "${...}" can also be a function call', function() { | |
function getDomain(){ | |
return document.domain; | |
} | |
var evaluated = `${ getDomain() }`; | |
assert.equal(evaluated, 'tddbin.com'); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 20: spread - with-arrays | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('Spread syntax with arrays', () => { | |
describe('basically', () => { | |
it('expands the items of an array by prefixing it with `...`', function() { | |
const middle = [1, 2, 3]; | |
const arr = [0, ...middle, 4]; | |
assert.deepEqual(arr, [0, 1, 2, 3, 4]); | |
}); | |
it('an empty array expanded is no item', function() { | |
const arr = [0, ...[], 1]; | |
assert.deepEqual(arr, [0, 1]); | |
}); | |
}); | |
describe('is (in a way) the opposite to the rest syntax', function() { | |
it('both use `...` to either expand all items and collect them', function() { | |
const [...rest] = [...[1, 2, 3, 4, 5]]; | |
assert.deepEqual(rest, [1, 2, 3, 4, 5]); | |
}); | |
it('rest syntax must be last in an array, spread can be used in any place', function() { | |
const [a, b, ...rest] = [1, ...[2, 3], 4, 5]; | |
assert.equal(a, 1); | |
assert.equal(b, 2); | |
assert.deepEqual(rest, [3, 4, 5]); | |
}); | |
}); | |
describe('used as function parameter', () => { | |
it('prefix with `...` to spread as function params', function() { | |
const magicNumbers = [1, 2]; | |
const fn = ([magicA, magicB]) => { | |
assert.deepEqual(magicNumbers[0], magicA); | |
assert.deepEqual(magicNumbers[1], magicB); | |
}; | |
fn(magicNumbers); | |
}); | |
it('pass an array of numbers to Math.max()', function() { | |
const max = Math.max(...[23, 0, 42]); | |
assert.equal(max, 42); | |
}); | |
}); | |
describe('used as constructor parameter', () => { | |
it('just like in a function call (is not possible using `apply`)', () => { | |
class X { | |
constructor(a, b, c) { return [a, b, c]; } | |
} | |
const args = [1,2,3]; | |
assert.deepEqual(new X(...args), [1, 2, 3]); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 21: spread - with-strings | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('Spread syntax with strings', () => { | |
it('expands each character of a string by prefixing it with `...`', function() { | |
const [a,b] = [...'ab']; | |
assert.equal(a, 'a'); | |
assert.equal(b, 'b'); | |
}); | |
it('expands any kind of character', function() { | |
const arr = [...'1', ' ', '☢', ' ', '2']; | |
assert.deepEqual(arr, ['1', ' ', '☢', ' ', '2']); | |
}); | |
it('works anywhere inside an array (must not be last)', function() { | |
const letters = ['a', 'bcd', 'e', 'f','','']; | |
assert.equal(letters.length, 6); | |
}); | |
it('don`t confuse with the rest operator', function() { | |
const [...rest] = [...'1234', ...'5']; | |
assert.deepEqual(rest, [1, 2, 3, 4, 5]); | |
}); | |
it('can also be used as function parameter', function() { | |
const max = Math.max(...'12345'); | |
assert.deepEqual(max, 5); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 22: class - creation | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('Class creation', () => { | |
it('is as simple as `class XXX {}`', function() { | |
class TestClass {}; | |
const instance = new TestClass(); | |
assert.equal(typeof instance, 'object'); | |
}); | |
it('a class is block scoped', () => { | |
{class Inside {}} | |
assert.equal(typeof Inside, 'undefined'); | |
}); | |
it('the `constructor` is a special method', function() { | |
class User { | |
constructor(id) { | |
this.id = id | |
} | |
} | |
const user = new User(42); | |
assert.equal(user.id, 42); | |
}); | |
it('defining a method by writing it inside the class body', function() { | |
class User { | |
writesTests(){ | |
return false | |
} | |
} | |
const notATester = new User(); | |
assert.equal(notATester.writesTests(), false); | |
}); | |
it('multiple methods need no commas (opposed to object notation)', function() { | |
class User { | |
wroteATest() { this.everWroteATest = true; } | |
isLazy() { return true } | |
} | |
const tester = new User(); | |
assert.equal(tester.isLazy(), true); | |
tester.wroteATest(); | |
assert.equal(tester.isLazy(), true); | |
}); | |
it('anonymous class', () => { | |
const classType = typeof class test {}; | |
assert.equal(classType, 'function'); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 23: class - accessors | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('Class accessors (getter and setter)', () => { | |
it('a getter is defined like a method prefixed with `get`', () => { | |
class MyAccount { | |
get balance() { return Infinity; } | |
} | |
assert.equal(new MyAccount().balance, Infinity); | |
}); | |
it('a setter has the prefix `set`', () => { | |
class MyAccount { | |
get balance() { return this.amount; } | |
set balance(amount) { this.amount = amount; } | |
} | |
const account = new MyAccount(); | |
account.balance = 23; | |
assert.equal(account.balance, 23); | |
}); | |
describe('dynamic accessors', () => { | |
it('a dynamic getter name is enclosed in `[]`', function() { | |
const balance = 'yourMoney'; | |
class YourAccount { | |
get [balance]() { return -Infinity; } | |
} | |
assert.equal(new YourAccount().yourMoney, -Infinity); | |
}); | |
it('a dynamic setter name as well', function() { | |
const propertyName = 'balance'; | |
class MyAccount { | |
get [propertyName]() { return this.amount; } | |
set [propertyName](amount) { this.amount = 23; } | |
} | |
const account = new MyAccount(); | |
account.balance = 42; | |
assert.equal(account.balance, 23); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 24: class - static keyword | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('Inside a class you can use the `static` keyword', () => { | |
describe('for methods', () => { | |
class UnitTest {} | |
it('a static method just has the prefix `static`', () => { | |
class TestFactory { | |
static makeTest() { return new UnitTest(); } | |
} | |
assert.ok(TestFactory.makeTest() instanceof UnitTest); | |
}); | |
it('the method name can be dynamic/computed at runtime', () => { | |
const methodName = 'createTest'; | |
class TestFactory { | |
static [methodName]() { return new UnitTest(); } | |
} | |
assert.ok(TestFactory.createTest() instanceof UnitTest); | |
}); | |
}); | |
describe('for accessors', () => { | |
it('a getter name can be static, just prefix it with `static`', () => { | |
class UnitTest { | |
static get testType() { return 'unit'; } | |
} | |
assert.equal(UnitTest.testType, 'unit'); | |
}); | |
it('even a static getter name can be dynamic/computed at runtime', () => { | |
const type = 'test' + 'Type'; | |
class IntegrationTest { | |
static get [type]() { return 'integration'; } | |
} | |
assert.ok('testType' in IntegrationTest); | |
assert.equal(IntegrationTest.testType, 'integration'); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 25: class - extends | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('Classes can inherit from another using `extends`', () => { | |
describe('the default super class is `Object`', () => { | |
it('a `class A` is an instance of `Object`', () => { | |
class A extends Object {} | |
assert.equal(new A() instanceof Object, true); | |
}); | |
it('when B extends A, B is also instance of `Object`', () => { | |
class A {} | |
class B extends A {} | |
assert.equal(new B() instanceof A, true); | |
assert.equal(new B() instanceof Object, true); | |
}); | |
it('a class can extend `null`, and is not an instance of Object', () => { | |
class NullClass extends null {} | |
let nullInstance = new NullClass(); | |
assert.equal(nullInstance instanceof Object, false); | |
}); | |
}); | |
describe('instance of', () => { | |
it('when B inherits from A, `new B()` is also an instance of A', () => { | |
class A {}; | |
class B extends A {} | |
assert.equal(new B() instanceof A, true); | |
}); | |
it('extend over multiple levels', () => { | |
class A {} | |
class B extends A {} | |
class C extends B {} | |
assert.equal(new C instanceof A, true); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 26: class - more-extends | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('Classes can inherit from another', () => { | |
it('extend an `old style` "class", a function, still works', () => { | |
class A {}; | |
class B extends A {} | |
assert.equal(new B() instanceof A, true); | |
}); | |
describe('prototypes are as you know them', () => { | |
class A {} | |
class B extends A {} | |
it('A is the prototype of B', () => { | |
const isIt = A.isPrototypeOf(B); | |
assert.equal(isIt, true); | |
}); | |
it('A`s prototype is also B`s prototype', () => { | |
const proto = new B (); | |
// Remember: don't touch the assert!!! :) | |
assert.equal(A.prototype.isPrototypeOf(proto), true); | |
}); | |
}); | |
describe('`extends` using an expression', () => { | |
it('e.g. the inline assignment of the parent class', () => { | |
class A {}; | |
class B extends A {} | |
assert.equal(new B() instanceof A, true); | |
}); | |
it('or calling a function that returns the parent class', () => { | |
const returnParent = (beNull) => beNull ? class {} : null; | |
class B extends returnParent() {} | |
assert.equal(Object.getPrototypeOf(B.prototype), null); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 27: class - super inside a method | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('Inside a class use `super` to access parent methods', () => { | |
it('use of `super` without `extends` fails (already when transpiling)', () => { | |
class A {hasSuper() { return false; }} | |
assert.equal(new A().hasSuper(), false); | |
}); | |
it('`super` with `extends` calls the method of the given name of the parent class', () => { | |
class A {hasSuper() { return true; }} | |
class B extends A {super() { return this.hasSuper; }} | |
assert.equal(new B().hasSuper(), true); | |
}); | |
it('when overridden a method does NOT automatically call its super method', () => { | |
class A {hasSuper() { return void 0; }} | |
class B extends A {super() { return this.hasSuper; }} | |
assert.equal(new B().hasSuper(), void 0); | |
}); | |
it('`super` works across any number of levels of inheritance', () => { | |
class A {iAmSuper() { return true; }} | |
class B extends A {} | |
class C extends B {super() { return iAmSuper(); }} | |
assert.equal(new C().iAmSuper(), true); | |
}); | |
it('accessing an undefined member of the parent class returns `undefined`', () => { | |
class A {} | |
class B extends A {getMethod() { return super.undefined; }} | |
assert.equal(new B().getMethod(), void 0); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 28: class - super in constructor | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('Inside a class`s constructor `super()` can be used', () => { | |
it('`extend` a class and use `super()` to call the parent constructor', () => { | |
class A {constructor() { this.levels = 1; }} | |
class B extends A { | |
constructor() { | |
super(); | |
this.levels++; | |
} | |
} | |
assert.equal(new B().levels, 2); | |
}); | |
it('`super()` may also take params', () => { | |
class A {constructor(startValue=1, addTo=1) { this.counter = startValue + addTo; }} | |
class B extends A { | |
constructor(...args) { | |
super(...args); | |
this.counter++; | |
} | |
} | |
assert.equal(new B(42, 2).counter, 45); | |
}); | |
it('it is important where you place your `super()` call!', () => { | |
class A {inc() { this.countUp = 1; }} | |
class B extends A { | |
inc() { | |
super.inc(); | |
this.countUp = 1; | |
return this.countUp; | |
} | |
} | |
assert.equal(new B().inc(), 1); | |
}); | |
it('use `super.constructor` to find out if there is a parent constructor', () => { | |
class ParentClassA {constructor() {"parent"}} | |
class B extends ParentClassA { | |
constructor() { | |
super(); | |
this.isTop = '' + super.constructor; | |
} | |
} | |
assert(new B().isTop.includes('ParentClassA'), new B().isTop); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 29: array - `Array.from` static method | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('`Array.from` converts an array-like object or list into an Array', () => { | |
const arrayLike = {0: 'one', 1: 'two', length: 2}; | |
it('call `Array.from` with an array-like object', function() { | |
const arr = Array.from(arrayLike); | |
assert.deepEqual(arr, ['one', 'two']); | |
}); | |
it('a DOM node`s classList object can be converted', function() { | |
const domNode = document.createElement('span'); | |
domNode.classList.add('some'); | |
domNode.classList.add('other'); | |
const classList = Array.from(domNode.classList); | |
assert.equal(''+classList, ''+['some', 'other']); | |
}); | |
it('convert a NodeList to an Array and `filter()` works on it', function() { | |
const nodeList = Array.from(document.createElement('span')); | |
const divs = nodeList.filter((node) => node.tagName === 'div'); | |
assert.deepEqual(divs.length, 0); | |
}); | |
describe('custom conversion using a map function as second param', () => { | |
it('we can modify the value before putting it in the array', function() { | |
const arr = Array.from(arrayLike, (value) => value.toUpperCase()); | |
assert.deepEqual(arr, ['ONE', 'TWO']); | |
}); | |
it('and we also get the object`s key as second parameter', function() { | |
const arr = Array.from(arrayLike, (value, key) => `${key}=${value}`); | |
assert.deepEqual(arr, ['0=one', '1=two']); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 2: template strings - multiline | |
// To do: make all tests pass, leave the asserts unchanged! | |
// Follow the hints of the failure messages! | |
describe('Template string, can contain multiline content', function() { | |
it('wrap it in backticks (`) and add a newline, to span across two lines', function() { | |
var normalString = `line1\n\nline3`; | |
assert.equal(normalString, 'line1\n\nline3'); | |
}); | |
it('even over more than two lines', function() { | |
var multiline = `\n\n\n`; | |
assert.equal(multiline.split('\n').length, 4); | |
}); | |
describe('and expressions inside work too', function() { | |
var x = 42; | |
it('like simple variables', function() { | |
var multiline = `line 1\n\n ${x}`; | |
assert.equal(multiline, 'line 1\n\n 42'); | |
}); | |
it('also here spaces matter', function() { | |
var multiline = `\n\n${x}`; | |
assert.equal(multiline, '\n\n42'); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 30: array - `Array.of` static method | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('`Array.of` creates an array with the given arguments as elements', () => { | |
it('dont mix it up with `Array(10)`, where the argument is the array length', () => { | |
const arr = Array.of(10); | |
assert.deepEqual(arr, [10]); | |
}); | |
it('puts all arguments into array elements', () => { | |
const arr = Array.of(1,2); | |
assert.deepEqual(arr, [1, 2]); | |
}); | |
it('takes any kind and number of arguments', () => { | |
const starter = [1, 2]; | |
const end = [3, '4']; | |
const arr = Array.of([...starter], ...end); | |
assert.deepEqual(arr, [[1, 2], 3, '4']); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 31: array - `Array.prototype.fill` method | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('`Array.prototype.fill` can fill up an array with one value', () => { | |
it('`fill(0)` will populate `0` into each array element', function() { | |
const arr = new Array(3).fill(0); | |
assert.deepEqual(arr, [0, 0, 0]); | |
}); | |
it('fill only changes content, adds no new elements', function() { | |
const arr = [].fill(); | |
assert.deepEqual(arr, []); | |
}); | |
it('second parameter to `fill()` is the position where to start filling', function() { | |
const fillPosition = 2; | |
const arr = [1,2,3].fill(42, fillPosition); | |
assert.deepEqual(arr, [1, 2, 42]); | |
}); | |
it('third parameter is the position where filling stops', function() { | |
const fillStartAt = 1; | |
const fillEndAt = 2; | |
const arr = [1,2,3].fill(42, fillStartAt, fillEndAt); | |
assert.deepEqual(arr, [1, 42, 3]); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 32: array - `Array.prototype.find` | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('`Array.prototype.find` makes finding items in arrays easier', () => { | |
it('takes a compare function', function() { | |
const found = [true].find(el => el === true); | |
assert.equal(found, true); | |
}); | |
it('returns the first value found', function() { | |
const found = [0, 1, 2].find(item => item > 1); | |
assert.equal(found, 2); | |
}); | |
it('returns `undefined` when nothing was found', function() { | |
const found = [1, 2, 3].find(item => item === 23); | |
assert.equal(found, void 0); | |
}); | |
it('combined with destructuring complex compares become short', function() { | |
const bob = {name: 'Bob'}; | |
const alice = {name: 'Alice'}; | |
const found = [bob, alice].find(({name}) => name === 'Alice'); | |
assert.equal(found, alice); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 33: array - `Array.prototype.findIndex` | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('`Array.prototype.findIndex` makes finding items in arrays easier', () => { | |
it('takes a compare function, returns the index where it returned true', function() { | |
const foundAt = [false, true].findIndex(item => item === true); | |
assert.equal(foundAt, 1); | |
}); | |
it('returns the first position it was found at', function() { | |
const foundAt = [0, 1, 1, 1].findIndex(item => item === 1); | |
assert.equal(foundAt, 1); | |
}); | |
it('returns `-1` when nothing was found', function() { | |
const foundAt = [1, 2, 3].findIndex(item => item > 5); | |
assert.equal(foundAt, -1); | |
}); | |
it('the findIndex callback gets the item, index and array as arguments', function() { | |
const three = 3; | |
const containsThree = arr => arr.indexOf(three) > -1; | |
function theSecondThree(item, index, arr) { | |
const preceedingItems = arr.slice(0, index); | |
return containsThree(preceedingItems); | |
} | |
const foundAt = [1, 1, 2, 3, 3, 3].findIndex(theSecondThree); | |
assert.equal(foundAt, 4); | |
}); | |
it('combined with destructuring complex compares become short', function() { | |
const bob = {name: 'Bob'}; | |
const alice = {name: 'Alice'}; | |
const foundAt = [bob, alice].findIndex(({name: {length: l}}) => l > 3); | |
assert.equal(foundAt, 1); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 34: symbol - basics | |
// A symbol is a unique and immutable data type and may be used as an identifier for object properties | |
// read more at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('Symbol', function() { | |
it('`Symbol` lives in the global scope', function(){ | |
const expected = window.Symbol; | |
assert.equal(Symbol, expected); | |
}); | |
it('every `Symbol()` is unique', function(){ | |
const sym1 = Symbol(); | |
const sym2 = Symbol(); | |
assert.notEqual(sym1, sym2); | |
}); | |
it('every `Symbol()` is unique, even with the same parameter', function(){ | |
var sym1 = Symbol('foo'); | |
var sym2 = Symbol('foo'); | |
assert.notEqual(sym1, sym2); | |
}); | |
it('`typeof Symbol()` returns "symbol"', function(){ | |
const theType = typeof(Symbol()); | |
assert.equal(theType, 'symbol'); | |
}); | |
it('`new Symbol()` throws an exception, to prevent creation of Symbol wrapper objects', function(){ | |
function fn() { | |
new Symbol(); | |
} | |
assert.throws(fn); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 35: Symbol.for - retrieves or creates a runtime-wide symbol | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('`Symbol.for` for registering Symbols globally', function() { | |
it('creates a new symbol (check via `typeof`)', function() { | |
const symbolType = typeof Symbol.for('symbol name'); | |
assert.equal(symbolType, 'symbol'); | |
}); | |
it('stores the symbol in a runtime-wide registry and retrieves it from there', function() { | |
const sym = Symbol.for('new symbol'); | |
const sym1 = Symbol.for('new symbol'); | |
assert.equal(sym, sym1); | |
}); | |
it('is different to `Symbol()` which creates a symbol every time and does not store it', function() { | |
var globalSymbol = Symbol.for('new symbol'); | |
var localSymbol = Symbol('new symbol'); | |
assert.notEqual(globalSymbol, localSymbol); | |
}); | |
describe('`.toString()` on a Symbol', function() { | |
it('also contains the key given to `Symbol.for()`', function() { | |
const description = Symbol('new symbol').toString(); | |
assert.equal(description, 'Symbol(new symbol)'); | |
}); | |
describe('NOTE: the description of two different symbols', function() { | |
it('might be the same', function() { | |
const symbol1AsString = Symbol('new symbol').toString(); | |
const symbol2AsString = Symbol.for('new symbol').toString(); | |
assert.equal(symbol1AsString, symbol2AsString); | |
}); | |
it('but the symbols are not the same!', function() { | |
const symbol1 = Symbol('new symbol'); | |
const symbol2 = Symbol.for('new symbol'); | |
assert.notEqual(symbol1, symbol2); | |
}); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 37: iterator/iterable - array. | |
// The iterator protocol defines a standard way to produce a sequence of values (either finite or infinite). | |
// read more at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('The native array is a built-in iterable object', function() { | |
const arr = ['a', 'B', 'see']; | |
describe('the iterator', function() { | |
it('an array has an iterator, which is a function', function() { | |
const iterator = arr[Symbol.iterator]; | |
const theType = typeof iterator; | |
const expected = 'function'; | |
assert.equal(theType, expected); | |
}); | |
it('can be looped with `for-of`, which expects an iterable', function() { | |
let count = 0; | |
for (let value of arr) { | |
count++; | |
} | |
assert.equal(count, arr.length); | |
}); | |
}); | |
describe('the iterator protocol', function() { | |
it('calling `next()` on an iterator returns an object according to the iterator protocol', function() { | |
const iterator = arr[Symbol.iterator](); | |
const firstItem = iterator.next(); | |
assert.deepEqual(firstItem, {done: false, value: 'a'}); | |
}); | |
it('the after-last element has done=true', function() { | |
const arr = []; | |
const iterator = arr[Symbol.iterator](); | |
const afterLast = iterator.next(); | |
assert.deepEqual(afterLast, {done: true, value: void 0}); | |
}); | |
}); | |
}); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 38: iterator/iterable - string. | |
// The iterator protocol defines a standard way to produce a sequence of values (either finite or infinite). | |
// read more at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('The native string is a built-in iterable object', function() { | |
const s = 'abc'; | |
describe('string is iterable', function() { | |
it('the string`s object key `Symbol.iterator` is a function', function() { | |
const isA = typeof s[Symbol.iterator]; | |
assert.equal(isA, 'function'); | |
}); | |
it('use `Array.from()` to make an array out of any iterable', function(){ | |
const arr = Array.from(s); | |
assert.deepEqual(arr, ['a', 'b', 'c']); | |
}); | |
}); | |
describe('a string`s iterator', function() { | |
let iterator; | |
beforeEach(function() { | |
iterator = s[Symbol.iterator](); | |
}); | |
it('has a special string representation', function(){ | |
const description = iterator.toString(); | |
assert.equal(description, '[object String Iterator]'); | |
}); | |
it('`iterator.next()` returns an object according to the iterator protocol', function(){ | |
const value = iterator.next(); | |
assert.deepEqual(value, {done: false, value: 'a'}); | |
}); | |
it('the after-last call to `iterator.next()` says done=true, no more elements', function(){ | |
iterator.next(); | |
iterator.next(); | |
iterator.next(); | |
assert.equal(iterator.next().done, true); | |
}); | |
}); | |
}); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 39: iterator - custom. Iterable is a protocol, when implemented allows objects | |
// to customize their iteration behavior, such as what values are looped over in a for..of construct. | |
// read more at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('A simple iterable without items inside, implementing the right protocol', () => { | |
function iteratorFunction() { | |
return { | |
next: function(){ return { done: true }} | |
} | |
} | |
describe('the `iteratorFunction` needs to comply to the iterator protocol', function() { | |
it('must return an object', function() { | |
assert.equal(typeof iteratorFunction(), 'object'); | |
}); | |
it('the object must have a function assigned to a key `next`', function() { | |
assert.equal(typeof iteratorFunction().next, 'function'); | |
}); | |
it('calling `next()` must return an object with `{done: true}`', function() { | |
assert.deepEqual(iteratorFunction().next(), {done: true}); | |
}); | |
}); | |
let iterable = { | |
[Symbol.iterator]: iteratorFunction | |
}; | |
beforeEach(function() { | |
iterable; | |
}); | |
describe('the iterable', function() { | |
it('must be an object', function() { | |
assert.equal(typeof iterable, 'object'); | |
}); | |
it('must have the iterator function assigned to the key `Symbol.iterator`', function() { | |
assert.equal(iterable[Symbol.iterator], iteratorFunction); | |
}); | |
}); | |
describe('using the iterable', function() { | |
it('it contains no values', function() { | |
let values = ''; | |
for (let value of iterable) { | |
values += value; | |
} | |
assert.equal(values, ''); | |
}); | |
it('has no `.length` property', function() { | |
const hasLengthProperty = iterable.hasOwnProperty('length'); | |
assert.equal(hasLengthProperty, false); | |
}); | |
describe('can be converted to an array', function() { | |
it('using `Array.from()`', function() { | |
const arr = Array.from(iterable); | |
assert.equal(Array.isArray(arr), true); | |
}); | |
it('where `.length` is still 0', function() { | |
const arr = Array.from(iterable); | |
const length = arr.length; | |
assert.equal(length, 0); | |
}); | |
}); | |
}); | |
}); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 3: template strings - tagged | |
// To do: make all tests pass, leave the asserts unchanged! | |
// Follow the hints of the failure messages! | |
describe('Tagged template strings, are an advanced form of template strings', function() { | |
it('syntax: prefix a template string with a function to call (without "()" around it)', function() { | |
function tagFunc(s) { | |
return s.toString(); | |
} | |
var evaluated = tagFunc `template string`; | |
assert.equal(evaluated, 'template string'); | |
}); | |
describe('the tag function can access each part of the template', function() { | |
describe('the 1st parameter receives only the pure strings of the template string', function() { | |
function tagFunction(strings) { | |
return strings; | |
} | |
it('the strings are an array', function() { | |
var result = ['template string']; | |
assert.deepEqual(tagFunction`template string`, result); | |
}); | |
it('expressions are NOT passed to it', function() { | |
var tagged = tagFunction`one${23}two`; | |
assert.deepEqual(tagged, ['one', 'two']); | |
}); | |
}); | |
describe('the 2nd and following parameters contain the values of the processed substitution', function() { | |
var one = 1; | |
var two = 2; | |
var three = 3; | |
it('the 2nd parameter contains the first expression`s value', function() { | |
function firstValueOnly(strings, firstValue) { | |
return firstValue; | |
} | |
assert.equal(firstValueOnly`uno ${one}, dos ${two}`, 1); | |
}); | |
it('the 3rd parameter contains the second expression`s value', function() { | |
function firstValueOnly(strings, firstValue, secondValue) { | |
return secondValue; | |
} | |
assert.equal(firstValueOnly`uno ${one}, dos ${two}`, 2); | |
}); | |
it('using ES6 rest syntax, all values can be accessed via one variable', function() { | |
function valuesOnly(stringsArray, ...allValues) { // using the new ES6 rest syntax | |
return allValues; | |
} | |
assert.deepEqual(valuesOnly`uno=${one}, dos=${two}, tres=${three}`, [1, 2, 3]); | |
}); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 45: Map.prototype.get() | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('`Map.prototype.get` returns the element from the map for a key', function(){ | |
it('`get(key)` returns the value stored for this key', function() { | |
let map = new Map(); | |
map.set('key', 'value'); | |
const value = map.get('key'); | |
assert.equal(value, 'value'); | |
}); | |
it('multiple calls still return the same value', function() { | |
let map = new Map(); | |
map.set('value', 'value'); | |
var value = map.get(map.get(map.get('value'))); | |
assert.equal(value, 'value'); | |
}); | |
it('requires exactly the value as passed to `set()`', function() { | |
let map = new Map(); | |
const obj = {}; | |
map.set(obj, 'object is key'); | |
assert.equal(map.get(obj), 'object is key'); | |
}); | |
it('leave out the key, and you get the value set for the key `undefined` (void 0)', function() { | |
let map = new Map(); | |
map.set(void 0, 'yo'); | |
const value = map.get(); | |
assert.equal(value, 'yo'); | |
}); | |
it('returns undefined for an unknown key', function() { | |
let map = new Map(); | |
map.set(void 0, 1); | |
const value = map.get('unknown'); | |
assert.equal(value, void 0); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 46: Map.prototype.set() | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('`Map.prototype.set` adds a new element with key and value to a Map', function(){ | |
it('simplest use case is `set(key, value)` and `get(key)`', function() { | |
let map = new Map(); | |
map.set('key','value'); | |
assert.equal(map.get('key'), 'value'); | |
}); | |
it('the key can be a complex type too', function() { | |
const noop = function() {}; | |
let map = new Map(); | |
map.set(noop, 'the real noop'); | |
assert.equal(map.get(noop), 'the real noop'); | |
}); | |
it('calling `set()` again with the same key replaces the value', function() { | |
let map = new Map(); | |
map.set('key', 'value'); | |
map.set('key', 'value1'); | |
assert.equal(map.get('key'), 'value1'); | |
}); | |
it('`set()` returns the map object, it`s chainable', function() { | |
let map = new Map(); | |
map.set(1, 'one') | |
.set(2, 'two') | |
.set(3, 'three') | |
; | |
assert.deepEqual([...map.keys()], [1,2,3]); | |
assert.deepEqual([...map.values()], ['one', 'two', 'three']); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 4: template strings - String.raw | |
// To do: make all tests pass, leave the asserts unchanged! | |
// Follow the hints of the failure messages! | |
describe('Use the `raw` property of tagged template strings like so `s.raw`', function() { | |
it('the `raw` property accesses the string as it was entered', function() { | |
function firstChar(strings) { | |
return strings.raw; | |
} | |
assert.equal(firstChar`\n`, '\\n'); | |
}); | |
it('`raw` can access the backslash of a line-break', function() { | |
function firstCharEntered(strings) { | |
var lineBreak = strings.raw; | |
return lineBreak; | |
} | |
assert.equal(firstCharEntered`\n`, '\\n'); | |
}); | |
describe('`String.raw` as a static function', function(){ | |
it('concats the raw strings', function() { | |
var expected = '\\n'; | |
assert.equal(String.raw`\n`, expected); | |
}); | |
it('two raw-templates-string-backslashes equal two escaped backslashes', function() { | |
const TWO_BACKSLASHES = '\\\\'; | |
assert.equal(String.raw`\\`, TWO_BACKSLASHES); | |
}); | |
it('works on unicodes too', function() { | |
var smilie = '\u{1F600}'; | |
var actual = String`\u{1F600}`; | |
assert.equal(actual, smilie); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 5: arrow functions - basics | |
// To do: make all tests pass, leave the asserts unchanged! | |
// Follow the hints of the failure messages! | |
describe('Arrow functions', function() { | |
it('are shorter to write, instead of `function(){}` write `() => {}`', function() { | |
var func = () => '() => {}'; | |
assert.equal('' + func(), '() => {}'); | |
}); | |
it('instead `{}` use an expression, as return value', function() { | |
var func = () => 'I return too'; | |
assert.equal(func(), 'I return too'); | |
}); | |
it('one parameter can be written without parens', () => { | |
var func = p => p - 1; | |
assert.equal(func(25), 24); | |
}); | |
it('many params require parens', () => { | |
var func = (param, param1) => param + param1; | |
assert.equal(func(23, 42), 23+42); | |
}); | |
it('the function body needs parens to return an object', () => { | |
var func = () => {return{iAm: 'an object'}}; | |
assert.deepEqual(func(), {iAm: 'an object'}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 6: arrow functions - binding | |
// To do: make all tests pass, leave the asserts unchanged! | |
// Follow the hints of the failure messages! | |
class LexicallyBound { | |
getFunction() { | |
return () => { | |
// return this returns that object from memory instead of a new LexicallyBound class obj | |
return this; | |
} | |
} | |
getArgumentsFunction() { | |
return () => {return arguments} | |
} | |
} | |
describe('Arrow functions have lexical `this`, no dynamic `this`', () => { | |
it('bound at definition time, use `=>`', function() { | |
var bound = new LexicallyBound(); | |
var fn = bound.getFunction(); | |
assert.strictEqual(fn(), bound); | |
}); | |
it('can NOT bind a different context', function() { | |
var bound = new LexicallyBound(); | |
var fn = bound.getFunction(); | |
var anotherObj = {}; | |
// expected = bound or a new LexicallyBound obj and fn.call(anotherObj) returns the same | |
var expected = bound; | |
assert.strictEqual(fn.call(anotherObj), expected); | |
}); | |
it('`arguments` does NOT work inside arrow functions', function() { | |
var bound = new LexicallyBound(); | |
var fn = bound.getArgumentsFunction(); | |
assert.equal(fn(1, 2).length, 0); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 7: block scope - let | |
// To do: make all tests pass, leave the asserts unchanged! | |
// Follow the hints of the failure messages! | |
describe('`let` restricts the scope of the variable to the current block', () => { | |
describe('`let` vs. `var`', () => { | |
it('`var` works as usual, it`s scope is the function', () => { | |
if (true) { | |
var varX = true; | |
} | |
assert.equal(varX, true); | |
}); | |
it('`let` restricts scope to inside the block', () => { | |
if (true) { | |
let letX = true; | |
} | |
assert.throws(() => console.log(letX)); | |
}); | |
}); | |
describe('`let` usage', () => { | |
it('`let` use in `for` loops', () => { | |
let obj = {x: 1}; | |
for (let key in obj) {} | |
assert.throws(() => console.log(key)); | |
}); | |
it('create artifical scope, using curly braces', () => { | |
{ | |
let letX = true; | |
} | |
assert.throws(() => console.log(letX)); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 8: block scope - const | |
// To do: make all tests pass, leave the asserts unchanged! | |
// Follow the hints of the failure messages! | |
describe('`const` is like `let` plus read-only', () => { | |
describe('scalar values are read-only', () => { | |
it('e.g. a number', () => { | |
const constNum = 0; | |
// constNum = 1; | |
assert.equal(constNum, 0); | |
}); | |
it('or a string', () => { | |
const constString = 'I am a const'; | |
// constString = 'Cant change you?'; | |
assert.equal(constString, 'I am a const'); | |
}); | |
}); | |
const notChangeable = 23; | |
it('const scope leaks too', () => { | |
assert.equal(notChangeable, 23); | |
}); | |
describe('complex types are NOT fully read-only', () => { | |
it('array`s items can be changed', () => { | |
const arr = []; | |
arr[0] = 42; | |
assert.equal(arr[0], 42); | |
}); | |
it('object`s can be modified', () => { | |
const obj = {x: 1}; | |
obj.x = 3; | |
assert.equal(obj.x, 3); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 9: object-literals - basics | |
// To do: make all tests pass, leave the assert lines unchanged! | |
// Follow the hints of the failure messages! | |
describe('The object literal allows for new shorthands', () => { | |
const x = 1; | |
const y = 2; | |
describe('with variables', () => { | |
it('the short version for `{x: x}` is {x}', () => { | |
const short = {y}; | |
assert.deepEqual(short, {y: y}); | |
}); | |
it('works with multiple variables too', () => { | |
const short = {x, y}; | |
assert.deepEqual(short, {x: x, y: y}); | |
}); | |
}); | |
describe('with methods', () => { | |
const func = () => func; | |
it('using the name only uses it as key', () => { | |
const short = {func}; | |
assert.deepEqual(short, {func: func}); | |
}); | |
it('a different key must be given explicitly, just like before ES6', () => { | |
const short = {otherKey: func}; | |
assert.deepEqual(short, {otherKey: func}); | |
}); | |
it('inline functions, can written as `obj={func(){}}` instead of `obj={func:function(){}}`', () => { | |
const short = { | |
inlineFunc: () => 'I am inline' | |
}; | |
assert.deepEqual(short.inlineFunc(), 'I am inline'); | |
}); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment