From 05ef8a1abff8a52e45c6c094d95b102dc2298f00 Mon Sep 17 00:00:00 2001 From: Ganesh Date: Tue, 20 Oct 2020 19:08:37 +0530 Subject: [PATCH] d2 ex --- .../unit-tests/js-3.6.0/SpecRunner.html | 1 + .../js-3.6.0/spec/PromisesAndCallbacksSpec.js | 268 ++++++++++++++++++ .../unit-tests/js-3.6.0/spec/sampleSpec.js | 24 +- 3 files changed, 292 insertions(+), 1 deletion(-) create mode 100755 jasmine-async-await/unit-tests/js-3.6.0/spec/PromisesAndCallbacksSpec.js diff --git a/jasmine-async-await/unit-tests/js-3.6.0/SpecRunner.html b/jasmine-async-await/unit-tests/js-3.6.0/SpecRunner.html index 7f7d977..6cd70b6 100644 --- a/jasmine-async-await/unit-tests/js-3.6.0/SpecRunner.html +++ b/jasmine-async-await/unit-tests/js-3.6.0/SpecRunner.html @@ -20,6 +20,7 @@ + diff --git a/jasmine-async-await/unit-tests/js-3.6.0/spec/PromisesAndCallbacksSpec.js b/jasmine-async-await/unit-tests/js-3.6.0/spec/PromisesAndCallbacksSpec.js new file mode 100755 index 0000000..b487acf --- /dev/null +++ b/jasmine-async-await/unit-tests/js-3.6.0/spec/PromisesAndCallbacksSpec.js @@ -0,0 +1,268 @@ +describe('Promise', () => { + it('Promise executor is run SYNCHRONOUSLY', () => { + let executorRun = false; + new Promise(function executor() { + executorRun = true; + }); + + expect(executorRun).toBe(true); + }); + + it('you can resolve a promise', (done) => { + new Promise((resolve) => setTimeout(resolve, 1)) + .then(done); + }); + + it('... or you can reject a promise', (done) => { + new Promise((resolve, reject) => setTimeout(reject, 1)) + .then(undefined, done); + }); + + it('An error inside the executor, rejects the promise', (done) => { + new Promise(function executor() { + throw 'Error'; + }).catch(done); + }); + + it('you can use Promise.resolve() to wrap values or promises', (done) => { + function iMayReturnAPromise() { + return Math.random() >= 0.5 ? Promise.resolve() : 5; + } + + Promise.resolve(iMayReturnAPromise()).then(done); + }); + + it('you can use Promise.resolve() to execute something just after', (done) => { + let arr = []; + Promise.resolve().then(() => arr.push(2)); + arr.push(1); + + setTimeout(() => { + expect(arr).toEqual([1, 2]); + done(); + }, 1); + }); + + /** @see https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/ **/ + it('Promise.resolve() is normally executed before setTimeout(..., 0)', (done) => { + let arr = []; + setTimeout(() => arr.push('timeOut'), 0); + Promise.resolve().then(() => { + arr.push('resolve'); + }); + + setTimeout(() => { + expect(arr).toEqual(['resolve', 'timeOut']); + done(); + }, 1); + }); + + it('you can create rejected promises', (done) => { + Promise.reject('reason').catch(done); + }); +/* + it('pay attention to "Uncaught (in promise) ..."', () => { + Promise.reject('The error').catch(); // Outputs in the console Uncaught (in promise) The error + }); +*/ + + // Chaining promises + it('you can chain promise because .then(...) returns a promise', (done) => { + fetch('https://jsonplaceholder.typicode.com/posts/1') + .then(response => response.json()) + .then(json => expect(json.userId).toBe(1)) + .then(done); + }); + + it('you can use the fail callback of .then(success, fail) to handle rejected promises', (done) => { + Promise.reject() + .then(function success() { + throw 'I must not be executed'; + }, function fail() { + done(); + }); + }); + + it('... or you can use .catch() to handle rejected promises', (done) => { + Promise.reject() + .then(function success() { + throw 'I must not be executed'; + }) + .catch(done); + }); + + it('also .catch() returns a promise, allowing promise chaining', (done) => { + Promise.reject() + .catch(() => undefined) + .then(done); + }); + + it('you must return a rejected promise if you want to execute the next fail callback', (done) => { + function someApiCall() { + return Promise.reject('Error'); + } + + someApiCall() + .catch((err) => { + console.error(err); + return Promise.reject(err); // Without this line, .catch gets not called + }) + .catch(done); + }); + + it('... or you can throw an error if you want to execute the next fail callback', (done) => { + function someApiCall() { + return Promise.reject('Error'); + } + + someApiCall() + .catch((err) => { + console.error(err); + throw err; // Without this line, .catch gets not called + }) + .catch(done); + }); + + it('values returned inside .then()/.catch() callbacks are provided to the next callback', (done) => { + Promise.resolve(1) + .then(value => value + 1) + .then(value => expect(value).toBe(2)); + + Promise.reject(1) + .catch(value => value + 1) + .then(value => expect(value).toBe(2)); + + setTimeout(() => { + done(); + }, 1); + }); + + + // New await/async syntax + it('you can use the new await/async syntax', async () => { + function timeout(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); + } + + const start = Date.now(); + const delay = 200; + + await timeout(delay + 1); // Just 1ms tolerance + + expect(Date.now() - start).toBeGreaterThanOrEqual(delay); + }); + + it('an async function returns a promise', (done) => { + async function iAmAsync() { + return 1; + } + + iAmAsync() + .then((val) => expect(val).toBe(1)) + .then(done); + }); + + it('await just awaits a promise resolution', async (done) => { + await Promise.resolve(); + done(); + }); + + it('await will throw an error if the promise fail', async (done) => { + try { + await Promise.reject(); + fail('I will not be executed'); + } catch (err) { + done(); + } + }); + + it("Don't use new Promise(...), prefer chaining", (done) => { + const url = 'https://jsonplaceholder.typicode.com/posts/1'; + + function badlyDesignedCustomFetch() { + return new Promise((resolve, reject) => { + fetch(url).then((response) => { + if (response.ok) { + resolve(response); + } else { + reject('Fetch failed'); + } + }); + }); + } + + function wellDesignedCustomFetch() { + return fetch(url).then((response) => { + if (!response.ok) { + return Promise.reject('Fetch failed'); + } + return (response); + }); + } + + Promise.all([badlyDesignedCustomFetch(), wellDesignedCustomFetch()]).then(done); + }); + + + // Parallel execution of promises + it('you can use Promise.all([...]) to execute promises in parallel', (done) => { + const url = 'https://jsonplaceholder.typicode.com/posts'; + const p1 = fetch(`${url}/1`); + const p2 = fetch(`${url}/2`); + + + Promise.all([p1, p2]) + .then(([res1, res2]) => { + return Promise.all([res1.json(), res2.json()]) + }) + .then(([post1, post2]) => { + expect(post1.id).toBe(1); + expect(post2.id).toBe(2); + }) + .then(done); + }); + + it('Promise.all([...]) will fail if any of the promises fails', (done) => { + const p1 = Promise.resolve(1); + const p2 = Promise.reject('Error'); + + Promise.all([p1, p2]) + .then(() => { + fail('I will not be executed') + }) + .catch(done); + }); + + it("if you don't want Promise.all() to fail, wrap the promises in a promise that will not fail", (done) => { + function iMayFail(val) { + return Math.random() >= 0.5 ? Promise.resolve(val) : Promise.reject(val); + } + + function promiseOr(p, value) { + return p.then(res => res, () => value); + } + + const p1 = iMayFail(10); + const p2 = iMayFail(9); + + Promise.all([promiseOr(p1, null), promiseOr(p2, null)]) + .then(([val1, val2]) => { + expect(val1 === 10 || val1 === null).toBe(true); + expect(val2 === 9 || val2 === null).toBe(true); + }) + .catch(() => { + fail('I will not be executed') + }) + .then(done); + }); + + it('Promise.race([...]) will resolve as soon as one of the promises resolves o rejects', (done) => { + const timeout = new Promise((resolve, reject) => setTimeout(reject, 100)); + const data = fetch('https://jsonplaceholder.typicode.com/posts/1'); + + Promise.race([data, timeout]) + .then(() => console.log('Fetch OK')) + .catch(() => console.log('Fetch timeout')) + .then(done); + }); +}); \ No newline at end of file diff --git a/jasmine-async-await/unit-tests/js-3.6.0/spec/sampleSpec.js b/jasmine-async-await/unit-tests/js-3.6.0/spec/sampleSpec.js index 1335b0e..d0ec009 100644 --- a/jasmine-async-await/unit-tests/js-3.6.0/spec/sampleSpec.js +++ b/jasmine-async-await/unit-tests/js-3.6.0/spec/sampleSpec.js @@ -9,8 +9,12 @@ describe("sample", function(){ function asyncFunctionSample(x) { return new Promise( resolve => { - setTimeout(()=> {resolve(x);}, 3000); + setTimeout( () => {resolve(x); }, 3000); } + /*, + reject => { + setTimeout(()=> {reject(x);}, 2000); + }*/ ); } @@ -25,4 +29,22 @@ describe("sample", function(){ }); + + it ("checks allowing creating rejected promises", (done) => { + Promise.reject('some reason').catch(done); + }); + + it('checks that promises work', function() { + function someAsyncFunction(x) { + return new Promise( + resolve => { + setTimeout(()=> {resolve(x*2);}, 3000); + } + ); + } + return someAsyncFunction(10).then(function (result) { + expect(result).toEqual(20); + }); + }); + }); \ No newline at end of file