blob: e42a64a4ee2ff8f90280f7e20b83a5426a5e3e69 [file] [log] [blame]
var assert = function (result, expected, message = "") {
if (result !== expected) {
throw new Error('Error in assert. Expected "' + expected + '" but was "' + result + '":' + message );
}
};
const Logger = function () {
var log = [];
this.logEvent = (type, value, done) => {
log.push({ type, value, done});
};
this.logFulfilledEvent = (value, done) => {
this.logEvent('fulfilled', value, done);
};
this.logRejectEvent = error => {
this.logEvent('reject', error.toString(), true);
};
this.logCatchEvent = value => {
this.logEvent('catch', value, true);
};
this.getLogger = () => log;
this.clear = () => {
log = [];
}
};
const fulfillSpy = logger => result => logger.logFulfilledEvent(result.value, result.done);
const rejectSpy = logger => error => logger.logRejectEvent(error);
const catchSpy = logger => error => logger.logCatchEvent(error);
const assertLogger = function (loggerObject) {
const logger = loggerObject.getLogger();
var _assertLogger = function () {
let index = 0;
const isNotOutOfLength = () => {
assert(index < logger.length, true, `Index is greater then log length`);
}
this.fullfilled = function (expectedValue, message = 'on fulfill') {
isNotOutOfLength();
const msg = `step: ${index} - ${message}`;
let step = logger[index];
assert(step.type, 'fulfilled', msg);
assert(step.value, expectedValue, msg);
assert(step.done, false, msg);
index++;
return this;
};
this.fullfilledDone = function (expectedValue, message = 'on fulfill with done true') {
isNotOutOfLength();
const msg = `step: ${index} - ${message}`;
let step = logger[index];
assert(step.type, 'fulfilled', msg);
assert(step.value, expectedValue, msg);
assert(step.done, true, msg);
index++;
return this;
};
this.rejected = function (error, message = 'on reject') {
isNotOutOfLength();
const msg = `step: ${index} - ${message}`;
let step = logger[index];
assert(step.type, 'reject', msg);
assert(step.value, error.toString(), msg);
assert(step.done, true, msg);
index++;
return this;
};
this.catched = function (expectedError, message = 'on catch') {
isNotOutOfLength();
const msg = `step: ${index} - ${message}`;
let step = logger[index];
assert(step.type, 'catch', msg);
assert(step.value, expectedError, msg);
assert(step.done, true, msg);
index++;
return this;
};
this.isFinal = function (message = '') {
assert(index, logger.length, `expected final step: ${message}`);
};
};
return new _assertLogger();
};
const getPromise = promiseHolder => {
return new Promise((resolve, reject) => {
promiseHolder.resolve = resolve;
promiseHolder.reject = reject;
});
};
var logger = new Logger();
const someValue = 'some-value';
const errorMessage = 'error-message';
const promiseHolder = {};
async function * foo(val) {
let reply = yield '0:' + val;
reply = yield getPromise(promiseHolder);
return 'end foo:' + reply;
}
let f = foo(someValue);
f.next(someValue + ':0').then(fulfillSpy(logger));
f.next(someValue + ':1').then(fulfillSpy(logger));
f.next(someValue + ':2').then(fulfillSpy(logger));
drainMicrotasks();
assertLogger(logger)
.fullfilled('0:' + someValue)
.isFinal();
promiseHolder.resolve('1');
drainMicrotasks();
assertLogger(logger)
.fullfilled('0:' + someValue)
.fullfilled('1')
.fullfilledDone('end foo:' + someValue + ':2')
.isFinal();
logger.clear();
f = foo('init');
f.next('0').then(fulfillSpy(logger), rejectSpy(logger));
f.next('1').then(fulfillSpy(logger), rejectSpy(logger));
f.next('2').then(fulfillSpy(logger), rejectSpy(logger));
drainMicrotasks();
assertLogger(logger)
.fullfilled('0:init')
.isFinal();
promiseHolder.reject('1');
drainMicrotasks();
assertLogger(logger)
.fullfilled('0:init')
.rejected('1')
.fullfilledDone()
.isFinal();
logger.clear();
f = foo('init');
f.next('0').then(fulfillSpy(logger)).catch(catchSpy(logger));
f.next('1').then(fulfillSpy(logger)).catch(catchSpy(logger));
f.next('2').then(fulfillSpy(logger)).catch(catchSpy(logger));
drainMicrotasks();
assertLogger(logger)
.fullfilled('0:init')
.isFinal();
promiseHolder.reject('1');
drainMicrotasks();
assertLogger(logger)
.fullfilled('0:init')
.fullfilledDone(undefined)
.catched('1')
.isFinal();
logger.clear();
const promiseHolder1 = {};
const promiseHolder2 = {};
async function * boo() {
const promise1 = getPromise(promiseHolder1);
const promise2 = getPromise(promiseHolder2);
yield '0';
yield promise1;
yield '1';
yield promise2;
return 'end foo';
}
let b = boo();
b.next().then(fulfillSpy(logger)).catch(catchSpy(logger));
b.next().then(fulfillSpy(logger)).catch(catchSpy(logger));
b.next().then(fulfillSpy(logger)).catch(catchSpy(logger));
b.next().then(fulfillSpy(logger)).catch(catchSpy(logger));
b.next().then(fulfillSpy(logger)).catch(catchSpy(logger));
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.isFinal();
promiseHolder1.resolve('#1');
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.fullfilled('#1')
.fullfilled('1')
.isFinal();
promiseHolder2.resolve('#2');
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.fullfilled('#1')
.fullfilled('1')
.fullfilled('#2')
.fullfilledDone('end foo')
.isFinal();
logger.clear();
b = boo();
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.isFinal();
promiseHolder1.resolve('#1');
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.fullfilled('#1')
.fullfilled('1')
.isFinal();
promiseHolder2.reject('#2');
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.fullfilled('#1')
.fullfilled('1')
.rejected('#2')
.fullfilledDone()
.isFinal();
logger.clear();
b = boo();
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.isFinal();
promiseHolder1.reject('#1');
promiseHolder2.resolve('#2');
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.rejected('#1')
.fullfilledDone()
.fullfilledDone()
.fullfilledDone()
.isFinal();
logger.clear();
b = boo();
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.isFinal();
promiseHolder2.reject('#2');
promiseHolder1.reject('#1');
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.rejected('#1')
.fullfilledDone()
.fullfilledDone()
.fullfilledDone()
.isFinal();
async function * bar() {
yield '0';
yield getPromise(promiseHolder1);
throw new Error(errorMessage);
yield getPromise(promiseHolder2);
return 'end foo';
}
logger.clear();
b = bar();
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.isFinal();
promiseHolder1.resolve('#1');
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.fullfilled('#1')
.rejected(new Error(errorMessage))
.fullfilledDone(undefined)
.isFinal();
logger.clear();
b = bar();
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.isFinal();
promiseHolder1.reject('#1');
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.rejected('#1')
.fullfilledDone()
.fullfilledDone()
.isFinal();
logger.clear();
b = bar();
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.return(someValue).then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.fullfilledDone(someValue)
.fullfilledDone(undefined)
.isFinal();
promiseHolder1.resolve('#1');
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.fullfilledDone(someValue)
.fullfilledDone(undefined)
.isFinal();
logger.clear();
b = bar();
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.return(someValue).then(fulfillSpy(logger), rejectSpy(logger));
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.isFinal();
promiseHolder1.resolve('#1');
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.fullfilled("#1")
.fullfilledDone(someValue)
.isFinal();
logger.clear();
b = bar();
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.next().then(fulfillSpy(logger), rejectSpy(logger));
b.return(someValue).then(fulfillSpy(logger), rejectSpy(logger));
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.isFinal();
promiseHolder1.reject('#1');
drainMicrotasks();
assertLogger(logger)
.fullfilled('0')
.rejected("#1")
.fullfilledDone(someValue)
.isFinal();