re-implementing tests with async await. tests also check asynchronous behaviour now.
This commit is contained in:
parent
ebc628adfc
commit
d4ef54358b
@ -37,6 +37,7 @@
|
|||||||
"CustomType": true,
|
"CustomType": true,
|
||||||
"window": true,
|
"window": true,
|
||||||
"document": true,
|
"document": true,
|
||||||
"smaller": true
|
"smaller": true,
|
||||||
|
"wait": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
12
gulpfile.js
12
gulpfile.js
@ -95,7 +95,9 @@ gulp.task("build", function () {
|
|||||||
.pipe(babel({
|
.pipe(babel({
|
||||||
loose: "all",
|
loose: "all",
|
||||||
modules: "ignore",
|
modules: "ignore",
|
||||||
blacklist: ["regenerator"]
|
optional: ["es7.asyncFunctions"],
|
||||||
|
blacklist: ["regenerator"],
|
||||||
|
experimental: true
|
||||||
}))
|
}))
|
||||||
.pipe(sourcemaps.write())
|
.pipe(sourcemaps.write())
|
||||||
.pipe(gulp.dest("."));
|
.pipe(gulp.dest("."));
|
||||||
@ -114,7 +116,9 @@ gulp.task("test", function () {
|
|||||||
.pipe(concat("jasmine"))
|
.pipe(concat("jasmine"))
|
||||||
.pipe(babel({
|
.pipe(babel({
|
||||||
loose: "all",
|
loose: "all",
|
||||||
modules: "ignore"
|
optional: ["es7.asyncFunctions"],
|
||||||
|
modules: "ignore",
|
||||||
|
experimental: true
|
||||||
}))
|
}))
|
||||||
.pipe(uglify())
|
.pipe(uglify())
|
||||||
.pipe(sourcemaps.write())
|
.pipe(sourcemaps.write())
|
||||||
@ -132,7 +136,9 @@ gulp.task("build_jasmine_browser", function(){
|
|||||||
.pipe(babel({
|
.pipe(babel({
|
||||||
loose: "all",
|
loose: "all",
|
||||||
modules: "ignore",
|
modules: "ignore",
|
||||||
blacklist: ["regenerator"]
|
optional: ["es7.asyncFunctions"],
|
||||||
|
blacklist: "regenerator",
|
||||||
|
experimental: true
|
||||||
}))
|
}))
|
||||||
.pipe(sourcemaps.write())
|
.pipe(sourcemaps.write())
|
||||||
.pipe(gulp.dest("build"));
|
.pipe(gulp.dest("build"));
|
||||||
|
@ -81,22 +81,22 @@ class AbstractConnector { //eslint-disable-line no-unused-vars
|
|||||||
// returns false, if there is no sync target
|
// returns false, if there is no sync target
|
||||||
// true otherwise
|
// true otherwise
|
||||||
findNextSyncTarget () {
|
findNextSyncTarget () {
|
||||||
if (this.currentSyncTarget != null && this.connections[this.currentSyncTarget].isSynced === false) {
|
if (this.currentSyncTarget != null) {
|
||||||
throw new Error("The current sync has not finished!");
|
return; // "The current sync has not finished!"
|
||||||
}
|
}
|
||||||
|
|
||||||
var syncUser = null;
|
var syncUser = null;
|
||||||
for (var uid in this.connections) {
|
for (var uid in this.connections) {
|
||||||
syncUser = this.connections[uid];
|
if (!this.connections[uid].isSynced) {
|
||||||
if (!syncUser.isSynced) {
|
syncUser = uid;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (syncUser != null){
|
if (syncUser != null){
|
||||||
var conn = this;
|
var conn = this;
|
||||||
|
this.currentSyncTarget = syncUser;
|
||||||
this.y.db.requestTransaction(function*(){
|
this.y.db.requestTransaction(function*(){
|
||||||
conn.currentSyncTarget = uid;
|
conn.send(syncUser, {
|
||||||
conn.send(uid, {
|
|
||||||
type: "sync step 1",
|
type: "sync step 1",
|
||||||
stateVector: yield* this.getStateVector()
|
stateVector: yield* this.getStateVector()
|
||||||
});
|
});
|
||||||
@ -110,7 +110,6 @@ class AbstractConnector { //eslint-disable-line no-unused-vars
|
|||||||
}
|
}
|
||||||
this.whenSyncedListeners = null;
|
this.whenSyncedListeners = null;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
send (uid, message) {
|
send (uid, message) {
|
||||||
if (this.debug) {
|
if (this.debug) {
|
||||||
@ -149,24 +148,38 @@ class AbstractConnector { //eslint-disable-line no-unused-vars
|
|||||||
type: "sync done"
|
type: "sync done"
|
||||||
});
|
});
|
||||||
}, conn.syncingClientDuration);
|
}, conn.syncingClientDuration);
|
||||||
|
} else {
|
||||||
|
conn.send(sender, {
|
||||||
|
type: "sync done"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (m.type === "sync step 2") {
|
} else if (m.type === "sync step 2") {
|
||||||
this.y.db.apply(m.os);
|
this.y.db.apply(m.os);
|
||||||
let conn = this;
|
let conn = this;
|
||||||
|
var broadcastHB = !this.broadcastedHB;
|
||||||
|
this.broadcastedHB = true;
|
||||||
this.y.db.requestTransaction(function*(){
|
this.y.db.requestTransaction(function*(){
|
||||||
var ops = yield* this.getOperations(m.stateVector);
|
var ops = yield* this.getOperations(m.stateVector);
|
||||||
conn.broadcastedHB = true;
|
|
||||||
if (ops.length > 0) {
|
if (ops.length > 0) {
|
||||||
conn.broadcast({
|
m = {
|
||||||
type: "update",
|
type: "update",
|
||||||
ops: ops
|
ops: ops
|
||||||
});
|
};
|
||||||
|
if (!broadcastHB) {
|
||||||
|
conn.send(sender, m);
|
||||||
|
} else {
|
||||||
|
// broadcast only once!
|
||||||
|
conn.broadcast(m);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (m.type === "sync done") {
|
} else if (m.type === "sync done") {
|
||||||
this.connections[sender].isSynced = true;
|
this.connections[sender].isSynced = true;
|
||||||
|
if (sender === this.currentSyncTarget) {
|
||||||
|
this.currentSyncTarget = null;
|
||||||
this.findNextSyncTarget();
|
this.findNextSyncTarget();
|
||||||
|
}
|
||||||
} else if (m.type === "update") {
|
} else if (m.type === "update") {
|
||||||
if (this.forwardToSyncingClients) {
|
if (this.forwardToSyncingClients) {
|
||||||
for (var client of this.syncingClients) {
|
for (var client of this.syncingClients) {
|
||||||
|
@ -73,10 +73,26 @@ class Test extends AbstractConnector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
flushAll () {
|
flushAll () {
|
||||||
var c = true;
|
var def = Promise.defer();
|
||||||
while (c) {
|
// flushes may result in more created operations,
|
||||||
c = flushOne();
|
// flush until there is nothing more to flush
|
||||||
|
function nextFlush() {
|
||||||
|
var c = flushOne();
|
||||||
|
if (c) {
|
||||||
|
while(flushOne()) {
|
||||||
|
//nop
|
||||||
}
|
}
|
||||||
|
wait().then(nextFlush);
|
||||||
|
} else {
|
||||||
|
wait().then(function(){
|
||||||
|
def.resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// in the case that there are
|
||||||
|
// still actions that want to be performed
|
||||||
|
wait(0).then(nextFlush);
|
||||||
|
return def.promise;
|
||||||
}
|
}
|
||||||
flushOne() {
|
flushOne() {
|
||||||
flushOne();
|
flushOne();
|
||||||
|
@ -5,6 +5,13 @@
|
|||||||
This is "just" a compilation of functions that help to test this library!
|
This is "just" a compilation of functions that help to test this library!
|
||||||
***/
|
***/
|
||||||
|
|
||||||
|
function wait(t = 0) {//eslint-disable-line
|
||||||
|
var def = Promise.defer();
|
||||||
|
setTimeout(function(){
|
||||||
|
def.resolve();
|
||||||
|
}, t);
|
||||||
|
return def.promise;
|
||||||
|
}
|
||||||
|
|
||||||
// returns a random element of o
|
// returns a random element of o
|
||||||
// works on Object, and Array
|
// works on Object, and Array
|
||||||
@ -26,7 +33,7 @@ function getRandomNumber(n) {//eslint-disable-line
|
|||||||
return Math.floor(Math.random() * n);
|
return Math.floor(Math.random() * n);
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyRandomTransactions (users, objects, transactions, numberOfTransactions) {//eslint-disable-line
|
async function applyRandomTransactions (users, objects, transactions, numberOfTransactions) {//eslint-disable-line
|
||||||
function randomTransaction (root) {
|
function randomTransaction (root) {
|
||||||
var f = getRandom(transactions);
|
var f = getRandom(transactions);
|
||||||
f(root);
|
f(root);
|
||||||
@ -39,40 +46,45 @@ function applyRandomTransactions (users, objects, transactions, numberOfTransact
|
|||||||
} else {
|
} else {
|
||||||
randomTransaction(getRandom(objects));
|
randomTransaction(getRandom(objects));
|
||||||
}
|
}
|
||||||
|
wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function compareAllUsers(users){//eslint-disable-line
|
async function compareAllUsers(users){//eslint-disable-line
|
||||||
var s1, s2;
|
var s1, s2;
|
||||||
|
var db1 = [];
|
||||||
function* t1(){
|
function* t1(){
|
||||||
s1 = yield* this.getStateSet();
|
s1 = yield* this.getStateSet();
|
||||||
}
|
}
|
||||||
function* t2(){
|
function* t2(){
|
||||||
s2 = yield* this.getStateSet();
|
s2 = yield* this.getStateSet();
|
||||||
}
|
}
|
||||||
users[0].connector.flushAll();
|
await users[0].connector.flushAll();
|
||||||
for (var uid = 0; uid + 1 < users.length; uid++) {
|
for (var uid = 0; uid < users.length; uid++) {
|
||||||
var u1 = users[uid];
|
if (s1 == null) {
|
||||||
var u2 = users[uid + 1];
|
var u = users[uid];
|
||||||
u1.db.requestTransaction(t1);
|
u.db.requestTransaction(t1);
|
||||||
u2.db.requestTransaction(t2);
|
await wait();
|
||||||
expect(s1).toEqual(s2);
|
u.db.os.iterate(null, null, function(o){//eslint-disable-line
|
||||||
var db1 = [];
|
|
||||||
var db2 = [];
|
|
||||||
u1.db.os.iterate(null, null, function(o){//eslint-disable-line
|
|
||||||
db1.push(o);
|
db1.push(o);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
var u2 = users[uid];
|
||||||
|
u2.db.requestTransaction(t2);
|
||||||
|
await wait();
|
||||||
|
expect(s1).toEqual(s2);
|
||||||
|
var count = 0;
|
||||||
u2.db.os.iterate(null, null, function(o){//eslint-disable-line
|
u2.db.os.iterate(null, null, function(o){//eslint-disable-line
|
||||||
db2.push(o);
|
expect(db1[count++]).toEqual(o);
|
||||||
});
|
});
|
||||||
|
|
||||||
for (var key in db1) {
|
|
||||||
expect(db1[key]).toEqual(db2[key]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createUsers(self, numberOfUsers, done) {//eslint-disable-line
|
async function createUsers(self, numberOfUsers) {//eslint-disable-line
|
||||||
|
if (globalRoom.users[0] != null) {//eslint-disable-line
|
||||||
|
await globalRoom.users[0].flushAll();//eslint-disable-line
|
||||||
|
}
|
||||||
//destroy old users
|
//destroy old users
|
||||||
for (var u in globalRoom.users) {//eslint-disable-line
|
for (var u in globalRoom.users) {//eslint-disable-line
|
||||||
globalRoom.users[u].y.destroy()//eslint-disable-line
|
globalRoom.users[u].y.destroy()//eslint-disable-line
|
||||||
@ -91,8 +103,5 @@ function createUsers(self, numberOfUsers, done) {//eslint-disable-line
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
Promise.all(promises).then( users => {
|
self.users = await Promise.all(promises);
|
||||||
self.users = users;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ Y.Memory = (function(){ //eslint-disable-line no-unused-vars
|
|||||||
requestTransaction (_makeGen : Function) {
|
requestTransaction (_makeGen : Function) {
|
||||||
if (!this.transactionInProgress) {
|
if (!this.transactionInProgress) {
|
||||||
this.transactionInProgress = true;
|
this.transactionInProgress = true;
|
||||||
window.setTimeout(() => {
|
setTimeout(() => {
|
||||||
var makeGen = _makeGen;
|
var makeGen = _makeGen;
|
||||||
while (makeGen != null) {
|
while (makeGen != null) {
|
||||||
var t = new Transaction(this);
|
var t = new Transaction(this);
|
||||||
|
@ -1,96 +1,78 @@
|
|||||||
/* @flow */
|
/* @flow */
|
||||||
/*eslint-env browser,jasmine */
|
/*eslint-env browser,jasmine */
|
||||||
|
|
||||||
var numberOfYArrayTests = 20;
|
var numberOfYArrayTests = 80;
|
||||||
|
|
||||||
describe("Array Type", function(){
|
describe("Array Type", function(){
|
||||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
|
var y1, y2, y3, flushAll;
|
||||||
beforeEach(function(done){
|
|
||||||
createUsers(this, 5, done);
|
jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000;
|
||||||
|
beforeEach(async function(done){
|
||||||
|
await createUsers(this, 5);
|
||||||
|
y1 = this.users[0].root;
|
||||||
|
y2 = this.users[1].root;
|
||||||
|
y3 = this.users[2].root;
|
||||||
|
flushAll = this.users[0].connector.flushAll;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
afterEach(async function(done) {
|
||||||
|
await compareAllUsers(this.users);
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Basic tests", function(){
|
describe("Basic tests", function(){
|
||||||
it("insert three elements", function(done){
|
it("insert three elements, try re-get property", async function(done){
|
||||||
var y = this.users[0].root;
|
var array = await y1.set("Array", Y.Array);
|
||||||
y.set("Array", Y.Array).then(function(array) {
|
|
||||||
array.insert(0, [1, 2, 3]);
|
array.insert(0, [1, 2, 3]);
|
||||||
return y.get("Array");
|
array = await y1.get("Array"); // re-get property
|
||||||
}).then(function(array){
|
|
||||||
expect(array.toArray()).toEqual([1, 2, 3]);
|
expect(array.toArray()).toEqual([1, 2, 3]);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
it("Basic insert in array (handle three conflicts)", async function(done){
|
||||||
it("Basic insert in array (handle three conflicts)", function(done){
|
|
||||||
var y = this.users[0];
|
|
||||||
var l1, l2, l3;
|
var l1, l2, l3;
|
||||||
y.root.set("Array", Y.Array).then((array)=>{
|
await y1.set("Array", Y.Array);
|
||||||
l1 = array;
|
await flushAll();
|
||||||
y.connector.flushAll();
|
(l1 = await y1.get("Array")).insert(0, [0]);
|
||||||
l1.insert(0, [0]);
|
(l2 = await y2.get("Array")).insert(0, [1]);
|
||||||
return this.users[1].root.get("Array");
|
(l3 = await y3.get("Array")).insert(0, [2]);
|
||||||
}).then((array)=>{
|
await flushAll();
|
||||||
l2 = array;
|
|
||||||
l2.insert(0, [1]);
|
|
||||||
return this.users[2].root.get("Array");
|
|
||||||
}).then((array)=>{
|
|
||||||
l3 = array;
|
|
||||||
l3.insert(0, [2]);
|
|
||||||
y.connector.flushAll();
|
|
||||||
expect(l1.toArray()).toEqual(l2.toArray());
|
expect(l1.toArray()).toEqual(l2.toArray());
|
||||||
expect(l2.toArray()).toEqual(l3.toArray());
|
expect(l2.toArray()).toEqual(l3.toArray());
|
||||||
compareAllUsers(this.users);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
it("Basic insert&delete in array (handle three conflicts)", async function(done){
|
||||||
it("Basic insert&delete in array (handle three conflicts)", function(done){
|
|
||||||
var y = this.users[0];
|
|
||||||
var l1, l2, l3;
|
var l1, l2, l3;
|
||||||
y.root.set("Array", Y.Array).then((array)=>{
|
l1 = await y1.set("Array", Y.Array);
|
||||||
l1 = array;
|
|
||||||
l1.insert(0, ["x", "y", "z"]);
|
l1.insert(0, ["x", "y", "z"]);
|
||||||
y.connector.flushAll();
|
await flushAll();
|
||||||
l1.insert(1, [0]);
|
l1.insert(1, [0]);
|
||||||
return this.users[1].root.get("Array");
|
l2 = await y2.get("Array");
|
||||||
}).then((array)=>{
|
|
||||||
l2 = array;
|
|
||||||
l2.delete(0);
|
l2.delete(0);
|
||||||
l2.delete(1);
|
l2.delete(1);
|
||||||
return this.users[2].root.get("Array");
|
l3 = await y3.get("Array");
|
||||||
}).then((array)=>{
|
|
||||||
l3 = array;
|
|
||||||
l3.insert(1, [2]);
|
l3.insert(1, [2]);
|
||||||
y.connector.flushAll();
|
await flushAll();
|
||||||
expect(l1.toArray()).toEqual(l2.toArray());
|
expect(l1.toArray()).toEqual(l2.toArray());
|
||||||
expect(l2.toArray()).toEqual(l3.toArray());
|
expect(l2.toArray()).toEqual(l3.toArray());
|
||||||
expect(l2.toArray()).toEqual([0, 2, "y"]);
|
expect(l2.toArray()).toEqual([0, 2, "y"]);
|
||||||
compareAllUsers(this.users);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
it("Basic insert. Then delete the whole array", async function(done){
|
||||||
it("Basic insert. Then delete the whole array", function(done){
|
|
||||||
var y = this.users[0];
|
|
||||||
var l1, l2, l3;
|
var l1, l2, l3;
|
||||||
y.root.set("Array", Y.Array).then((array)=>{
|
l1 = await y1.set("Array", Y.Array);
|
||||||
l1 = array;
|
|
||||||
l1.insert(0, ["x", "y", "z"]);
|
l1.insert(0, ["x", "y", "z"]);
|
||||||
y.connector.flushAll();
|
await flushAll();
|
||||||
l1.delete(0, 3);
|
l1.delete(0, 3);
|
||||||
return this.users[1].root.get("Array");
|
l2 = await y2.get("Array");
|
||||||
}).then((array)=>{
|
l3 = await y3.get("Array");
|
||||||
l2 = array;
|
await flushAll();
|
||||||
return this.users[2].root.get("Array");
|
|
||||||
}).then((array)=>{
|
|
||||||
l3 = array;
|
|
||||||
y.connector.flushAll();
|
|
||||||
expect(l1.toArray()).toEqual(l2.toArray());
|
expect(l1.toArray()).toEqual(l2.toArray());
|
||||||
expect(l2.toArray()).toEqual(l3.toArray());
|
expect(l2.toArray()).toEqual(l3.toArray());
|
||||||
expect(l2.toArray()).toEqual([]);
|
expect(l2.toArray()).toEqual([]);
|
||||||
compareAllUsers(this.users);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
it("throw insert & delete events", async function(done){
|
||||||
it("throw insert & delete events", function(done){
|
var array = await this.users[0].root.set("array", Y.Array);
|
||||||
this.users[0].root.set("array", Y.Array).then(function(array){
|
|
||||||
var event;
|
var event;
|
||||||
array.observe(function(e){
|
array.observe(function(e){
|
||||||
event = e;
|
event = e;
|
||||||
@ -109,10 +91,10 @@ describe("Array Type", function(){
|
|||||||
index: 0,
|
index: 0,
|
||||||
length: 1
|
length: 1
|
||||||
}]);
|
}]);
|
||||||
|
await wait(50);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
describe(`${numberOfYArrayTests} Random tests`, function(){
|
describe(`${numberOfYArrayTests} Random tests`, function(){
|
||||||
var randomArrayTransactions = [
|
var randomArrayTransactions = [
|
||||||
function insert (array) {
|
function insert (array) {
|
||||||
@ -136,34 +118,26 @@ describe("Array Type", function(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
beforeEach(function(done){
|
beforeEach(async function(done){
|
||||||
this.users[0].root.set("Array", Y.Array);
|
await this.users[0].root.set("Array", Y.Array);
|
||||||
this.users[0].connector.flushAll();
|
await flushAll();
|
||||||
|
|
||||||
var then = Promise.resolve();
|
var promises = [];
|
||||||
var arrays = [];
|
for (var u = 0; u < this.users.length; u++) {
|
||||||
for (var u of this.users) {
|
promises.push(this.users[u].root.get("Array"));
|
||||||
then = then.then(function(){ //eslint-disable-line
|
|
||||||
return u.root.get("Array");
|
|
||||||
}).then(function(array){//eslint-disable-line
|
|
||||||
arrays.push(array);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
this.arrays = arrays;
|
this.arrays = await Promise.all(promises);
|
||||||
then.then(function(){
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
it("arrays.length equals users.length", async function(done){
|
||||||
it("arrays.length equals users.length", function(){
|
|
||||||
expect(this.arrays.length).toEqual(this.users.length);
|
expect(this.arrays.length).toEqual(this.users.length);
|
||||||
});
|
|
||||||
it(`succeed after ${numberOfYArrayTests} actions`, function(done){
|
|
||||||
applyRandomTransactions(this.users, this.arrays, randomArrayTransactions, numberOfYArrayTests);
|
|
||||||
setTimeout(()=>{
|
|
||||||
compareAllUsers(this.users);
|
|
||||||
compareArrayValues(this.arrays);
|
|
||||||
done();
|
done();
|
||||||
}, 500);
|
});
|
||||||
|
it(`succeed after ${numberOfYArrayTests} actions`, async function(done){
|
||||||
|
await applyRandomTransactions(this.users, this.arrays, randomArrayTransactions, numberOfYArrayTests);
|
||||||
|
await flushAll();
|
||||||
|
await compareArrayValues(this.arrays);
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user