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