diff --git a/.eslintrc b/.eslintrc
index 340ba6a714484a70462f21ab156589d64ee6231c..388077643cecf1c892dfa93b7168992fa595a375 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -29,6 +29,10 @@
     "getRandom": true,
     "RBTree": true,
     "compareIds": true,
-    "EventHandler": true
+    "EventHandler": true,
+    "compareAllUsers": true,
+    "createUsers": true,
+    "getRandomNumber": true,
+    "applyRandomTransactions": true
   }
 }
diff --git a/src/Types/Array.spec.js b/src/Types/Array.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..386ba15069b9973a420f8b8ed5330a1cbc24b604
--- /dev/null
+++ b/src/Types/Array.spec.js
@@ -0,0 +1,93 @@
+/* @flow */
+/*eslint-env browser,jasmine */
+
+var numberOfYArrayTests = 10;
+
+describe("Array Type", function(){
+  jasmine.DEFAULT_TIMEOUT_INTERVAL = 3000;
+  beforeEach(function(done){
+    createUsers(this, 5, done);
+  });
+
+  describe("Basic tests", function(){
+    it("insert three elements", function(done){
+      var y = this.users[0].root;
+      y.set("Array", Y.Array).then(function(array) {
+        array.insert(0, [1, 2, 3]);
+        return y.get("Array");
+      }).then(function(array){
+        expect(array.toArray()).toEqual([1, 2, 3]);
+        done();
+      });
+    });
+    it("Basic insert in array (handle three conflicts)", function(done){
+      var y = this.users[0];
+      var l1, l2, l3;
+      y.root.set("Array", Y.Array).then((array)=>{
+        l1 = array;
+        y.connector.flushAll();
+        l1.insert(0, [0]);
+        return this.users[1].root.get("Array");
+      }).then((array)=>{
+        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(l2.toArray()).toEqual(l3.toArray());
+        compareAllUsers(this.users);
+        done();
+      });
+    });
+  });
+  describe("Random tests", function(){
+    var randomMapTransactions = [
+      function insert (array) {
+        array.insert(getRandomNumber(array.toArray().length), [getRandomNumber()]);
+      }
+    ];
+    function compareArrayValues(arrays){
+      var firstArray;
+      for (var l of arrays) {
+        var val = l.toArray();
+        if (firstArray == null) {
+          firstArray = val;
+        } else {
+          expect(val).toEqual(firstArray);
+        }
+      }
+    }
+    beforeEach(function(done){
+      this.users[0].root.set("Array", Y.Array);
+      this.users[0].connector.flushAll();
+
+      var then = Promise.resolve();
+      var arrays = [];
+      for (var u of this.users) {
+        then = then.then(function(){ //eslint-disable-line
+          return u.root.get("Array");
+        }).then(function(array){//eslint-disable-line
+          arrays.push(array);
+        });
+      }
+      this.arrays = arrays;
+      then.then(function(){
+        done();
+      });
+    });
+    it("arrays.length equals users.length", function(){
+      expect(this.arrays.length).toEqual(this.users.length);
+    });
+    it(`succeed after ${numberOfYArrayTests} actions`, function(done){
+      applyRandomTransactions(this.users, this.arrays, randomMapTransactions, numberOfYArrayTests);
+      setTimeout(()=>{
+        compareAllUsers(this.users);
+        compareArrayValues(this.arrays);
+        done();
+      }, 500);
+    });
+  });
+});
diff --git a/src/Types/Map.spec.js b/src/Types/Map.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..acc9e4ae98217c11e5a48f8864c3cbf1b0160057
--- /dev/null
+++ b/src/Types/Map.spec.js
@@ -0,0 +1,145 @@
+/* @flow */
+/*eslint-env browser,jasmine */
+
+var numberOfYMapTests = 5;
+
+describe("Map Type", function(){
+  jasmine.DEFAULT_TIMEOUT_INTERVAL = 3000;
+  beforeEach(function(done){
+    createUsers(this, 5, done);
+  });
+
+  describe("Basic tests", function(){
+    it("Basic get&set of Map property (converge via sync)", function(){
+      var y = this.users[0].root;
+      y.set("stuff", "stuffy");
+      expect(y.get("stuff")).toEqual("stuffy");
+
+      this.users[0].connector.flushAll();
+
+      for (var key in this.users) {
+        var u = this.users[key].root;
+        expect(u.get("stuff")).toEqual("stuffy");
+      }
+      compareAllUsers(this.users);
+    });
+    it("Map can set custom types (Map)", function(done){
+      var y = this.users[0].root;
+      y.set("Map", Y.Map).then(function(map) {
+        map.set("one", 1);
+        return y.get("Map");
+      }).then(function(map){
+        expect(map.get("one")).toEqual(1);
+        done();
+      });
+    });
+    it("Map can set custom types (Array)", function(done){
+      var y = this.users[0].root;
+      y.set("Array", Y.Array).then(function(array) {
+        array.insert(0, [1, 2, 3]);
+        return y.get("Array");
+      }).then(function(array){
+        expect(array.toArray()).toEqual([1, 2, 3]);
+        done();
+      });
+    });
+    it("Basic get&set of Map property (converge via update)", function(done){
+      var u = this.users[0];
+      u.connector.flushAll();
+      var y = u.root;
+      y.set("stuff", "stuffy");
+      expect(y.get("stuff")).toEqual("stuffy");
+
+      u.connector.flushAll();
+      setTimeout(() => {
+        for (var key in this.users) {
+          var r = this.users[key].root;
+          expect(r.get("stuff")).toEqual("stuffy");
+        }
+        done();
+      }, 50);
+    });
+    it("Basic get&set of Map property (handle conflict)", function(done){
+      var y = this.users[0];
+      y.connector.flushAll();
+      y.root.set("stuff", "c0");
+
+      this.users[1].root.set("stuff", "c1");
+
+      y.connector.flushAll();
+
+      setTimeout( () => {
+        for (var key in this.users) {
+          var u = this.users[key];
+          expect(u.root.get("stuff")).toEqual("c0");
+          compareAllUsers(this.users);
+        }
+        done();
+      }, 50);
+    });
+    it("Basic get&set of Map property (handle three conflicts)", function(done){
+      var y = this.users[0];
+      this.users[0].root.set("stuff", "c0");
+      this.users[1].root.set("stuff", "c1");
+      this.users[2].root.set("stuff", "c2");
+      this.users[3].root.set("stuff", "c3");
+      y.connector.flushAll();
+
+      setTimeout( () => {
+        for (var key in this.users) {
+          var u = this.users[key];
+          expect(u.root.get("stuff")).toEqual("c0");
+        }
+        compareAllUsers(this.users);
+        done();
+      }, 50);
+    });
+  });
+  describe("Random tests", function(){
+    var randomMapTransactions = [
+      function set (map) {
+        map.set("somekey", getRandomNumber());
+      },
+      function* delete_ (map) {
+        map.delete("somekey");
+      }
+    ];
+    function compareMapValues(maps){
+      var firstMap;
+      for (var map of maps) {
+        var val = map.get();
+        if (firstMap == null) {
+          firstMap = val;
+        } else {
+          expect(val).toEqual(firstMap);
+        }
+      }
+    }
+    beforeEach(function(done){
+      this.users[0].root.set("Map", Y.Map);
+      this.users[0].connector.flushAll();
+
+      var then = Promise.resolve();
+      var maps = [];
+      for (var u of this.users) {
+        then = then.then(function(){ //eslint-disable-line
+          return u.root.get("Map");
+        }).then(function(map){//eslint-disable-line
+          maps.push(map);
+        });
+      }
+      this.maps = maps;
+      then.then(function(){
+        done();
+      });
+    });
+    it(`succeed after ${numberOfYMapTests} actions`, function(done){
+      applyRandomTransactions(this.users, this.maps, randomMapTransactions, numberOfYMapTests);
+      setTimeout(()=>{
+        compareAllUsers(this.users);
+        compareMapValues(this.maps);
+        done();
+      }, 500);
+    });
+  });
+});
diff --git a/src/helper.spec.js b/src/helper.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..912bbda995488f8765225154835e72d5a4676d6f
--- /dev/null
+++ b/src/helper.spec.js
@@ -0,0 +1,99 @@
+/* @flow */
+/*eslint-env browser,jasmine */
+
+/***
+  This is "just" a compilation of functions that help to test this library!
+***/
+
+
+// returns a random element of o
+// works on Object, and Array
+function getRandom (o) {
+  if (o instanceof Array) {
+    return o[Math.floor(Math.random() * o.length)];
+  } else if (o.constructor === Object) {
+    var ks = [];
+    for (var key in o) {
+      ks.push(key);
+    }
+    return o[getRandom(ks)];
+  }
+}
+function getRandomNumber(n) {//eslint-disable-line
+  if (n == null) {
+    n = 9999;
+  }
+  return Math.floor(Math.random() * n);
+}
+
+function applyRandomTransactions (users, objects, transactions, numberOfTransactions) {//eslint-disable-line
+  function randomTransaction (root) {
+    var f = getRandom(transactions);
+    f(root);
+  }
+  for(var i = 0; i < numberOfTransactions; i++) {
+    var r = Math.random();
+    if (r >= 0.9) {
+      // 10% chance to flush
+      users[0].connector.flushOne();
+    } else {
+      randomTransaction(getRandom(objects));
+    }
+  }
+}
+
+function compareAllUsers(users){//eslint-disable-line
+  var s1, s2;
+  function* t1(){
+    s1 = yield* this.getStateSet();
+  }
+  function* t2(){
+    s2 = yield* this.getStateSet();
+  }
+  users[0].connector.flushAll();
+  for (var uid = 0; uid + 1 < users.length; uid++) {
+    var u1 = users[uid];
+    var u2 = users[uid + 1];
+    u1.db.requestTransaction(t1);
+    u2.db.requestTransaction(t2);
+    expect(s1).toEqual(s2);
+    var db1 = [];
+    var db2 = [];
+    u1.db.os.iterate(null, null, function(o){//eslint-disable-line
+      db1.push(o);
+    });
+    u2.db.os.iterate(null, null, function(o){//eslint-disable-line
+      db2.push(o);
+    });
+
+    for (var key in db1) {
+      expect(db1[key]).toEqual(db2[key]);
+    }
+  }
+}
+
+function createUsers(self, numberOfUsers, done) {//eslint-disable-line
+  if (self.users != null) {
+    for (var y of self.users) {
+      y.destroy();
+    }
+  }
+  self.users = [];
+
+  var promises = [];
+  for (var i = 0; i < numberOfUsers; i++) {
+    promises.push(Y({
+      db: {
+        name: "Memory"
+      },
+      connector: {
+        name: "Test",
+        debug: false
+      }
+    }));
+  }
+  Promise.all(promises).then( users => {
+    self.users = users;
+    done();
+  });
+}
diff --git a/src/y.spec.js b/src/y.spec.js
deleted file mode 100644
index 06381c5578e27e192ab03d6ab77b03dc8b178ead..0000000000000000000000000000000000000000
--- a/src/y.spec.js
+++ /dev/null
@@ -1,304 +0,0 @@
-/* @flow */
-/*eslint-env browser,jasmine */
-
-// returns a random element of o
-// works on Object, and Array
-function getRandom (o) {
-  if (o instanceof Array) {
-    return o[Math.floor(Math.random() * o.length)];
-  } else if (o.constructor === Object) {
-    var ks = [];
-    for (var key in o) {
-      ks.push(key);
-    }
-    return o[getRandom(ks)];
-  }
-}
-function getRandomNumber(n) {
-  if (n == null) {
-    n = 9999;
-  }
-  return Math.floor(Math.random() * n);
-}
-
-var numberOfYMapTests = 5;
-
-function applyRandomTransactions (users, objects, transactions, numberOfTransactions) {
-  function randomTransaction (root) {
-    var f = getRandom(transactions);
-    f(root);
-  }
-  for(var i = 0; i < numberOfTransactions; i++) {
-    var r = Math.random();
-    if (r >= 0.9) {
-      // 10% chance to flush
-      users[0].connector.flushOne();
-    } else {
-      randomTransaction(getRandom(objects));
-    }
-  }
-}
-
-function compareAllUsers(users){
-  var s1, s2;
-  function* t1(){
-    s1 = yield* this.getStateSet();
-  }
-  function* t2(){
-    s2 = yield* this.getStateSet();
-  }
-  users[0].connector.flushAll();
-  for (var uid = 0; uid + 1 < users.length; uid++) {
-    var u1 = users[uid];
-    var u2 = users[uid + 1];
-    u1.db.requestTransaction(t1);
-    u2.db.requestTransaction(t2);
-    expect(s1).toEqual(s2);
-    var db1 = [];
-    var db2 = [];
-    u1.db.os.iterate(null, null, function(o){//eslint-disable-line
-      db1.push(o);
-    });
-    u2.db.os.iterate(null, null, function(o){//eslint-disable-line
-      db2.push(o);
-    });
-
-    for (var key in db1) {
-      expect(db1[key]).toEqual(db2[key]);
-    }
-  }
-}
-
-describe("Yjs", function(){
-  jasmine.DEFAULT_TIMEOUT_INTERVAL = 3000;
-  beforeEach(function(done){
-    if (this.users != null) {
-      for (var y of this.users) {
-        y.destroy();
-      }
-    }
-    this.users = [];
-
-    var promises = [];
-    for (var i = 0; i < 5; i++) {
-      promises.push(Y({
-        db: {
-          name: "Memory"
-        },
-        connector: {
-          name: "Test",
-          debug: false
-        }
-      }));
-    }
-    Promise.all(promises).then( users => {
-      this.users = users;
-      done();
-    });
-  });
-
-  describe("Basic tests", function(){
-    it("Basic get&set of Map property (converge via sync)", function(){
-      var y = this.users[0].root;
-      y.set("stuff", "stuffy");
-      expect(y.get("stuff")).toEqual("stuffy");
-
-      this.users[0].connector.flushAll();
-
-      for (var key in this.users) {
-        var u = this.users[key].root;
-        expect(u.get("stuff")).toEqual("stuffy");
-      }
-      compareAllUsers(this.users);
-    });
-    it("Map can set custom types (Map)", function(done){
-      var y = this.users[0].root;
-      y.set("Map", Y.Map).then(function(map) {
-        map.set("one", 1);
-        return y.get("Map");
-      }).then(function(map){
-        expect(map.get("one")).toEqual(1);
-        done();
-      });
-    });
-    it("Map can set custom types (Array)", function(done){
-      var y = this.users[0].root;
-      y.set("Array", Y.Array).then(function(array) {
-        array.insert(0, [1, 2, 3]);
-        return y.get("Array");
-      }).then(function(array){
-        expect(array.toArray()).toEqual([1, 2, 3]);
-        done();
-      });
-    });
-    it("Basic get&set of Map property (converge via update)", function(done){
-      var u = this.users[0];
-      u.connector.flushAll();
-      var y = u.root;
-      y.set("stuff", "stuffy");
-      expect(y.get("stuff")).toEqual("stuffy");
-
-      u.connector.flushAll();
-      setTimeout(() => {
-        for (var key in this.users) {
-          var r = this.users[key].root;
-          expect(r.get("stuff")).toEqual("stuffy");
-        }
-        done();
-      }, 50);
-    });
-    it("Basic get&set of Map property (handle conflict)", function(done){
-      var y = this.users[0];
-      y.connector.flushAll();
-      y.root.set("stuff", "c0");
-
-      this.users[1].root.set("stuff", "c1");
-
-      y.connector.flushAll();
-
-      setTimeout( () => {
-        for (var key in this.users) {
-          var u = this.users[key];
-          expect(u.root.get("stuff")).toEqual("c0");
-          compareAllUsers(this.users);
-        }
-        done();
-      }, 50);
-    });
-    it("Basic get&set of Map property (handle three conflicts)", function(done){
-      var y = this.users[0];
-      this.users[0].root.set("stuff", "c0");
-      this.users[1].root.set("stuff", "c1");
-      this.users[2].root.set("stuff", "c2");
-      this.users[3].root.set("stuff", "c3");
-      y.connector.flushAll();
-
-      setTimeout( () => {
-        for (var key in this.users) {
-          var u = this.users[key];
-          expect(u.root.get("stuff")).toEqual("c0");
-        }
-        compareAllUsers(this.users);
-        done();
-      }, 50);
-    });
-    it("Basic insert in array (handle three conflicts)", function(done){
-      var y = this.users[0];
-      var l1, l2, l3;
-      y.root.set("Array", Y.Array).then((array)=>{
-        l1 = array;
-        y.connector.flushAll();
-        l1.insert(0, [0]);
-        return this.users[1].root.get("Array");
-      }).then((array)=>{
-        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(l2.toArray()).toEqual(l3.toArray());
-        compareAllUsers(this.users);
-        done();
-      });
-    });
-  });
-  describe("Map random tests", function(){
-    var randomMapTransactions = [
-      function set (map) {
-        map.set("somekey", getRandomNumber());
-      },
-      function* delete_ (map) {
-        map.delete("somekey");
-      }
-    ];
-    function compareMapValues(maps){
-      var firstMap;
-      for (var map of maps) {
-        var val = map.get();
-        if (firstMap == null) {
-          firstMap = val;
-        } else {
-          expect(val).toEqual(firstMap);
-        }
-      }
-    }
-    beforeEach(function(done){
-      this.users[0].root.set("Map", Y.Map);
-      this.users[0].connector.flushAll();
-
-      var then = Promise.resolve();
-      var maps = [];
-      for (var u of this.users) {
-        then = then.then(function(){ //eslint-disable-line
-          return u.root.get("Map");
-        }).then(function(map){//eslint-disable-line
-          maps.push(map);
-        });
-      }
-      this.maps = maps;
-      then.then(function(){
-        done();
-      });
-    });
-    it(`succeed after ${numberOfYMapTests} actions`, function(done){
-      applyRandomTransactions(this.users, this.maps, randomMapTransactions, numberOfYMapTests);
-      setTimeout(()=>{
-        compareAllUsers(this.users);
-        compareMapValues(this.maps);
-        done();
-      }, 500);
-    });
-  });
-
-  var numberOfYArrayTests = 10;
-  describe("Array random tests", function(){
-    var randomMapTransactions = [
-      function insert (array) {
-        array.insert(getRandomNumber(array.toArray().length), [getRandomNumber()]);
-      }
-    ];
-    function compareArrayValues(arrays){
-      var firstArray;
-      for (var l of arrays) {
-        var val = l.toArray();
-        if (firstArray == null) {
-          firstArray = val;
-        } else {
-          expect(val).toEqual(firstArray);
-        }
-      }
-    }
-    beforeEach(function(done){
-      this.users[0].root.set("Array", Y.Array);
-      this.users[0].connector.flushAll();
-
-      var then = Promise.resolve();
-      var arrays = [];
-      for (var u of this.users) {
-        then = then.then(function(){ //eslint-disable-line
-          return u.root.get("Array");
-        }).then(function(array){//eslint-disable-line
-          arrays.push(array);
-        });
-      }
-      this.arrays = arrays;
-      then.then(function(){
-        done();
-      });
-    });
-    it("arrays.length equals users.length", function(){
-      expect(this.arrays.length).toEqual(this.users.length);
-    });
-    it(`succeed after ${numberOfYArrayTests} actions`, function(done){
-      applyRandomTransactions(this.users, this.arrays, randomMapTransactions, numberOfYArrayTests);
-      setTimeout(()=>{
-        compareAllUsers(this.users);
-        compareArrayValues(this.arrays);
-        done();
-      }, 500);
-    });
-  });
-});