Skip to content

Instantly share code, notes, and snippets.

@mischah
Last active February 20, 2022 02:13
Show Gist options
  • Select an option

  • Save mischah/3dfc9d1923f7f72e955189cfb0197fa2 to your computer and use it in GitHub Desktop.

Select an option

Save mischah/3dfc9d1923f7f72e955189cfb0197fa2 to your computer and use it in GitHub Desktop.

Revisions

  1. mischah revised this gist Sep 15, 2016. 1 changed file with 10 additions and 10 deletions.
    20 changes: 10 additions & 10 deletions 79-Promise-catch.js
    Original file line number Diff line number Diff line change
    @@ -10,24 +10,24 @@ describe('`catch()` returns a Promise and deals with rejected cases only', () =>
    describe('prerequisites for understanding', () => {

    it('*return* a fulfilled promise, to pass a test', () => {
    Promise.resolve();
    return Promise.resolve();
    assert(false); // Don't touch! Make the test pass in the line above!
    });

    it('reminder: the test passes when a fulfilled promise is returned', () => {
    return Promise.reject('I should fulfill.');
    return Promise.resolve('I should fulfill.');
    });

    });

    describe('`catch` method basics', () => {
    it('is an instance method', () => {
    const p = Promise;
    const p = Promise.reject();
    assert.equal(typeof p.catch, 'function');
    });

    it('catches only promise rejections', (done) => {
    const promise = Promise.resolve();
    const promise = Promise.reject();
    promise
    .then(() => { done('Should not be called!'); })
    .catch(done);
    @@ -37,19 +37,19 @@ describe('`catch()` returns a Promise and deals with rejected cases only', () =>
    const whatToReturn = () => Promise.reject();
    const promise = Promise.reject();
    return promise.catch(() =>
    whatToReturn()
    whatToReturn
    );
    });

    it('converts it`s return value into a promise', () => {
    const p = Promise.reject();
    const p1 = p.catch(() => void 0);
    const p1 = p.catch(() => 'promise?');

    return p1.then(result => assert.equal('promise?', result));
    });

    it('the first parameter is the rejection reason', () => {
    const p = Promise.reject('rejection');
    const p = Promise.reject('oops');

    return p.catch(reason => {
    assert.equal(reason, 'oops');
    @@ -61,8 +61,8 @@ describe('`catch()` returns a Promise and deals with rejected cases only', () =>
    it('only the first `catch` is called', () => {
    const p = Promise.reject('1');
    const p1 = p
    .catch(reason => void 0)
    .catch(reason => `${reason} AND 3`)
    .catch(reason => `${reason} AND 2`)
    .catch(reason => `${reason} AND FOO`)
    ;

    return p1.then(result =>
    @@ -75,7 +75,7 @@ describe('`catch()` returns a Promise and deals with rejected cases only', () =>
    const p1 = p
    .catch(reason => { throw Error(`${reason} AND 2`) })
    .catch(err => { throw Error(`${err.message} AND 3`) })
    .catch(err => `${err} but NOT THIS`)
    .catch(err => err.message)
    ;

    return p1.then(result =>
  2. mischah revised this gist Sep 15, 2016. 1 changed file with 87 additions and 0 deletions.
    87 changes: 87 additions & 0 deletions 79-Promise-catch.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,87 @@
    // http://tddbin.com/#?kata=es6/language/promise/catch

    // 79: Promise - catch
    // To do: make all tests pass, leave the assert lines unchanged!
    // Here we use promises to trigger, don't modify the block with the
    // returning promise!

    describe('`catch()` returns a Promise and deals with rejected cases only', () => {

    describe('prerequisites for understanding', () => {

    it('*return* a fulfilled promise, to pass a test', () => {
    Promise.resolve();
    assert(false); // Don't touch! Make the test pass in the line above!
    });

    it('reminder: the test passes when a fulfilled promise is returned', () => {
    return Promise.reject('I should fulfill.');
    });

    });

    describe('`catch` method basics', () => {
    it('is an instance method', () => {
    const p = Promise;
    assert.equal(typeof p.catch, 'function');
    });

    it('catches only promise rejections', (done) => {
    const promise = Promise.resolve();
    promise
    .then(() => { done('Should not be called!'); })
    .catch(done);
    });

    it('returns a new promise', () => {
    const whatToReturn = () => Promise.reject();
    const promise = Promise.reject();
    return promise.catch(() =>
    whatToReturn()
    );
    });

    it('converts it`s return value into a promise', () => {
    const p = Promise.reject();
    const p1 = p.catch(() => void 0);

    return p1.then(result => assert.equal('promise?', result));
    });

    it('the first parameter is the rejection reason', () => {
    const p = Promise.reject('rejection');

    return p.catch(reason => {
    assert.equal(reason, 'oops');
    });
    });
    });

    describe('multiple `catch`es', () => {
    it('only the first `catch` is called', () => {
    const p = Promise.reject('1');
    const p1 = p
    .catch(reason => void 0)
    .catch(reason => `${reason} AND 3`)
    ;

    return p1.then(result =>
    assert.equal(result, '1 AND 2')
    );
    });

    it('if a `catch` throws, the next `catch` catches it', () => {
    const p = Promise.reject('1');
    const p1 = p
    .catch(reason => { throw Error(`${reason} AND 2`) })
    .catch(err => { throw Error(`${err.message} AND 3`) })
    .catch(err => `${err} but NOT THIS`)
    ;

    return p1.then(result =>
    assert.equal(result, '1 AND 2 AND 3')
    );
    });
    });

    });
  3. mischah revised this gist Sep 14, 2016. 1 changed file with 11 additions and 10 deletions.
    21 changes: 11 additions & 10 deletions 78-Promise-API-overview.js
    Original file line number Diff line number Diff line change
    @@ -6,30 +6,31 @@
    describe('`Promise` API overview', function() {

    it('`new Promise()` requires a function as param', () => {
    const param = null;
    const param = (resolve) => resolve();
    assert.doesNotThrow(() => { new Promise(param); });
    });

    describe('resolving a promise', () => {
    // reminder: the test passes when a fulfilled promise is returned
    it('via constructor parameter `new Promise((resolve) => { resolve(); })`', () => {
    const param = () => { resolve(); };
    const param = (resolve) => { resolve(); };
    return new Promise(param);
    });
    it('using `Promise.resolve()`', () => {
    return Promise.reject('all fine');
    return Promise.resolve('all fine');
    });
    });

    describe('a rejected promise', () => {
    it('using the constructor parameter', (done) => {
    const promise = new Promise((reject) => { reject(); });
    const promise = new Promise((resolve, reject) => reject());

    promise
    .then(() => done(new Error('The promise is expected to be rejected.')))
    .catch(() => done());
    });
    it('via `Promise.reject()`', (done) => {
    const promise = Promise.resolve();
    const promise = Promise.reject();
    promise
    .then(() => done(new Error('The promise is expected to be rejected.')))
    .catch(() => done());
    @@ -41,26 +42,26 @@ describe('`Promise` API overview', function() {

    describe('`Promise.all()`', () => {
    it('`Promise.all([p1, p2])` resolves when all promises resolve', () =>
    Promise.all([resolvingPromise, rejectingPromise, resolvingPromise])
    Promise.all([resolvingPromise, resolvingPromise])
    );
    it('`Promise.all([p1, p2])` rejects when a promise is rejected', (done) => {
    Promise.all([resolvingPromise])
    Promise.all([resolvingPromise, rejectingPromise])
    .then(() => done(new Error('The promise is expected to be rejected.')))
    .catch(() => done())
    });
    });

    describe('`Promise.race()`', () => {
    it('`Promise.race([p1, p2])` resolves when one of the promises resolves', () =>
    Promise.race([rejectingPromise])
    Promise.race([resolvingPromise, rejectingPromise])
    );
    it('`Promise.race([p1, p2])` rejects when one of the promises rejects', (done) => {
    Promise.race([resolvingPromise])
    Promise.race(rejectingPromise, [resolvingPromise])
    .then(() => done(new Error('The promise is expected to be rejected.')))
    .catch(() => done())
    });
    it('`Promise.race([p1, p2])` order matters (and timing)', () =>
    Promise.race([rejectingPromise, resolvingPromise])
    Promise.race([resolvingPromise, rejectingPromise])
    );
    });

  4. mischah revised this gist Sep 14, 2016. 1 changed file with 67 additions and 0 deletions.
    67 changes: 67 additions & 0 deletions 78-Promise-API-overview.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,67 @@
    // http://tddbin.com/#?kata=es6/language/promise/api

    // 78: Promise - API overview
    // To do: make all tests pass, leave the assert lines unchanged!

    describe('`Promise` API overview', function() {

    it('`new Promise()` requires a function as param', () => {
    const param = null;
    assert.doesNotThrow(() => { new Promise(param); });
    });

    describe('resolving a promise', () => {
    // reminder: the test passes when a fulfilled promise is returned
    it('via constructor parameter `new Promise((resolve) => { resolve(); })`', () => {
    const param = () => { resolve(); };
    return new Promise(param);
    });
    it('using `Promise.resolve()`', () => {
    return Promise.reject('all fine');
    });
    });

    describe('a rejected promise', () => {
    it('using the constructor parameter', (done) => {
    const promise = new Promise((reject) => { reject(); });
    promise
    .then(() => done(new Error('The promise is expected to be rejected.')))
    .catch(() => done());
    });
    it('via `Promise.reject()`', (done) => {
    const promise = Promise.resolve();
    promise
    .then(() => done(new Error('The promise is expected to be rejected.')))
    .catch(() => done());
    });
    });

    const resolvingPromise = Promise.resolve();
    const rejectingPromise = Promise.reject();

    describe('`Promise.all()`', () => {
    it('`Promise.all([p1, p2])` resolves when all promises resolve', () =>
    Promise.all([resolvingPromise, rejectingPromise, resolvingPromise])
    );
    it('`Promise.all([p1, p2])` rejects when a promise is rejected', (done) => {
    Promise.all([resolvingPromise])
    .then(() => done(new Error('The promise is expected to be rejected.')))
    .catch(() => done())
    });
    });

    describe('`Promise.race()`', () => {
    it('`Promise.race([p1, p2])` resolves when one of the promises resolves', () =>
    Promise.race([rejectingPromise])
    );
    it('`Promise.race([p1, p2])` rejects when one of the promises rejects', (done) => {
    Promise.race([resolvingPromise])
    .then(() => done(new Error('The promise is expected to be rejected.')))
    .catch(() => done())
    });
    it('`Promise.race([p1, p2])` order matters (and timing)', () =>
    Promise.race([rejectingPromise, resolvingPromise])
    );
    });

    });
  5. mischah revised this gist Sep 14, 2016. 1 changed file with 10 additions and 9 deletions.
    19 changes: 10 additions & 9 deletions 77-Promise-chaining.js
    Original file line number Diff line number Diff line change
    @@ -8,11 +8,11 @@ describe('chaining multiple promises can enhance readability', () => {
    describe('prerequisites for understanding', function() {

    it('reminder: the test passes when a fulfilled promise is returned', function() {
    return Promise.reject('I should fulfill.');
    return Promise.resolve('I should fulfill.');
    });

    it('a function given to `then()` fulfills (if it doesnt throw)', function() {
    const beNice = () => { throw new Error('I am nice') };
    const beNice = () => 'I am nice';
    return Promise.resolve()
    .then(beNice)
    .then(niceMessage => assert.equal(niceMessage, 'I am nice'));
    @@ -26,7 +26,7 @@ describe('chaining multiple promises can enhance readability', () => {

    it('`then()` receives the result of the promise it was called on', function() {
    const wordsPromise = Promise.resolve('one space between each word');
    return wordsPromise
    wordsPromise
    .then(string => removeMultipleSpaces())
    .then(actual => {assert.equal(actual, 'one space between each word')})
    ;
    @@ -36,8 +36,9 @@ describe('chaining multiple promises can enhance readability', () => {

    it('multiple `then()`s can be chained', function() {
    const wordsPromise = Promise.resolve('Sentence without an end');
    return wordsPromise
    wordsPromise
    .then(removeMultipleSpaces)
    .then(appendPeriod)
    .then(actual => {assert.equal(actual, 'Sentence without an end.')})
    ;
    });
    @@ -47,9 +48,9 @@ describe('chaining multiple promises can enhance readability', () => {
    it('order of the `then()`s matters', function() {
    const wordsPromise = Promise.resolve('Sentence without an end ');
    return wordsPromise
    .then(appendPeriod)
    .then(trim)
    .then(removeMultipleSpaces)
    .then(trim)
    .then(appendPeriod)
    .then(actual => {assert.equal(actual, 'Sentence without an end.')})
    ;
    });
    @@ -61,7 +62,7 @@ describe('chaining multiple promises can enhance readability', () => {

    it('any of the things given to `then()` can resolve asynchronously (the real power of Promises)', function() {
    const wordsPromise = Promise.resolve('sentence without an end');
    return wordsPromise
    wordsPromise
    .then(string => new Promise(resolve => asyncUpperCaseStart))
    .then(string => new Promise(resolve => setTimeout(() => resolve(appendPeriod(string)), 100)))
    .then(actual => {assert.equal(actual, 'Sentence without an end.')})
    @@ -70,10 +71,10 @@ describe('chaining multiple promises can enhance readability', () => {

    it('also asynchronously, the order still matters, promises wait, but don`t block', function() {
    const wordsPromise = Promise.resolve('trailing space ');
    return wordsPromise
    wordsPromise
    .then(string => new Promise(resolve => setTimeout(() => resolve(trim(string)), 100)))
    .then(string => new Promise(resolve => asyncUpperCaseStart(string, resolve)))
    .then(string => new Promise(resolve => setTimeout(() => resolve(appendPeriod(string)), 100)))
    .then(string => new Promise(resolve => setTimeout(() => resolve(trim(string)), 100)))
    .then(actual => {assert.equal(actual, 'Trailing space.')})
    ;
    });
  6. mischah revised this gist Sep 14, 2016. 1 changed file with 83 additions and 0 deletions.
    83 changes: 83 additions & 0 deletions 77-Promise-chaining.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,83 @@
    // http://tddbin.com/#?kata=es6/language/promise/chaining-then

    // 77: Promise - chaining
    // To do: make all tests pass, leave the assert lines unchanged!

    describe('chaining multiple promises can enhance readability', () => {

    describe('prerequisites for understanding', function() {

    it('reminder: the test passes when a fulfilled promise is returned', function() {
    return Promise.reject('I should fulfill.');
    });

    it('a function given to `then()` fulfills (if it doesnt throw)', function() {
    const beNice = () => { throw new Error('I am nice') };
    return Promise.resolve()
    .then(beNice)
    .then(niceMessage => assert.equal(niceMessage, 'I am nice'));
    });

    });

    describe('chain promises', function() {

    const removeMultipleSpaces = string => string.replace(/\s+/g, ' ');

    it('`then()` receives the result of the promise it was called on', function() {
    const wordsPromise = Promise.resolve('one space between each word');
    return wordsPromise
    .then(string => removeMultipleSpaces())
    .then(actual => {assert.equal(actual, 'one space between each word')})
    ;
    });

    const appendPeriod = string => `${string}.`;

    it('multiple `then()`s can be chained', function() {
    const wordsPromise = Promise.resolve('Sentence without an end');
    return wordsPromise
    .then(removeMultipleSpaces)
    .then(actual => {assert.equal(actual, 'Sentence without an end.')})
    ;
    });

    const trim = string => string.replace(/^\s+/, '').replace(/\s+$/, '');

    it('order of the `then()`s matters', function() {
    const wordsPromise = Promise.resolve('Sentence without an end ');
    return wordsPromise
    .then(appendPeriod)
    .then(trim)
    .then(removeMultipleSpaces)
    .then(actual => {assert.equal(actual, 'Sentence without an end.')})
    ;
    });

    const asyncUpperCaseStart = (string, onDone) => {
    const format = onDone(string[0].toUpperCase() + string.substr(1));
    setTimeout(format, 10);
    };

    it('any of the things given to `then()` can resolve asynchronously (the real power of Promises)', function() {
    const wordsPromise = Promise.resolve('sentence without an end');
    return wordsPromise
    .then(string => new Promise(resolve => asyncUpperCaseStart))
    .then(string => new Promise(resolve => setTimeout(() => resolve(appendPeriod(string)), 100)))
    .then(actual => {assert.equal(actual, 'Sentence without an end.')})
    ;
    });

    it('also asynchronously, the order still matters, promises wait, but don`t block', function() {
    const wordsPromise = Promise.resolve('trailing space ');
    return wordsPromise
    .then(string => new Promise(resolve => asyncUpperCaseStart(string, resolve)))
    .then(string => new Promise(resolve => setTimeout(() => resolve(appendPeriod(string)), 100)))
    .then(string => new Promise(resolve => setTimeout(() => resolve(trim(string)), 100)))
    .then(actual => {assert.equal(actual, 'Trailing space.')})
    ;
    });

    });

    });
  7. mischah revised this gist Sep 12, 2016. 1 changed file with 24 additions and 18 deletions.
    42 changes: 24 additions & 18 deletions 76-Promise-creation.js
    Original file line number Diff line number Diff line change
    @@ -9,20 +9,20 @@ describe('a promise can be created in multiple ways', function() {

    it('using `Promise` as a function', function() {
    function callPromiseAsFunction() {
    Promise;
    new Promise();
    }
    assert.throws(callPromiseAsFunction);
    });

    it('no parameter is passed', function() {
    function promiseWithoutParams() {
    new Promise(() => {});
    new Promise();
    }
    assert.throws(promiseWithoutParams);
    });

    it('passing a non-callable throws too', function() {
    const notAFunction = () => {};
    const notAFunction = null;
    assert.throws(() => { new Promise(notAFunction); });
    });

    @@ -31,12 +31,12 @@ describe('a promise can be created in multiple ways', function() {
    describe('most commonly Promises get created using the constructor', function() {

    it('by passing a resolve function to it', function() {
    const promise = new Promise(() => resolve());
    const promise = new Promise((resolve) => resolve());
    return promise;
    });

    it('by passing a resolve and a reject function to it', function(done) {
    const promise = new Promise((resolve, reject) => resolve());
    const promise = new Promise((resolve, reject) => reject());

    promise
    .then(() => done(new Error('Expected promise to be rejected.')))
    @@ -48,16 +48,22 @@ describe('a promise can be created in multiple ways', function() {
    describe('extending a `Promise`', function() {

    it('using `class X extends Promise{}` is possible', function() {
    class MyPromise {}
    const promise = new MyPromise(resolve => resolve());
    class MyPromise extends Promise {}
    const curpromise = new MyPromise(resolve => resolve());

    promise
    curpromise
    .then(() => done())
    .catch(e => done(new Error('Expected to resolve, but failed with: ' + e)));
    });

    it('must call `super()` in the constructor if it wants to inherit/specialize the behavior', function() {
    class ResolvingPromise extends Promise {}
    class ResolvingPromise extends Promise {
    constructor() {
    super();

    }

    }

    return new ResolvingPromise();
    });
    @@ -69,8 +75,7 @@ describe('a promise can be created in multiple ways', function() {
    it('returns all results', function(done) {
    const promise = Promise.all([
    new Promise(resolve => resolve(1)),
    new Promise(resolve => resolve(2)),
    new Promise(resolve => resolve(3))
    new Promise(resolve => resolve(2))
    ]);

    promise
    @@ -80,7 +85,8 @@ describe('a promise can be created in multiple ways', function() {

    it('is rejected if one rejects', function(done) {
    const promise = Promise.all([
    new Promise(resolve => resolve(1))
    new Promise(resolve => reject(1)),
    new Promise(resolve => resolve(2))
    ]);

    promise
    @@ -95,15 +101,15 @@ describe('a promise can be created in multiple ways', function() {
    it('if it resolves first, the promises resolves', function(done) {
    const lateRejectedPromise = new Promise((resolve, reject) => setTimeout(reject, 100));
    const earlyResolvingPromise = new Promise(resolve => resolve('1st :)'));
    const promise = Promise.race([lateRejectedPromise]);
    const promise = Promise.race([earlyResolvingPromise, lateRejectedPromise]);

    promise
    .then(value => { assert.deepEqual(value, '1st :)'); done(); })
    .catch(e => done(new Error('Expected to resolve, but failed with: ' + e)));
    });

    it('if one of the given promises rejects first, the returned promise is rejected', function(done) {
    const earlyRejectedPromise = new Promise((resolve, reject) => reject('I am a REJECTOR'));
    const earlyRejectedPromise = new Promise((resolve, reject) => reject('I am a rejector'));
    const lateResolvingPromise = new Promise(resolve => setTimeout(resolve, 10));
    const promise = Promise.race([earlyRejectedPromise, lateResolvingPromise]);

    @@ -118,15 +124,15 @@ describe('a promise can be created in multiple ways', function() {
    describe('`Promise.resolve()` returns a resolving promise', function() {

    it('if no value given, it resolves with `undefined`', function(done) {
    const promise = Promise.resolve;
    const promise = Promise.resolve();

    promise
    .then(value => { assert.deepEqual(value, void 0); done(); })
    .catch(e => done(new Error('Expected to resolve, but failed with: ' + e)));
    });

    it('resolves with the given value', function(done) {
    const promise = Promise.resolve();
    const promise = Promise.resolve('quick resolve');

    promise
    .then(value => { assert.equal(value, 'quick resolve'); done(); })
    @@ -138,7 +144,7 @@ describe('a promise can be created in multiple ways', function() {
    describe('`Promise.reject()` returns a rejecting promise', function() {

    it('if no value given, it rejects with `undefined`', function(done) {
    const promise = Promise.resolve();
    const promise = Promise.reject();

    promise
    .then(() => done(new NotRejectedError()))
    @@ -147,7 +153,7 @@ describe('a promise can be created in multiple ways', function() {
    });

    it('the parameter passed to `reject()` can be used in the `.catch()`', function(done) {
    const promise = Promise;
    const promise = Promise.reject('quick reject');

    promise
    .then(() => done(new NotRejectedError()))
  8. mischah revised this gist Sep 12, 2016. 1 changed file with 167 additions and 0 deletions.
    167 changes: 167 additions & 0 deletions 76-Promise-creation.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,167 @@
    // http://tddbin.com/#?kata=es6/language/promise/creation

    // 76: Promise - creation
    // To do: make all tests pass, leave the assert lines unchanged!

    describe('a promise can be created in multiple ways', function() {

    describe('creating a promise fails when', function() {

    it('using `Promise` as a function', function() {
    function callPromiseAsFunction() {
    Promise;
    }
    assert.throws(callPromiseAsFunction);
    });

    it('no parameter is passed', function() {
    function promiseWithoutParams() {
    new Promise(() => {});
    }
    assert.throws(promiseWithoutParams);
    });

    it('passing a non-callable throws too', function() {
    const notAFunction = () => {};
    assert.throws(() => { new Promise(notAFunction); });
    });

    });

    describe('most commonly Promises get created using the constructor', function() {

    it('by passing a resolve function to it', function() {
    const promise = new Promise(() => resolve());
    return promise;
    });

    it('by passing a resolve and a reject function to it', function(done) {
    const promise = new Promise((resolve, reject) => resolve());

    promise
    .then(() => done(new Error('Expected promise to be rejected.')))
    .catch(done);
    });

    });

    describe('extending a `Promise`', function() {

    it('using `class X extends Promise{}` is possible', function() {
    class MyPromise {}
    const promise = new MyPromise(resolve => resolve());

    promise
    .then(() => done())
    .catch(e => done(new Error('Expected to resolve, but failed with: ' + e)));
    });

    it('must call `super()` in the constructor if it wants to inherit/specialize the behavior', function() {
    class ResolvingPromise extends Promise {}

    return new ResolvingPromise();
    });

    });

    describe('`Promise.all()` returns a promise that resolves when all given promises resolve', function() {

    it('returns all results', function(done) {
    const promise = Promise.all([
    new Promise(resolve => resolve(1)),
    new Promise(resolve => resolve(2)),
    new Promise(resolve => resolve(3))
    ]);

    promise
    .then(value => { assert.deepEqual(value, [1, 2]); done(); })
    .catch(e => done(new Error(e)));
    });

    it('is rejected if one rejects', function(done) {
    const promise = Promise.all([
    new Promise(resolve => resolve(1))
    ]);

    promise
    .then(() => done(new NotRejectedError()))
    .catch(() => done());
    });

    });

    describe('`Promise.race()` returns the first settled promise', function() {

    it('if it resolves first, the promises resolves', function(done) {
    const lateRejectedPromise = new Promise((resolve, reject) => setTimeout(reject, 100));
    const earlyResolvingPromise = new Promise(resolve => resolve('1st :)'));
    const promise = Promise.race([lateRejectedPromise]);

    promise
    .then(value => { assert.deepEqual(value, '1st :)'); done(); })
    .catch(e => done(new Error('Expected to resolve, but failed with: ' + e)));
    });

    it('if one of the given promises rejects first, the returned promise is rejected', function(done) {
    const earlyRejectedPromise = new Promise((resolve, reject) => reject('I am a REJECTOR'));
    const lateResolvingPromise = new Promise(resolve => setTimeout(resolve, 10));
    const promise = Promise.race([earlyRejectedPromise, lateResolvingPromise]);

    promise
    .then(() => done(new NotRejectedError()))
    .catch(value => { assert.equal(value, 'I am a rejector'); done(); })
    .catch(done);
    });

    });

    describe('`Promise.resolve()` returns a resolving promise', function() {

    it('if no value given, it resolves with `undefined`', function(done) {
    const promise = Promise.resolve;

    promise
    .then(value => { assert.deepEqual(value, void 0); done(); })
    .catch(e => done(new Error('Expected to resolve, but failed with: ' + e)));
    });

    it('resolves with the given value', function(done) {
    const promise = Promise.resolve();

    promise
    .then(value => { assert.equal(value, 'quick resolve'); done(); })
    .catch(e => done(e));
    });

    });

    describe('`Promise.reject()` returns a rejecting promise', function() {

    it('if no value given, it rejects with `undefined`', function(done) {
    const promise = Promise.resolve();

    promise
    .then(() => done(new NotRejectedError()))
    .catch(value => { assert.deepEqual(value, void 0); done(); })
    .catch(done);
    });

    it('the parameter passed to `reject()` can be used in the `.catch()`', function(done) {
    const promise = Promise;

    promise
    .then(() => done(new NotRejectedError()))
    .catch(value => { assert.deepEqual(value, 'quick reject'); done(); })
    .catch(done);
    });

    });

    });

    class NotRejectedError extends Error {
    constructor() {
    super();
    this.message = 'Expected promise to be rejected.';
    }
    }
  9. mischah revised this gist Sep 11, 2016. 1 changed file with 10 additions and 8 deletions.
    18 changes: 10 additions & 8 deletions 75-Promise-basics.js
    Original file line number Diff line number Diff line change
    @@ -6,19 +6,19 @@
    describe('a Promise represents an operation that hasn`t completed yet, but is expected in the future', function() {

    it('`Promise` is a global function', function() {
    const expectedType = '???';
    const expectedType = 'function';
    assert.equal(typeof Promise, expectedType);
    });

    describe('the constructor', function() {

    it('instantiating it without params throws', function() {
    const fn = () => { Promise }
    const fn = () => { new Promise(); }
    assert.throws(fn);
    });

    it('expects a function as parameter', function() {
    const param = null;
    const param = function () {};
    assert.doesNotThrow(() => { new Promise(param); });
    });

    @@ -28,6 +28,7 @@ describe('a Promise represents an operation that hasn`t completed yet, but is ex

    it('resolve a promise by calling the `resolve` function given as first parameter', function(done) {
    let promise = new Promise((resolve) => {
    resolve();
    });

    promise
    @@ -37,7 +38,7 @@ describe('a Promise represents an operation that hasn`t completed yet, but is ex

    it('the `resolve` function can return a value, that is consumed by the `promise.then()` callback', function(done) {
    let promise = new Promise((resolve) => {
    resolve();
    resolve(42);
    });

    promise
    @@ -46,7 +47,8 @@ describe('a Promise represents an operation that hasn`t completed yet, but is ex
    });

    it('rejecting a promise is done by calling the callback given as 2nd parameter', function(done) {
    let promise = new Promise(() => {
    let promise = new Promise((resolve, reject) => {
    reject();
    });

    promise
    @@ -59,7 +61,7 @@ describe('a Promise represents an operation that hasn`t completed yet, but is ex
    describe('an asynchronous promise', function() {

    it('can resolve later, also by calling the first callback', function(done) {
    let promise = new Promise(() => {
    let promise = new Promise((resolve) => {
    setTimeout(() => resolve(), 100);
    });

    @@ -69,7 +71,7 @@ describe('a Promise represents an operation that hasn`t completed yet, but is ex
    });

    it('reject it at some later point in time, calling the 2nd callback', function(done) {
    let promise = new Promise((reject) => {
    let promise = new Promise((resolve, reject) => {
    setTimeout(() => reject(), 100);
    });

    @@ -83,7 +85,7 @@ describe('a Promise represents an operation that hasn`t completed yet, but is ex
    describe('test library (mocha here) support for promises', function() {

    it('just returning the promise makes the test library check that the promise resolves', function() {
    let promise = new Promise((reject, resolve) => {
    let promise = new Promise((resolve, reject) => {
    resolve();
    });

  10. mischah revised this gist Sep 11, 2016. 1 changed file with 95 additions and 0 deletions.
    95 changes: 95 additions & 0 deletions 75-Promise-basics.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,95 @@
    // http://tddbin.com/#?kata=es6/language/promise/basics

    // 75: Promise - basics
    // To do: make all tests pass, leave the assert lines unchanged!

    describe('a Promise represents an operation that hasn`t completed yet, but is expected in the future', function() {

    it('`Promise` is a global function', function() {
    const expectedType = '???';
    assert.equal(typeof Promise, expectedType);
    });

    describe('the constructor', function() {

    it('instantiating it without params throws', function() {
    const fn = () => { Promise }
    assert.throws(fn);
    });

    it('expects a function as parameter', function() {
    const param = null;
    assert.doesNotThrow(() => { new Promise(param); });
    });

    });

    describe('simplest promises', function() {

    it('resolve a promise by calling the `resolve` function given as first parameter', function(done) {
    let promise = new Promise((resolve) => {
    });

    promise
    .then(() => done())
    .catch(() => done(new Error('The promise is expected to resolve.')));
    });

    it('the `resolve` function can return a value, that is consumed by the `promise.then()` callback', function(done) {
    let promise = new Promise((resolve) => {
    resolve();
    });

    promise
    .then(value => {assert.equal(value, 42); done(); })
    .catch(() => done(new Error('The promise is expected to resolve with 42!')));
    });

    it('rejecting a promise is done by calling the callback given as 2nd parameter', function(done) {
    let promise = new Promise(() => {
    });

    promise
    .then(() => done(new Error('The promise is expected to be rejected.')))
    .catch(() => done());
    });

    });

    describe('an asynchronous promise', function() {

    it('can resolve later, also by calling the first callback', function(done) {
    let promise = new Promise(() => {
    setTimeout(() => resolve(), 100);
    });

    promise
    .then(() => done())
    .catch(() => done(new Error('The promise is expected to resolve.')));
    });

    it('reject it at some later point in time, calling the 2nd callback', function(done) {
    let promise = new Promise((reject) => {
    setTimeout(() => reject(), 100);
    });

    promise
    .then(() => done(new Error('The promise is expected to be rejected.')))
    .catch(() => done());
    });

    });

    describe('test library (mocha here) support for promises', function() {

    it('just returning the promise makes the test library check that the promise resolves', function() {
    let promise = new Promise((reject, resolve) => {
    resolve();
    });

    // return the promise to mocha, it has the checking for promise resolving built in, when it receives a promise
    return promise;
    });

    });
    });
  11. mischah revised this gist Sep 10, 2016. 1 changed file with 12 additions and 12 deletions.
    24 changes: 12 additions & 12 deletions 74-String-endsWith.js
    Original file line number Diff line number Diff line change
    @@ -9,43 +9,43 @@ describe('`str.endsWith(searchString)` determines whether `str` ends with `searc

    describe('1st parameter, the string to search for', function() {
    it('works with just a character', function() {
    const doesEndWith = s.doesItReallyEndWith('n');
    const doesEndWith = s.endsWith('n');
    assert.equal(doesEndWith, true);
    });
    it('works with a string', function() {
    const expected = false;
    const expected = true;
    assert.equal(s.endsWith('fin'), expected);
    });
    it('works with unicode characters', function() {
    const nuclear = 'NO ☢ Oh NO!';
    const nuclear = 'NO ☢';
    assert.equal(nuclear.endsWith('☢'), true);
    });
    it('a regular expression throws a TypeError', function() {
    const aRegExp = '/the/';
    const aRegExp = /the/;
    assert.throws(() => {''.endsWith(aRegExp)}, TypeError);
    });
    });

    describe('2nd parameter, searches within this string as if this string were only this long', function() {
    it('find "el" at a substring of the length 2', function() {
    const endPos = 0;
    const endPos = 2;
    assert.equal(s.endsWith('el', endPos), true);
    });
    it('`undefined` uses the entire string', function() {
    const _undefined_ = 'i would like to be undefined';
    let _undefined_;
    assert.equal(s.endsWith('fin', _undefined_), true);
    });
    it('the parameter gets coerced to an int', function() {
    const position = 'five';
    const position = '5';
    assert.equal(s.endsWith('fi', position), true);
    });
    describe('value less than 0', function() {
    it('returns `true`, when searching for an empty string', function() {
    const emptyString = '??';
    const emptyString = '';
    assert.equal('1'.endsWith(emptyString, -1), true);
    });
    it('return `false`, when searching for a non-empty string', function() {
    const notEmpty = '';
    const notEmpty = 'huh';
    assert.equal('1'.endsWith(notEmpty, -1), false);
    });
    });
    @@ -56,15 +56,15 @@ describe('`str.endsWith(searchString)` determines whether `str` ends with `searc
    const endsWith = (...args) => String.prototype.endsWith.call(...args);

    it('e.g. a boolean', function() {
    let aBool = false;
    let aBool = true;
    assert.equal(endsWith(!aBool, 'lse'), true);
    });
    it('e.g. a number', function() {
    let aNumber = 0;
    let aNumber = 84;
    assert.equal(endsWith(aNumber + 1900, 84), true);
    });
    it('also using the position works', function() {
    const position = '??';
    const position = 3;
    assert.equal(endsWith(1994, '99', position), true);
    });
    });
  12. mischah revised this gist Sep 10, 2016. 1 changed file with 72 additions and 0 deletions.
    72 changes: 72 additions & 0 deletions 74-String-endsWith.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,72 @@
    // http://tddbin.com/#?kata=es6/language/string-api/endswith

    // 74: String - `endsWith()`
    // To do: make all tests pass, leave the assert lines unchanged!

    describe('`str.endsWith(searchString)` determines whether `str` ends with `searchString`.', function() {

    const s = 'el fin';

    describe('1st parameter, the string to search for', function() {
    it('works with just a character', function() {
    const doesEndWith = s.doesItReallyEndWith('n');
    assert.equal(doesEndWith, true);
    });
    it('works with a string', function() {
    const expected = false;
    assert.equal(s.endsWith('fin'), expected);
    });
    it('works with unicode characters', function() {
    const nuclear = 'NO ☢ Oh NO!';
    assert.equal(nuclear.endsWith('☢'), true);
    });
    it('a regular expression throws a TypeError', function() {
    const aRegExp = '/the/';
    assert.throws(() => {''.endsWith(aRegExp)}, TypeError);
    });
    });

    describe('2nd parameter, searches within this string as if this string were only this long', function() {
    it('find "el" at a substring of the length 2', function() {
    const endPos = 0;
    assert.equal(s.endsWith('el', endPos), true);
    });
    it('`undefined` uses the entire string', function() {
    const _undefined_ = 'i would like to be undefined';
    assert.equal(s.endsWith('fin', _undefined_), true);
    });
    it('the parameter gets coerced to an int', function() {
    const position = 'five';
    assert.equal(s.endsWith('fi', position), true);
    });
    describe('value less than 0', function() {
    it('returns `true`, when searching for an empty string', function() {
    const emptyString = '??';
    assert.equal('1'.endsWith(emptyString, -1), true);
    });
    it('return `false`, when searching for a non-empty string', function() {
    const notEmpty = '';
    assert.equal('1'.endsWith(notEmpty, -1), false);
    });
    });
    });

    describe('transfer the functionality to other objects', function() {

    const endsWith = (...args) => String.prototype.endsWith.call(...args);

    it('e.g. a boolean', function() {
    let aBool = false;
    assert.equal(endsWith(!aBool, 'lse'), true);
    });
    it('e.g. a number', function() {
    let aNumber = 0;
    assert.equal(endsWith(aNumber + 1900, 84), true);
    });
    it('also using the position works', function() {
    const position = '??';
    assert.equal(endsWith(1994, '99', position), true);
    });
    });

    });
  13. mischah revised this gist Sep 9, 2016. 1 changed file with 11 additions and 7 deletions.
    18 changes: 11 additions & 7 deletions 73-Generator-return-inside-a-generator-is-special.js
    Original file line number Diff line number Diff line change
    @@ -10,30 +10,30 @@ describe('`return` in a generator function is special', function() {
    it('returns an IteratorResult (an object with the properties `value` and `done`)', function() {
    function* generatorFunction() { return 1; }
    const returned = generatorFunction().next();
    const propertyNames = [];
    const propertyNames = ['value', 'done'];
    assert.deepEqual(Object.keys(returned), propertyNames);
    });

    it('the property `value` is the value given after the `return` statement', function() {
    function* generatorFunction() { return; }
    function* generatorFunction() { return 23; }
    const {value} = generatorFunction().next();
    assert.equal(value, 23);
    });

    it('the property `done` is true', function() {
    function* generatorFunction() { yield 42; }
    function* generatorFunction() { return 42; }
    const {done} = generatorFunction().next();
    assert.equal(done, true);
    });

    it('NOTE: `yield` does not return `done=true` but `done=false`!', function() {
    function* generatorFunction() { return 1; }
    function* generatorFunction() { yield 1; }
    const returned = generatorFunction().next();
    assert.deepEqual(returned, {value: 1, done: false});
    });

    it('a missing `return` returns {value: undefined, done: true}', function() {
    function* generatorFunction() { yield; }
    function* generatorFunction() { }
    const returned = generatorFunction().next();
    assert.deepEqual(returned, {value: void 0, done: true});
    });
    @@ -44,6 +44,7 @@ describe('`return` in a generator function is special', function() {

    function* generatorFunctionWithYieldAndReturn() {
    yield 1;
    return 2;
    }

    it('is possible', function() {
    @@ -57,19 +58,22 @@ describe('`return` in a generator function is special', function() {

    it('the mix behaves different to two `yield`s', function() {
    const iterator = generatorFunctionWithYieldAndReturn();
    const values = [1, 2];
    const values = [1];
    assert.deepEqual(Array.from(iterator), values);
    });

    it('two `yield`s returning values', function() {
    function* generatorFunctionWithTwoYields() {
    yield 1;
    yield 2;
    }
    assert.deepEqual(Array.from(generatorFunctionWithTwoYields()), [1, 2]);
    });

    it('returning a yielded value', function() {
    function* generatorFunction() {
    return 1;
    yield 1;
    yield 2;
    }
    const iterator = generatorFunction();
    const values = [
  14. mischah revised this gist Sep 9, 2016. 1 changed file with 84 additions and 0 deletions.
    84 changes: 84 additions & 0 deletions 73-Generator-return-inside-a-generator-is-special.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,84 @@
    // http://tddbin.com/#?kata=es6/language/generator/return

    // 73: Generator - `return` inside a generator is special
    // To do: make all tests pass, leave the assert lines unchanged!

    describe('`return` in a generator function is special', function() {

    describe('the returned value is an IteratorResult (just like any value returned via `yield`)', function() {

    it('returns an IteratorResult (an object with the properties `value` and `done`)', function() {
    function* generatorFunction() { return 1; }
    const returned = generatorFunction().next();
    const propertyNames = [];
    assert.deepEqual(Object.keys(returned), propertyNames);
    });

    it('the property `value` is the value given after the `return` statement', function() {
    function* generatorFunction() { return; }
    const {value} = generatorFunction().next();
    assert.equal(value, 23);
    });

    it('the property `done` is true', function() {
    function* generatorFunction() { yield 42; }
    const {done} = generatorFunction().next();
    assert.equal(done, true);
    });

    it('NOTE: `yield` does not return `done=true` but `done=false`!', function() {
    function* generatorFunction() { return 1; }
    const returned = generatorFunction().next();
    assert.deepEqual(returned, {value: 1, done: false});
    });

    it('a missing `return` returns {value: undefined, done: true}', function() {
    function* generatorFunction() { yield; }
    const returned = generatorFunction().next();
    assert.deepEqual(returned, {value: void 0, done: true});
    });

    });

    describe('mixing `return` and `yield`', function() {

    function* generatorFunctionWithYieldAndReturn() {
    yield 1;
    }

    it('is possible', function() {
    const iterator = generatorFunctionWithYieldAndReturn();
    const values = [
    iterator.next(),
    iterator.next()
    ];
    assert.deepEqual(values, [{value: 1, done: false}, {value: 2, done: true}]);
    });

    it('the mix behaves different to two `yield`s', function() {
    const iterator = generatorFunctionWithYieldAndReturn();
    const values = [1, 2];
    assert.deepEqual(Array.from(iterator), values);
    });

    it('two `yield`s returning values', function() {
    function* generatorFunctionWithTwoYields() {
    }
    assert.deepEqual(Array.from(generatorFunctionWithTwoYields()), [1, 2]);
    });

    it('returning a yielded value', function() {
    function* generatorFunction() {
    return 1;
    }
    const iterator = generatorFunction();
    const values = [
    iterator.next().value,
    iterator.next(2).value
    ];
    assert.deepEqual(values, [1, 2]);
    });

    });

    });
  15. mischah revised this gist Sep 8, 2016. 1 changed file with 11 additions and 11 deletions.
    22 changes: 11 additions & 11 deletions 72-String-startsWith.js
    Original file line number Diff line number Diff line change
    @@ -9,38 +9,38 @@ describe('`str.startsWith(searchString)` determines whether `str` begins with `s

    describe('1st parameter, the string to search for', function() {
    it('works with just a character', function() {
    const actual = s.starts_with('t');
    const actual = s.startsWith('t');
    assert.equal(actual, true);
    });
    it('works with a string', function() {
    const expected = '???';
    const expected = true;
    assert.equal(s.startsWith('the'), expected);
    });
    it('works with unicode characters', function() {
    const nuclear = 'NO ☢ NO';
    const nuclear = '☢ NO';
    assert.equal(nuclear.startsWith('☢'), true);
    });
    it('a regular expression throws a TypeError', function() {
    const aRegExp = 'the';
    const aRegExp = /the/;
    assert.throws(() => {''.startsWith(aRegExp)}, TypeError);
    });
    });

    describe('2nd parameter, the position where to start searching from', function() {
    it('find "str" at position 4', function() {
    const position = 3;
    const position = 4;
    assert.equal(s.startsWith('str', position), true);
    });
    it('`undefined` is the same as 0', function() {
    const _undefined_ = '1';
    let _undefined_;
    assert.equal(s.startsWith('the', _undefined_), true);
    });
    it('the parameter gets coerced to an int', function() {
    const position = 'four';
    const position = '4';
    assert.equal(s.startsWith('str', position), true);
    });
    it('a value larger than the string`s length, returns false', function() {
    const expected = true;
    const expected = false;
    assert.equal(s.startsWith(' ', s.length + 1), expected);
    });
    });
    @@ -50,15 +50,15 @@ describe('`str.startsWith(searchString)` determines whether `str` begins with `s
    const startsWith = (...args) => String.prototype.startsWith.call(...args);

    it('e.g. a boolean', function() {
    let aBool;
    let aBool = true;
    assert.equal(startsWith(!aBool, 'false'), true);
    });
    it('e.g. a number', function() {
    let aNumber = 19;
    let aNumber = 1900;
    assert.equal(startsWith(aNumber + 84, '1984'), true);
    });
    it('also using the position works', function() {
    const position = 0;
    const position = 1;
    assert.equal(startsWith(1994, '99', position), true);
    });
    });
  16. mischah revised this gist Sep 8, 2016. 1 changed file with 66 additions and 0 deletions.
    66 changes: 66 additions & 0 deletions 72-String-startsWith.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,66 @@
    // http://tddbin.com/#?kata=es6/language/string-api/startswith

    // 72: String - `startsWith()`
    // To do: make all tests pass, leave the assert lines unchanged!

    describe('`str.startsWith(searchString)` determines whether `str` begins with `searchString`.', function() {

    const s = 'the string s';

    describe('1st parameter, the string to search for', function() {
    it('works with just a character', function() {
    const actual = s.starts_with('t');
    assert.equal(actual, true);
    });
    it('works with a string', function() {
    const expected = '???';
    assert.equal(s.startsWith('the'), expected);
    });
    it('works with unicode characters', function() {
    const nuclear = 'NO ☢ NO';
    assert.equal(nuclear.startsWith('☢'), true);
    });
    it('a regular expression throws a TypeError', function() {
    const aRegExp = 'the';
    assert.throws(() => {''.startsWith(aRegExp)}, TypeError);
    });
    });

    describe('2nd parameter, the position where to start searching from', function() {
    it('find "str" at position 4', function() {
    const position = 3;
    assert.equal(s.startsWith('str', position), true);
    });
    it('`undefined` is the same as 0', function() {
    const _undefined_ = '1';
    assert.equal(s.startsWith('the', _undefined_), true);
    });
    it('the parameter gets coerced to an int', function() {
    const position = 'four';
    assert.equal(s.startsWith('str', position), true);
    });
    it('a value larger than the string`s length, returns false', function() {
    const expected = true;
    assert.equal(s.startsWith(' ', s.length + 1), expected);
    });
    });

    describe('transfer the functionality to other objects', function() {

    const startsWith = (...args) => String.prototype.startsWith.call(...args);

    it('e.g. a boolean', function() {
    let aBool;
    assert.equal(startsWith(!aBool, 'false'), true);
    });
    it('e.g. a number', function() {
    let aNumber = 19;
    assert.equal(startsWith(aNumber + 84, '1984'), true);
    });
    it('also using the position works', function() {
    const position = 0;
    assert.equal(startsWith(1994, '99', position), true);
    });
    });

    });
  17. mischah revised this gist Sep 7, 2016. 1 changed file with 10 additions and 10 deletions.
    20 changes: 10 additions & 10 deletions 71-String-repeat.js
    Original file line number Diff line number Diff line change
    @@ -7,42 +7,42 @@ describe('`str.repeat(x)` appends `x` copies of `str` to each other and returns

    describe('pass the count to `str.repeat(count)`', function() {
    it('for `1` the string stays the same', function() {
    const what = '???'.repeat();
    const what = 'one'.repeat(1);
    assert.equal(what, 'one');
    });
    it('for `3` the string `x` becomes `xxx`', function() {
    const actual = 'x'.repeets;
    const actual = 'x'.repeat(3);
    assert.equal(actual, 'xxx');
    });
    it('for `0` an empty string is returned', function() {
    const dontRepeat = 1;
    const dontRepeat = '1'.repeat(0);
    assert.equal('shrink'.repeat(dontRepeat), '');
    });

    it('the count is not an int, such as "3", it gets coerced to an int', function() {
    const repeated = ''.repeat('2');
    const repeated = 'three'.repeat('3');
    assert.equal(repeated, 'threethreethree');
    });
    });

    describe('throws an error for', function() {
    it('a count of <0', function() {
    const belowZero = 1;
    const belowZero = -1;
    assert.throws(() => { ''.repeat(belowZero); }, RangeError);
    });
    it('a count of +Infinty', function() {
    let infinity = 'infinity';
    let infinity = Infinity;
    assert.throws(() => { ''.repeat(infinity); }, RangeError);
    });
    });

    describe('accepts everything that can be coerced to a string', function() {
    it('e.g. a boolean', function() {
    let aBool = true;
    let aBool = false;
    assert.equal(String.prototype.repeat.call(aBool, 2), 'falsefalse');
    });
    it('e.g. a number', function() {
    let aNumber;
    let aNumber = 1;
    assert.equal(String.prototype.repeat.call(aNumber, 2), '11');
    });
    });
    @@ -51,7 +51,7 @@ describe('`str.repeat(x)` appends `x` copies of `str` to each other and returns
    it('calls `toString()` to make it a string', function() {
    class MyString { toString() { return 'my string'; } }

    const expectedString = '';
    const expectedString = new MyString();

    assert.equal(String(new MyString()).repeat(1), expectedString);
    });
    @@ -63,7 +63,7 @@ describe('`str.repeat(x)` appends `x` copies of `str` to each other and returns
    }
    }

    let repeated = new X().repeat(2);
    let repeated = String(new X()).repeat(2);

    assert.equal(repeated, '11');
    });
  18. mischah revised this gist Sep 7, 2016. 1 changed file with 72 additions and 0 deletions.
    72 changes: 72 additions & 0 deletions 71-String-repeat.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,72 @@
    // http://tddbin.com/#?kata=es6/language/string-api/repeat

    // 71: String - `repeat()`
    // To do: make all tests pass, leave the assert lines unchanged!

    describe('`str.repeat(x)` appends `x` copies of `str` to each other and returns it', function() {

    describe('pass the count to `str.repeat(count)`', function() {
    it('for `1` the string stays the same', function() {
    const what = '???'.repeat();
    assert.equal(what, 'one');
    });
    it('for `3` the string `x` becomes `xxx`', function() {
    const actual = 'x'.repeets;
    assert.equal(actual, 'xxx');
    });
    it('for `0` an empty string is returned', function() {
    const dontRepeat = 1;
    assert.equal('shrink'.repeat(dontRepeat), '');
    });

    it('the count is not an int, such as "3", it gets coerced to an int', function() {
    const repeated = ''.repeat('2');
    assert.equal(repeated, 'threethreethree');
    });
    });

    describe('throws an error for', function() {
    it('a count of <0', function() {
    const belowZero = 1;
    assert.throws(() => { ''.repeat(belowZero); }, RangeError);
    });
    it('a count of +Infinty', function() {
    let infinity = 'infinity';
    assert.throws(() => { ''.repeat(infinity); }, RangeError);
    });
    });

    describe('accepts everything that can be coerced to a string', function() {
    it('e.g. a boolean', function() {
    let aBool = true;
    assert.equal(String.prototype.repeat.call(aBool, 2), 'falsefalse');
    });
    it('e.g. a number', function() {
    let aNumber;
    assert.equal(String.prototype.repeat.call(aNumber, 2), '11');
    });
    });

    describe('for my own (string) class', function() {
    it('calls `toString()` to make it a string', function() {
    class MyString { toString() { return 'my string'; } }

    const expectedString = '';

    assert.equal(String(new MyString()).repeat(1), expectedString);
    });
    it('`toString()` is only called once', function() {
    let counter = 1;
    class X {
    toString() {
    return counter++;
    }
    }

    let repeated = new X().repeat(2);

    assert.equal(repeated, '11');
    });
    });

    });
  19. mischah revised this gist Sep 6, 2016. 1 changed file with 4 additions and 3 deletions.
    7 changes: 4 additions & 3 deletions 70-Set-clear.js
    Original file line number Diff line number Diff line change
    @@ -12,27 +12,28 @@ describe('`clear()` removes all elements from a Set object.', function(){
    set.add('one').add(2);
    set.clear();

    var expectedSize;
    var expectedSize = 0;
    assert.equal(set.size, expectedSize);
    });

    it('the iterator `set.entries()` will not contain any items', function() {
    set.add('one').add(2);

    set.clear;
    set.clear();

    const {done} = set.entries().next();
    assert.equal(done, true);
    });

    it('any call to `set.has()` returns false', function() {
    set.add('one').add(2);
    set.clear();

    assert.deepEqual(set.has(2), false);
    });

    it('returns `undefined`', function() {
    var expectedReturn = true;
    var expectedReturn;
    assert.equal(set.clear(), expectedReturn);
    });

  20. mischah revised this gist Sep 6, 2016. 1 changed file with 39 additions and 0 deletions.
    39 changes: 39 additions & 0 deletions 70-Set-clear.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,39 @@
    // http://tddbin.com/#?kata=es6/language/set/clear

    // 70: Set - clear
    // To do: make all tests pass, leave the assert lines unchanged!

    describe('`clear()` removes all elements from a Set object.', function(){

    let set;
    beforeEach(() => set = new Set());

    it('`set.size` becomes 0', function() {
    set.add('one').add(2);
    set.clear();

    var expectedSize;
    assert.equal(set.size, expectedSize);
    });

    it('the iterator `set.entries()` will not contain any items', function() {
    set.add('one').add(2);

    set.clear;

    const {done} = set.entries().next();
    assert.equal(done, true);
    });

    it('any call to `set.has()` returns false', function() {
    set.add('one').add(2);

    assert.deepEqual(set.has(2), false);
    });

    it('returns `undefined`', function() {
    var expectedReturn = true;
    assert.equal(set.clear(), expectedReturn);
    });

    });
  21. mischah revised this gist Sep 5, 2016. 1 changed file with 19 additions and 18 deletions.
    37 changes: 19 additions & 18 deletions 69-Reflect-defineProperty.js
    Original file line number Diff line number Diff line change
    @@ -7,51 +7,52 @@ describe('`Reflect.defineProperty()` is like `Object.defineProperty()` but retur

    describe('the function itself', function() {
    it('is static on the `Reflect` object', function() {
    const name = 'waht`s the functions name again? :)';
    const name = 'defineProperty';
    assert.equal(name in Reflect, true);
    });
    it('is of type `function`', function() {
    const expectedType = '';
    const expectedType = 'function';
    assert.equal(typeof Reflect.defineProperty, expectedType)
    });
    });

    describe('the 1st parameter is the object on which to define a property', function() {
    it('fails if it is not an object', function() {
    let noObj = {};
    assert.throws(() => { Reflect.defineProperty(noObj); }, TypeError);
    let noObj = '';
    assert.throws(() => { Reflect.defineProperty(noObj, 'x', {value: 42}); }, TypeError);
    });
    it('accepts an object', function() {
    let obj = '';
    assert.doesNotThrow(() => { Reflect.defineProperty(obj); });
    let obj = {};
    assert.doesNotThrow(() => { Reflect.defineProperty(obj, 'x', {value: 42}); });
    });
    it('accepts an instance (of a class)', function() {
    let instance;
    assert.doesNotThrow(() => { Reflect.defineProperty(instance); });
    class Foo {}
    let instance = new Foo();
    assert.doesNotThrow(() => { Reflect.defineProperty(instance, 'x', {value: 42}); });
    });
    });

    describe('2nd parameter is the name of the property to be defined on the object (normally a string)', function() {
    it('works with a `normal` string', function() {
    let obj = {};
    Reflect.defineProperty(obj, '', {});
    Reflect.defineProperty(obj, 'prop', {});
    assert.equal('prop' in obj, true);
    });
    it('a number gets converted into a string', function() {
    let obj = {};
    Reflect.defineProperty(obj, 2, {});
    Reflect.defineProperty(obj, 1, {});
    assert.equal('1' in obj, true);
    });
    it('`undefined` also gets converted into a string (watch out!)', function() {
    let obj = {};
    let undef = 1;
    let undef;
    Reflect.defineProperty(obj, undef, {});
    assert.equal('undefined' in obj, true);
    });
    it('it can be a symbol', function() {
    let obj = {};
    const sym = Symbol.for('prop');
    Reflect.defineProperty(obj, 'prop', {});
    Reflect.defineProperty(obj, sym, {});
    assert.equal(sym in obj, true);
    });
    });
    @@ -61,12 +62,12 @@ describe('`Reflect.defineProperty()` is like `Object.defineProperty()` but retur

    it('contains the initial value of the property, as an object in the property `value`', function() {
    let obj = {};
    Reflect.defineProperty(obj, 'prop');
    Reflect.defineProperty(obj, 'prop', {value: 'property value'});
    assert.equal(obj.prop, 'property value');
    });
    it('can be of any type (even itself)', function() {
    let obj = {};
    Reflect.defineProperty(obj, 'prop');
    Reflect.defineProperty(obj, 'prop', {value: obj});
    assert.equal(obj.prop, obj);
    });
    });
    @@ -75,24 +76,24 @@ describe('`Reflect.defineProperty()` is like `Object.defineProperty()` but retur
    describe('returns true', function() {
    it('when the property was created (which requires the 3rd parameter too!!!)', function() {
    let instance = new class {};
    const wasPropertyDefined = Reflect.defineProperty();
    const wasPropertyDefined = Reflect.defineProperty(instance, 'prop', {value: 'value'});
    assert.equal(wasPropertyDefined, true);
    });
    it('no matter what the value of the property is (just the 3rd param has to exist as `{}`)', function() {
    let instance = new class {};
    const wasPropertyDefined = Reflect.defineProperty(instance);
    const wasPropertyDefined = Reflect.defineProperty(instance, 'prop', {});
    assert.equal(wasPropertyDefined, true);
    });
    });
    describe('returns false', function() {
    it('when no property name is given (since no property has been added)', function() {
    let instance = new class {};
    const wasPropertyDefined = Reflect.defineProperty;
    const wasPropertyDefined = Reflect.defineProperty(instance, null, {});
    assert.equal(wasPropertyDefined, false);
    });
    it('when no 3rd parameter, the descriptor is given', function() {
    let instance = new class {};
    const wasPropertyDefined = Reflect.defineProperty(instance, 'prop', {value: 1});
    const wasPropertyDefined = Reflect.defineProperty(instance, 'prop');
    assert.equal(wasPropertyDefined, false);
    });
    });
  22. mischah revised this gist Sep 5, 2016. 1 changed file with 101 additions and 0 deletions.
    101 changes: 101 additions & 0 deletions 69-Reflect-defineProperty.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,101 @@
    // http://tddbin.com/#?kata=es6/language/reflect/defineproperty

    // 69: Reflect - defineProperty
    // To do: make all tests pass, leave the assert lines unchanged!

    describe('`Reflect.defineProperty()` is like `Object.defineProperty()` but returns a Boolean.', function() {

    describe('the function itself', function() {
    it('is static on the `Reflect` object', function() {
    const name = 'waht`s the functions name again? :)';
    assert.equal(name in Reflect, true);
    });
    it('is of type `function`', function() {
    const expectedType = '';
    assert.equal(typeof Reflect.defineProperty, expectedType)
    });
    });

    describe('the 1st parameter is the object on which to define a property', function() {
    it('fails if it is not an object', function() {
    let noObj = {};
    assert.throws(() => { Reflect.defineProperty(noObj); }, TypeError);
    });
    it('accepts an object', function() {
    let obj = '';
    assert.doesNotThrow(() => { Reflect.defineProperty(obj); });
    });
    it('accepts an instance (of a class)', function() {
    let instance;
    assert.doesNotThrow(() => { Reflect.defineProperty(instance); });
    });
    });

    describe('2nd parameter is the name of the property to be defined on the object (normally a string)', function() {
    it('works with a `normal` string', function() {
    let obj = {};
    Reflect.defineProperty(obj, '', {});
    assert.equal('prop' in obj, true);
    });
    it('a number gets converted into a string', function() {
    let obj = {};
    Reflect.defineProperty(obj, 2, {});
    assert.equal('1' in obj, true);
    });
    it('`undefined` also gets converted into a string (watch out!)', function() {
    let obj = {};
    let undef = 1;
    Reflect.defineProperty(obj, undef, {});
    assert.equal('undefined' in obj, true);
    });
    it('it can be a symbol', function() {
    let obj = {};
    const sym = Symbol.for('prop');
    Reflect.defineProperty(obj, 'prop', {});
    assert.equal(sym in obj, true);
    });
    });

    describe('the `value` is part of the 3rd parameter, given as a property in an object `{value: ...}`', function() {
    // The entire complexity of the 3rd parameter might be covered in a later kata.

    it('contains the initial value of the property, as an object in the property `value`', function() {
    let obj = {};
    Reflect.defineProperty(obj, 'prop');
    assert.equal(obj.prop, 'property value');
    });
    it('can be of any type (even itself)', function() {
    let obj = {};
    Reflect.defineProperty(obj, 'prop');
    assert.equal(obj.prop, obj);
    });
    });

    describe('the return value of the function indicates wether the property was defined successfully', function() {
    describe('returns true', function() {
    it('when the property was created (which requires the 3rd parameter too!!!)', function() {
    let instance = new class {};
    const wasPropertyDefined = Reflect.defineProperty();
    assert.equal(wasPropertyDefined, true);
    });
    it('no matter what the value of the property is (just the 3rd param has to exist as `{}`)', function() {
    let instance = new class {};
    const wasPropertyDefined = Reflect.defineProperty(instance);
    assert.equal(wasPropertyDefined, true);
    });
    });
    describe('returns false', function() {
    it('when no property name is given (since no property has been added)', function() {
    let instance = new class {};
    const wasPropertyDefined = Reflect.defineProperty;
    assert.equal(wasPropertyDefined, false);
    });
    it('when no 3rd parameter, the descriptor is given', function() {
    let instance = new class {};
    const wasPropertyDefined = Reflect.defineProperty(instance, 'prop', {value: 1});
    assert.equal(wasPropertyDefined, false);
    });
    });
    });

    });
  23. mischah revised this gist Sep 4, 2016. 1 changed file with 13 additions and 13 deletions.
    26 changes: 13 additions & 13 deletions 68-Reflect-construct.js
    Original file line number Diff line number Diff line change
    @@ -7,26 +7,26 @@ describe('`Reflect.construct` is the `new` operator as a function', function() {

    describe('the function itself', function() {
    it('is static on the `Reflect` object', function() {
    const name = 'konstructor';
    const name = 'constructor';
    assert.equal(name in Reflect, true);
    });
    it('is of type `function`', function() {
    const expectedType = '???';
    const expectedType = 'function';
    assert.equal(typeof Reflect.construct, expectedType)
    });
    });

    describe('the 1st parameter is the constructor to be invoked', function() {
    it('fails when given a number as constructor', function() {
    let aNumber = () => {};
    assert.throws(() => { Reflect.construct(aNumber) }, TypeError);
    let aNumber = 42;
    assert.throws(() => { Reflect.construct(aNumber, []) }, TypeError);
    });
    it('works giving a function', function() {
    let aFunction;
    let aFunction = () => {};
    assert.doesNotThrow(() => { Reflect.construct(aFunction, []) });
    });
    it('works giving a class', function() {
    const aClass = {};
    const aClass = class {};
    assert.doesNotThrow(() => { Reflect.construct(aClass, []) });
    });
    });
    @@ -35,15 +35,15 @@ describe('`Reflect.construct` is the `new` operator as a function', function() {

    const aClass = class {};
    it('fails when it`s not an array(-like), e.g. a number', function() {
    let aNumber = [];
    let aNumber = 42;
    assert.throws(() => { Reflect.construct(aClass, aNumber) }, TypeError);
    });
    it('works with an array-like object (the `length` property look up should not throw)', function() {
    let arrayLike = {get length() { throw new Error(); }};
    let arrayLike = {get length() { [].length; }};
    assert.doesNotThrow(() => { Reflect.construct(aClass, arrayLike) });
    });
    it('works with a real array', function() {
    let realArray = '';
    let realArray = ['foo', 'bar'];
    assert.doesNotThrow(() => { Reflect.construct(aClass, realArray) });
    });
    });
    @@ -52,7 +52,7 @@ describe('`Reflect.construct` is the `new` operator as a function', function() {

    it('giving it a class it returns an instance of this class', function() {
    class Constructable {}
    let instance; // use Reflect.construct here!!!
    let instance = Reflect.construct(Constructable, []); // use Reflect.construct here!!!

    assert.equal(instance instanceof Constructable, true);
    });
    @@ -62,13 +62,13 @@ describe('`Reflect.construct` is the `new` operator as a function', function() {
    constructor(...args) { this.args = args; }
    }
    it('if none given, nothing is passed', function() {
    let instance = Reflect.construct(Constructable, [1]);
    let instance = Reflect.construct(Constructable, []);

    assert.deepEqual(instance.args, []);
    });
    it('passing an array, all args of any type are passed', function() {
    const argumentsList = ['arg1', ['arg2.1', 'arg2.2'], {arg: 3}];
    let instance = Reflect.construct;
    let instance = Reflect.construct(Constructable, argumentsList);

    assert.deepEqual(instance.args, argumentsList);
    });
    @@ -77,7 +77,7 @@ describe('`Reflect.construct` is the `new` operator as a function', function() {

    describe('the length property', function() {
    it('of `Reflect.construct` is 2', function() {
    let expected;
    let expected = 2;
    assert.equal(Reflect.construct.length, expected);
    });
    });
  24. mischah revised this gist Sep 4, 2016. 1 changed file with 85 additions and 0 deletions.
    85 changes: 85 additions & 0 deletions 68-Reflect-construct.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,85 @@
    // http://tddbin.com/#?kata=es6/language/reflect/construct

    // 68: Reflect - construct
    // To do: make all tests pass, leave the assert lines unchanged!

    describe('`Reflect.construct` is the `new` operator as a function', function() {

    describe('the function itself', function() {
    it('is static on the `Reflect` object', function() {
    const name = 'konstructor';
    assert.equal(name in Reflect, true);
    });
    it('is of type `function`', function() {
    const expectedType = '???';
    assert.equal(typeof Reflect.construct, expectedType)
    });
    });

    describe('the 1st parameter is the constructor to be invoked', function() {
    it('fails when given a number as constructor', function() {
    let aNumber = () => {};
    assert.throws(() => { Reflect.construct(aNumber) }, TypeError);
    });
    it('works giving a function', function() {
    let aFunction;
    assert.doesNotThrow(() => { Reflect.construct(aFunction, []) });
    });
    it('works giving a class', function() {
    const aClass = {};
    assert.doesNotThrow(() => { Reflect.construct(aClass, []) });
    });
    });

    describe('the 2nd parameter is a list of arguments, that will be passed to the constructor', function() {

    const aClass = class {};
    it('fails when it`s not an array(-like), e.g. a number', function() {
    let aNumber = [];
    assert.throws(() => { Reflect.construct(aClass, aNumber) }, TypeError);
    });
    it('works with an array-like object (the `length` property look up should not throw)', function() {
    let arrayLike = {get length() { throw new Error(); }};
    assert.doesNotThrow(() => { Reflect.construct(aClass, arrayLike) });
    });
    it('works with a real array', function() {
    let realArray = '';
    assert.doesNotThrow(() => { Reflect.construct(aClass, realArray) });
    });
    });

    describe('in use', function() {

    it('giving it a class it returns an instance of this class', function() {
    class Constructable {}
    let instance; // use Reflect.construct here!!!

    assert.equal(instance instanceof Constructable, true);
    });

    describe('the list of arguments are passed to the constructor as given', function() {
    class Constructable {
    constructor(...args) { this.args = args; }
    }
    it('if none given, nothing is passed', function() {
    let instance = Reflect.construct(Constructable, [1]);

    assert.deepEqual(instance.args, []);
    });
    it('passing an array, all args of any type are passed', function() {
    const argumentsList = ['arg1', ['arg2.1', 'arg2.2'], {arg: 3}];
    let instance = Reflect.construct;

    assert.deepEqual(instance.args, argumentsList);
    });
    });
    });

    describe('the length property', function() {
    it('of `Reflect.construct` is 2', function() {
    let expected;
    assert.equal(Reflect.construct.length, expected);
    });
    });

    });
  25. mischah revised this gist Sep 3, 2016. No changes.
  26. mischah revised this gist Sep 3, 2016. 1 changed file with 8 additions and 5 deletions.
    13 changes: 8 additions & 5 deletions 67-object-literal-setter.js
    Original file line number Diff line number Diff line change
    @@ -9,7 +9,7 @@ describe('An object literal can also contain setters', () => {
    it('by prefixing the property with `set` (and make it a function)', function() {
    let theX = null;
    const obj = {
    x(newX) { theX = newX; }
    set x(newX) { theX = newX; }
    };

    obj.x = 'the new X';
    @@ -18,7 +18,7 @@ describe('An object literal can also contain setters', () => {
    it('must have exactly one parameter', function() {
    let setterCalledWith = void 0;
    const obj = {
    x() { // <<<<=== it's not a setter yet!
    set x(foo) {
    if (arguments.length === 1) {
    setterCalledWith = arguments[0];
    }
    @@ -29,10 +29,12 @@ describe('An object literal can also contain setters', () => {
    });
    it('can be a computed property (an expression enclosed in `[]`)', function() {
    const publicPropertyName = 'x';
    const privatePropertyName = '_' + publicPropertyName;
    let privatePropertyName = '_' + publicPropertyName;
    const obj = {
    [privatePropertyName]: nulls
    // write the complete setter to make the assert below pass :)
    [privatePropertyName]: null,
    set [publicPropertyName](foo) {
    this[privatePropertyName] = foo;
    }
    };

    obj.x = 'axe';
    @@ -49,6 +51,7 @@ describe('An object literal can also contain setters', () => {
    };

    // delete the property x here, to make the test pass
    delete obj.x

    obj.x = true;
    assert.equal(setterCalled, false);
  27. mischah revised this gist Sep 3, 2016. 2 changed files with 78 additions and 0 deletions.
    File renamed without changes.
    78 changes: 78 additions & 0 deletions 67-object-literal-setter.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,78 @@
    // http://tddbin.com/#?kata=es6/language/object-literal/setter

    // 67: object-literal - setter
    // To do: make all tests pass, leave the assert lines unchanged!

    describe('An object literal can also contain setters', () => {

    describe('defining: a setter', function() {
    it('by prefixing the property with `set` (and make it a function)', function() {
    let theX = null;
    const obj = {
    x(newX) { theX = newX; }
    };

    obj.x = 'the new X';
    assert.equal(theX, 'the new X');
    });
    it('must have exactly one parameter', function() {
    let setterCalledWith = void 0;
    const obj = {
    x() { // <<<<=== it's not a setter yet!
    if (arguments.length === 1) {
    setterCalledWith = arguments[0];
    }
    }
    };

    assert.equal(obj.x = 'new value', setterCalledWith);
    });
    it('can be a computed property (an expression enclosed in `[]`)', function() {
    const publicPropertyName = 'x';
    const privatePropertyName = '_' + publicPropertyName;
    const obj = {
    [privatePropertyName]: nulls
    // write the complete setter to make the assert below pass :)
    };

    obj.x = 'axe';
    assert.equal(obj._x, 'axe');
    });
    });

    describe('working with/on the setter', function() {

    it('you can use `delete` to remove the property (including it`s setter)', function() {
    let setterCalled = false;
    const obj = {
    set x(param) { setterCalled = true; }
    };

    // delete the property x here, to make the test pass

    obj.x = true;
    assert.equal(setterCalled, false);
    });

    });

    // TODO
    // The following dont seem to work in the current transpiler version
    // but should be correct, as stated here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set
    // It might be corrected later, new knowledge welcome.
    // it('must not overlap with a pure property', function() {
    // const obj = {
    // x: 1,
    // set x(val) { return 'ax'; }
    // };
    // assert.equal(obj.x, 'ax');
    // });
    // it('multiple `set` for the same property are not allowed', function() {
    // const obj = {
    // x: 1,
    // set x(v) { return 'ax'; },
    // set x(v) { return 'ax1'; }
    // };
    // assert.equal(obj.x, 'ax');
    // });
    });
  28. mischah renamed this gist Sep 2, 2016. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions gistfile1.txt → 66-object-literal-getter.js
    Original file line number Diff line number Diff line change
    @@ -7,15 +7,15 @@ describe('An object literal can also contain getters', () => {

    it('just prefix the property with `get` (and make it a function)', function() {
    const obj = {
    x() { return 'ax'; }
    get x() { return 'ax'; }
    };

    assert.equal(obj.x, 'ax');
    });

    it('must have NO parameters', function() {
    const obj = {
    x(param) { return 'ax'; }
    get x() { return 'ax'; }
    };

    assert.equal(obj.x, 'ax');
    @@ -25,7 +25,7 @@ describe('An object literal can also contain getters', () => {
    it('can be a computed property (an expression enclosed in `[]`)', function() {
    const keyName = 'x';
    const obj = {
    get keyName() { return 'ax'; }
    get [keyName]() { return 'ax'; }
    };

    assert.equal(obj.x, 'ax');
    @@ -35,7 +35,7 @@ describe('An object literal can also contain getters', () => {
    const obj = {
    get x() { return 'ax'; }
    };

    delete obj.x;
    assert.equal(obj.x, void 0);
    });

  29. mischah revised this gist Sep 2, 2016. 1 changed file with 64 additions and 0 deletions.
    64 changes: 64 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,64 @@
    // http://tddbin.com/#?kata=es6/language/object-literal/getter

    // 66: object-literal - getter
    // To do: make all tests pass, leave the assert lines unchanged!

    describe('An object literal can also contain getters', () => {

    it('just prefix the property with `get` (and make it a function)', function() {
    const obj = {
    x() { return 'ax'; }
    };

    assert.equal(obj.x, 'ax');
    });

    it('must have NO parameters', function() {
    const obj = {
    x(param) { return 'ax'; }
    };

    assert.equal(obj.x, 'ax');
    });


    it('can be a computed property (an expression enclosed in `[]`)', function() {
    const keyName = 'x';
    const obj = {
    get keyName() { return 'ax'; }
    };

    assert.equal(obj.x, 'ax');
    });

    it('can be removed using delete', function() {
    const obj = {
    get x() { return 'ax'; }
    };

    assert.equal(obj.x, void 0);
    });

    // The following dont seem to work in the current transpiler version
    // but should be correct, as stated here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get
    // It might be corrected later, new knowledge welcome.

    //it('must not overlap with a pure property', function() {
    // const obj = {
    // x: 1,
    // get x() { return 'ax'; }
    // };
    //
    // assert.equal(obj.x, 'ax');
    //});
    //
    //it('multiple `get` for the same property are not allowed', function() {
    // const obj = {
    // x: 1,
    // get x() { return 'ax'; },
    // get x() { return 'ax1'; }
    // };
    //
    // assert.equal(obj.x, 'ax');
    //});
    });
  30. mischah revised this gist Sep 1, 2016. 1 changed file with 11 additions and 8 deletions.
    19 changes: 11 additions & 8 deletions 65-Set-API-overview.js
    Original file line number Diff line number Diff line change
    @@ -12,60 +12,63 @@ describe('`Set` API overview', function(){
    });

    it('a Set can be created from an array', function() {
    let set = new Set([]);
    let set = new Set(api);
    assert.deepEqual(Array.from(set), api);
    });

    it('`size` is the number of values', function() {
    const theSize = set.count;
    const theSize = set.size;
    assert.equal(theSize, api.length);
    });

    it('`add()` appends the given value', function() {
    // hint: to make the example consistent you can add the `Symbol.iterator` to `set`
    // strongly speaking it is missing in the API.
    set.add(Symbol.iterator);
    assert.equal(set.size, api.length + 1);
    });

    it('`clear()` removes all elements', function() {
    set.clear();
    assert.equal(set.size, 0);
    });

    it('`delete()` removes the given value', function() {
    set.delete('size');
    assert.equal(set.size, api.length - 1);
    });

    it('`entries()` returns an iterator for all values', function() {
    const expectedEntries = api.map(entry => [entry, entry]);
    const actualEntries = set.entry;
    const actualEntries = set.entries();
    assert.deepEqual([...actualEntries], expectedEntries);
    });

    it('`forEach()` calls a callback for each value', function() {
    let values = [];
    set.map(value => { values.push(value); });
    set.forEach(value => { values.push(value); });
    assert.deepEqual(values, api);
    });

    it('`has()` returns true if the given value is in the set', function() {
    const propertyName = '';
    const propertyName = 'has';
    assert.equal(set.has(propertyName), true);
    });

    describe('returns an iterator that contains all values', function() {
    // in order to be alike to `Map` `keys()` and `values()` are essentially the same thing for a `Set`.
    it('`keys()`', function() {
    const allKeys = Object.keys(set);
    const allKeys = set.keys();
    assert.deepEqual([...allKeys], api);
    });

    it('`values()`', function() {
    const allValues = set.value();
    const allValues = set.values();
    assert.deepEqual([...allValues], api);
    });

    it('`[Symbol.iterator]()`', function() {
    const iteratorKey = '???';
    const iteratorKey = Symbol.iterator;
    assert.deepEqual([...set[iteratorKey]()], api);
    });
    });