UNPKG

transactional

Version:

Reactive objects with transactional updates and automatic serialization

268 lines (220 loc) 8.61 kB
var Nested = require( '../nestedtypes' ), sinon = require( 'sinon' ), chai = require( 'chai'), as_promised = require("chai-as-promised"); chai.use( as_promised ); expect = chai.expect; describe( 'One-to-many and many-to-many relations', function(){ var Something = Nested.Model.extend({ attributes : { name : '' } }); var collection = new Something.Collection([ { id: 1, name : 1 }, { id: 2, name : 2 }, { id: 3, name : 3 } ]); describe( 'Attributes merging', function(){ var A = Nested.Model.extend({ defaults : { a : 1, b : 2 }, f : function(){ return this.a + this.b; }, properties : { c : function(){ return this.a + this.b; } } }); it( 'merges properties, which does not present in model', function(){ var B = Nested.Model.extend({ defaults : { a : 6, _x : A.has.proxy() } }); var b = new B(); expect( b.a ).to.eql( 6 ); expect( b.b ).to.eql( 2 ); expect( b.f() ).to.eql( 3 ); expect( b.c ).to.eql( 3 ); }); }); describe( 'Model.from reference', function(){ var A = Nested.Model.extend({ attributes : { ref : Something.from( collection ) } }); it( 'is initialized with null', function(){ var m = new A(); expect( m.ref ).to.be.null; }); it( 'parse model id', function(){ var m = new A({ ref : 1 }); expect( m.ref.name ).to.equal( "1" ); }); it( 'can be assigned with model id', function(){ var m = new A(); m.ref = 1; expect( m.ref.name ).to.equal( "1" ); m.set({ ref: 2 }); expect( m.ref.name ).to.equal( "2" ); }); it( 'can be assigned with model', function(){ var m = new A(); m.ref = collection.first(); expect( m.ref.name ).to.equal( "1" ); }); it( 'is serialized to model id', function(){ var m = new A(); m.ref = collection.first(); var json = m.toJSON(); expect( json.ref ).to.equal( 1 ); }); it( 'can use lazy reference to collection', function(){ var A = Nested.Model.extend({ attributes : { ref : Something.from( function(){ return collection; } ) } }); var m = new A(); m.ref = 1; expect( m.ref.name ).to.equal( "1" ); }); it( 'must return null when not resolved', function(){ var A = Nested.Model.extend({ attributes : { ref : Something.from( function(){ return this.__collection; } ) } }); var m = new A(); m.ref = 1; expect( m.ref ).to.be.null; m.__collection = collection; expect( m.ref.name ).to.equal( "1" ); }); }); describe( 'Collection.subsetOf', function(){ var A = Nested.Model.extend({ attributes : { refs : Something.Collection.subsetOf( collection ) } }); it( 'is initialized with empty collection', function(){ var m = new A(); expect( m.refs.length ).to.equal( 0 ); }); it( 'parse array of model ids', function(){ var m = new A({ refs : [ 1 ] }); expect( m.refs.first().name ).to.equal( "1" ); }); it( 'can be assigned with array of model ids', function(){ var m = new A(); m.refs = [ 1 ]; expect( m.refs.first().name ).to.equal( "1" ); }); it( 'can be assigned with models array', function(){ var m = new A(); m.refs = [ collection.first() ]; expect( m.refs.first().name ).to.equal( "1" ); }); it( 'is serialized to array of model ids', function(){ var m = new A(); m.refs = [ collection.first() ]; var json = m.toJSON(); expect( json.refs[ 0 ] ).to.equal( 1 ); }); it( 'can use lazy reference to collection', function(){ var A = Nested.Model.extend({ attributes : { refs : Something.Collection.subsetOf( function(){ return collection; } ) } }); var m = new A(); m.refs = [ 1 ]; expect( m.refs.first().name ).to.equal( "1" ); }); }); }); describe( 'Nested relations', function(){ var User = Nested.Model.extend({ defaults : { name : '', roles : Nested.Collection.subsetOf( 'store.roles' ) }, collection : { fetch : function(){ this.reset([ { id : 1, name : 'admin', roles : [ 1 ] },{ id : 2, name : 'user', roles : [ 2 ] }], { parse : true }); this.trigger( 'sync', this ); return new Promise(function( resolve, reject ) { resolve('loaded'); }); } } }); var Role = Nested.Model.extend({ defaults : { name : '', users : Nested.Collection.subsetOf( 'store.users' ) }, collection : { fetch : function(){ this.reset([ { id : 1, name : 'Administrators', users : [ 1 ] },{ id : 2, name : 'Users', users : [ 2 ] }], { parse : true }); this.trigger( 'sync', this ); return new Promise(function( resolve, reject ) { resolve('loaded'); }); } } }); it( 'can be initialized with a list of attributes', function(){ var Store = Nested.LazyStore.defaults({ users : User.Collection, roles : Role.Collection }); Nested.store = new Store(); }); it( 'fetch everything when called without arguments', function(){ Nested.store.fetch(); expect( Nested.store._resolved.users ).to.eventually.equal('loaded'); expect( Nested.store._resolved.roles ).to.eventually.equal('loaded'); }); it( 'can be prefetched', function(){ Nested.store.users.fetch(); expect( Nested.store._resolved.users ).to.be.fulfilled.then(function () { expect( Nested.store.users.length ).to.equal( 2 ); }); }); it( 'fetched of the first attributes access', function(){ var role = Nested.store.users.first().roles.first(); expect( Nested.store._resolved.roles ).to.be.fulfilled.then(function () { expect( role.name ).to.equal( 'Administrators' ); }); }); it( 'individual elements can be cleaned up ', function(){ Nested.store.clear( 'users' ); expect( Nested.store._resolved.users ).to.be.not.ok; }); it( 'all cache can be cleaned up ', function(){ Nested.store.clear(); expect( Nested.store._resolved.users ).to.be.not.ok; expect( Nested.store._resolved.roles ).to.be.not.ok; }); });