Skip to content

Commit

Permalink
Add tests and fix issues with finding entities in the store
Browse files Browse the repository at this point in the history
  • Loading branch information
danschultz committed Aug 24, 2011
1 parent 82d96a4 commit 1a5539e
Show file tree
Hide file tree
Showing 13 changed files with 183 additions and 21 deletions.
2 changes: 2 additions & 0 deletions src/mesh/core/object/copy.as
Expand Up @@ -42,6 +42,8 @@ package mesh.core.object
}
} catch (e:ReferenceError) {

} catch (e:TypeError) {

}
}
}
Expand Down
19 changes: 19 additions & 0 deletions src/mesh/model/source/FixtureSource.as
Expand Up @@ -4,10 +4,13 @@ package mesh.model.source
import flash.utils.setTimeout;

import mesh.core.object.merge;
import mesh.core.reflection.newInstance;
import mesh.model.Entity;
import mesh.model.store.Commit;
import mesh.model.store.Query;
import mesh.model.store.Store;

import mx.collections.ArrayList;
import mx.rpc.Fault;

public class FixtureSource extends Source
Expand Down Expand Up @@ -55,6 +58,22 @@ package mesh.model.source
});
}

/**
* @inheritDoc
*/
override public function fetch(store:Store, query:Query):void
{
if (query.entityType == _entityType) {
var entities:Array = [];
for each (var hash:Object in _fixtures) {
var entity:Entity = newInstance(_entityType);
entity.fromObject(hash);
entities.push(entity);
}
store.query.loaded(query, new ArrayList(entities));
}
}

/**
* @inheritDoc
*/
Expand Down
11 changes: 11 additions & 0 deletions src/mesh/model/source/MultiSource.as
Expand Up @@ -6,6 +6,7 @@ package mesh.model.source
import mesh.core.reflection.reflect;
import mesh.model.Entity;
import mesh.model.store.Commit;
import mesh.model.store.Query;
import mesh.model.store.Store;

/**
Expand Down Expand Up @@ -78,6 +79,16 @@ package mesh.model.source
invokeEach(commit, "destroyEach", entities);
}

/**
* @inheritDoc
*/
override public function fetch(store:Store, query:Query):void
{
for each (var source:Source in _mapping) {
source.fetch(store, query);
}
}

/**
* @inheritDoc
*/
Expand Down
2 changes: 1 addition & 1 deletion src/mesh/model/source/Source.as
Expand Up @@ -49,7 +49,7 @@ package mesh.model.source
}
}

