Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' of github.com:Abacus/Abacus
- Loading branch information
Showing
8 changed files
with
184 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
(function( window, Abacus ) { | ||
|
||
var entities = {}; | ||
|
||
// Express the Entity function | ||
function Entity( options ) { | ||
|
||
var hooks; | ||
|
||
// If no options.type, default to player | ||
options.type = options.type || 'player'; | ||
|
||
// If no options.id, provide default | ||
options.id = options.id || Abacus.guid(); | ||
|
||
hooks = Entity.hooks[ options.type ] || {}; | ||
|
||
// Extend a reasonable set of defaults with | ||
// any hooks that may exist, with the | ||
// options argument onto fresh target object | ||
this.attributes = Abacus.extend({}, hooks, options ); | ||
} | ||
|
||
// Setup the Entity prototype with methods for opperating | ||
// on entity instances | ||
Entity.prototype = { | ||
// Serialize the entity | ||
toJSON: function() { | ||
return JSON.stringify( this.attributes ); | ||
}, | ||
// Get the value of an entity's property. | ||
get: function( prop ) { | ||
return this.attributes[ prop ]; | ||
}, | ||
// Returns `true` if the property contains a value that is not null | ||
// or undefined. | ||
has: function( prop ) { | ||
// Use native syntax or raw speed | ||
return typeof this.attributes[ prop ] !== 'undefined'; | ||
}, | ||
// Set a property on an entity's attributes | ||
set: function( prop, value ) { | ||
|
||
// Check arg type and set accordingly | ||
if ( typeof prop === 'object' ) { | ||
// Directly extend `this.attributes` if `prop` arg is an | ||
// object argument of key/vals | ||
Abacus.extend( this.attributes, prop ); | ||
} else { | ||
this.attributes[ prop ] = value; | ||
} | ||
|
||
return this; | ||
}, | ||
// Remove a property from the entity | ||
unset: function( prop ) { | ||
delete this.attributes[prop]; | ||
return this; | ||
} | ||
}; | ||
|
||
// Special methods and data to extend specific types | ||
Entity.hooks = { | ||
// type: { methods } | ||
player: { | ||
achievements: [] | ||
} | ||
}; | ||
|
||
Abacus.entity = function( options ) { | ||
// Ensure that id duplication is prohibited | ||
if ( options.id && entities[ options.id ] ) { | ||
throw new Error( 'Cannot create entity; id in use: ' + options.id ); | ||
} | ||
|
||
// Create new Entity instance | ||
var entity = new Entity( options ); | ||
|
||
// Cache entity reference in memory | ||
entities[ options.id ] = entity; | ||
|
||
// Return new entity | ||
return entity; | ||
}; | ||
|
||
// Allow for custom hooks | ||
Abacus.entity.hooks = Entity.hooks; | ||
|
||
// Attach static functions | ||
|
||
// Returns instances from cache by id | ||
Abacus.entity.get = function( id ) { | ||
return id ? entities[ id ] : entities; | ||
}; | ||
|
||
// Removes all instances from cache | ||
Abacus.entity.flush = function() { | ||
entities = []; | ||
}; | ||
|
||
})( this, this.Abacus ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
module('Entity'); | ||
|
||
test('Abacus.entity() exists and is a function', 2, function() { | ||
ok( Abacus.entity, 'Abacus.entity exists' ); | ||
equal( typeof Abacus.entity, 'function', 'Abacus.entity is a function' ); | ||
}); | ||
|
||
test('Abacus.entity() creates entities', 4, function() { | ||
|
||
var attributes = { name: 'player', type: 'enemy', id: 'asd' }, | ||
player = Abacus.entity(attributes); | ||
|
||
ok( player, 'Abacus.entity({}) does not return null/undefined' ); | ||
|
||
Object.keys( attributes ).forEach(function( key ) { | ||
equal( player.get( key ), attributes[ key ], 'Instance has correct value per key' ); | ||
}); | ||
}); | ||
|
||
test('Abacus.entity constructs a player correctly', 18, function() { | ||
var player = Abacus.entity({ name: 'player' }); | ||
|
||
equal( typeof player.attributes.achievements, 'object', 'achievements exists on player and is an object' ); | ||
equal( typeof player.get, 'function', 'get exists on player and is a function' ); | ||
equal( typeof player.has, 'function', 'has exists on player and is a function' ); | ||
equal( typeof player.set, 'function', 'set exists on player and is a function' ); | ||
equal( typeof player.toJSON, 'function', 'toJSON exists on player and is a function' ); | ||
equal( typeof player.unset, 'function', 'unset exists on player and is a function' ); | ||
equal( player.attributes.id.length, 36, 'id exists on player and is 36 characters long' ); | ||
ok( player.attributes.name, 'the name property was properly merged onto the player object' ); | ||
|
||
equal( player.get('name'), 'player', 'Test get method to return correct value' ); | ||
equal( player.get('id').length, 36, 'test that get id returns a 36 char string' ); | ||
equal( player.has('name'), true, 'check that has method returns true for prop that is expected to exist' ); | ||
equal( player.set('foo', 'bar').get('foo'), 'bar', 'check that setting foo as bar and then getting foo returns bar' ); | ||
equal( player.has('foo'), true, 'check that has foo is true' ); | ||
equal( player.get('foo'), 'bar', 'check that get foo returns bar' ); | ||
equal( player.unset('foo').has('foo'), false, 'check that unset foo and then has foo is false' ); | ||
equal( player.has('foo'), false, 'check that has foo is false' ); | ||
equal( typeof player.toJSON(), 'string', 'check that toJSON returns a string' ); | ||
|
||
deepEqual( JSON.parse( player.toJSON() ), player.attributes, 'JSON roundstrip' ); | ||
}); |