public function fetch(query:Query):void
public function fetch(store:Store, query:Query):void
{
throw new IllegalOperationError("EntitySource.fetch() is not implemented.");
}
Expand Down
13 changes: 9 additions & 4 deletions src/mesh/model/store/Queries.as
Expand Up @@ -2,8 +2,6 @@ package mesh.model.store
{
import flash.utils.Dictionary;

import mesh.model.source.Source;

import mx.collections.IList;

/**
Expand Down Expand Up @@ -48,7 +46,12 @@ package mesh.model.store
if (!contains(query)) {
throw new ArgumentError("Query '" + query + "' not found in cache.");
}
results(query).loaded(entities);

if (entities != null) _store.add.apply(null, entities.toArray());

if (query is RemoteQuery) {
results(query).loaded(entities);
}
}

/**
Expand All @@ -61,7 +64,9 @@ package mesh.model.store
internal function results(query:Query):ResultList
{
if (!contains(query)) {
_cache[query] = new ResultList(query, _store).refresh();
var result:ResultList = new ResultList(query, _store);
_cache[query] = result;
result.refresh();
}
return _cache[query];
}
Expand Down
10 changes: 9 additions & 1 deletion src/mesh/model/store/Query.as
Expand Up @@ -50,7 +50,15 @@ package mesh.model.store
*/
public function contains(entity:Entity):Boolean
{
return _condition != null ? _condition(entity) : false;
if (_condition != null) {
return _condition(entity);
}

if (entityType != null) {
return entity.reflect.isA(entityType);
}

return false;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/mesh/model/store/ResultList.as
Expand Up @@ -79,7 +79,7 @@ package mesh.model.store
*/
public function refresh():ResultList
{
_store.dataSource.fetch(_query);
_store.dataSource.fetch(_store, _query);

if (_query is LocalQuery) {
createList(_store.index.findByType(_query.entityType));
Expand Down
24 changes: 21 additions & 3 deletions tests/mesh/Address.as
@@ -1,8 +1,14 @@
package mesh
{
public class Address
import flash.utils.IDataInput;
import flash.utils.IDataOutput;
import flash.utils.IExternalizable;

[RemoteClass(alias="mesh.Address")]

public class Address implements IExternalizable
{
public function Address(street:String, city:String)
public function Address(street:String = "", city:String = "")
{
_street = street;
_city = city;
Expand All @@ -11,7 +17,19 @@ package mesh
public function equals(address:Address):Boolean
{
return street == address.street &&
city == address.city;
city == address.city;
}

public function readExternal(input:IDataInput):void
{
_street = input.readUTF();
_city = input.readUTF();
}

public function writeExternal(output:IDataOutput):void
{
output.writeUTF(street);
output.writeUTF(city);
}

private var _street:String;
Expand Down
16 changes: 11 additions & 5 deletions tests/mesh/Customer.as
@@ -1,6 +1,6 @@
package mesh
{
import mesh.core.object.copy;
import mesh.core.object.merge;
import mesh.model.validators.PresenceValidator;

import mx.collections.IList;
Expand All @@ -27,11 +27,17 @@ package mesh
hasMany("orders", {inverse:"customer", isMaster:true});
}

override public function toObject(options:Object = null):Object
override public function fromObject(object:Object):void
{
var result:Object = super.toObject();
copy(this, result, {includes:["address", "accountId"]});
return result;
super.fromObject(object);
address = object.address != null ? new Address(object.address.street, object.address.city) : null;
}

override protected function get serializableOptions():Object
{
var inherited:Object = super.serializableOptions;
inherited.includes = merge(inherited.includes, {address:true});
return inherited;
}
}
}
22 changes: 20 additions & 2 deletions tests/mesh/Name.as
@@ -1,8 +1,14 @@
package mesh
{
public class Name
import flash.utils.IDataInput;
import flash.utils.IDataOutput;
import flash.utils.IExternalizable;

[RemoteClass(alias="mesh.Name")]

public class Name implements IExternalizable
{
public function Name(firstName:String, lastName:String)
public function Name(firstName:String = "", lastName:String = "")
{
_firstName = firstName;
_lastName = lastName;
Expand All @@ -13,6 +19,18 @@ package mesh
return firstName == name.firstName && lastName == name.lastName;
}

public function readExternal(input:IDataInput):void
{
_firstName = input.readUTF();
_lastName = input.readUTF();
}

public function writeExternal(output:IDataOutput):void
{
output.writeUTF(firstName);
output.writeUTF(lastName);
}

private var _firstName:String;
public function get firstName():String
{
Expand Down
16 changes: 16 additions & 0 deletions tests/mesh/Person.as
Expand Up @@ -21,5 +21,21 @@ package mesh
{
super(properties);
}

override public function fromObject(object:Object):void
{
super.fromObject(object);
name = object.name != null ? new Name(object.name.firstName, object.name.lastName) : null;
}

override protected function get serializableOptions():Object
{
return {
exclude:["state", "storeKey"],
includes:{
name:true
}
};
}
}
}
6 changes: 2 additions & 4 deletions tests/mesh/model/serialization/SerializerTests.as
Expand Up @@ -43,7 +43,7 @@ package mesh.model.serialization
[Test]
public function testSerializeUnnested():void
{
var serialized:Object = _customer.serialize();
var serialized:Object = _customer.serialize({});

assertThat(serialized.id, equalTo(_customer.id));
assertThat(serialized.age, equalTo(_customer.age));
Expand Down Expand Up @@ -76,9 +76,7 @@ package mesh.model.serialization
{
var serialized:Object = _customer.serialize({
includes:{
name:{
only:["firstName", "lastName"]
},
name:true,
address:{only:["street"]},
orders:{
includes:{
Expand Down
61 changes: 61 additions & 0 deletions tests/mesh/model/store/FindTests.as
@@ -0,0 +1,61 @@
package mesh.model.store
{
import mesh.Name;
import mesh.Person;
import mesh.model.source.FixtureSource;
import mesh.model.source.MultiSource;

import org.flexunit.assertThat;
import org.hamcrest.collection.array;
import org.hamcrest.object.equalTo;
import org.hamcrest.object.hasProperties;

public class FindTests
{
private var _jimmyPage:Person;
private var _robertPlant:Person;
private var _store:Store;

[Before]
public function setup():void
{
_jimmyPage = new Person({
age: 67,
name: new Name("Jimmy", "Page")
});
_robertPlant = new Person({
age: 63,
name: new Name("Robert", "Plant")
});

var multiSource:MultiSource = new MultiSource();
multiSource.map(Person, new FixtureSource(Person, {latency:0}));

var tempStore:Store = new Store(multiSource);
tempStore.add(_jimmyPage);
tempStore.add(_robertPlant);
tempStore.commit();

// Start fresh with an empty store.
_store = new Store(multiSource);
}

[Test]
public function testFindEntity():void
{
var customer:Person = _store.find(Person, _jimmyPage.id);
assertThat(customer.id, equalTo(_jimmyPage.id));
assertThat(customer.name, hasProperties({firstName:_jimmyPage.name.firstName, lastName:_jimmyPage.name.lastName}));
}

[Test]
public function testFindQuery():void
{
var result:ResultList = _store.find(new LocalQuery().on(Person));
var results:Array = result.toArray();
assertThat(results.length, equalTo(2));
assertThat(results, array(hasProperties({id:_jimmyPage.id, name:hasProperties({firstName:_jimmyPage.name.firstName, lastName:_jimmyPage.name.lastName})}),
hasProperties({id:_robertPlant.id, name:hasProperties({firstName:_robertPlant.name.firstName, lastName:_robertPlant.name.lastName})})));
}
}
}

0 comments on commit 1a5539e

Please sign in to comment.