diff --git a/lib/datastore.js b/lib/datastore.js index 1b6dc7b..f6b1aa0 100644 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -1,8 +1,6 @@ /** * The datastore itself * TODO - * Improve serialization (for types such as Dates, handle new lines in strings) - * Serialization and deserialization functions * Queue inserts, removes and updates * Update and removes should only modify the corresponding part of the database */ diff --git a/lib/model.js b/lib/model.js index a931f9a..1dffdba 100644 --- a/lib/model.js +++ b/lib/model.js @@ -4,10 +4,15 @@ * Copying */ -var dateToJSON = function () { return { $$date: this.toString() }; } +var dateToJSON = function () { return { $$date: this.getTime() }; } , originalDateToJSON = Date.prototype.toJSON - +/** + * Serialize an object to be persisted to a one-line string + * Accepted primitive types: Number, String, Boolean, Date, null + * Accepted secondary types: Objects, Arrays + * TODO: throw an error if variable name begins with '$' + */ function serialize (obj) { var res; @@ -27,6 +32,11 @@ function serialize (obj) { return res; } + +/** + * From a one-line representation of an object generate by the serialize function + * Return the object itself + */ function deserialize (rawData) { return JSON.parse(rawData, function (k, v) { if (k === '$$date') { return new Date(v); } @@ -39,10 +49,6 @@ function deserialize (rawData) { - - - // Interface module.exports.serialize = serialize; module.exports.deserialize = deserialize; - diff --git a/test/model.test.js b/test/model.test.js new file mode 100644 index 0000000..3997053 --- /dev/null +++ b/test/model.test.js @@ -0,0 +1,90 @@ +var model = require('../lib/model') + , should = require('chai').should() + , assert = require('chai').assert + , _ = require('underscore') + , async = require('async') + ; + + +describe('Model', function () { + + describe('Serialization, deserialization', function () { + + it('Can serialize and deserialize strings', function (done) { + var a, b, c; + + a = { test: "Some string" }; + b = model.serialize(a); + c = model.deserialize(b); + b.indexOf('\n').should.equal(-1); + c.test.should.equal("Some string"); + + // Even if a property is a string containing a new line, the serialized + // version doesn't. The new line must still be there upon deserialization + a = { test: "With a new\nline" }; + b = model.serialize(a); + c = model.deserialize(b); + c.test.should.equal("With a new\nline"); + a.test.indexOf('\n').should.not.equal(-1); + b.indexOf('\n').should.equal(-1); + c.test.indexOf('\n').should.not.equal(-1); + + done(); + }); + + it('Can serialize and deserialize booleans', function (done) { + var a, b, c; + + a = { test: true }; + b = model.serialize(a); + c = model.deserialize(b); + b.indexOf('\n').should.equal(-1); + c.test.should.equal(true); + c.test.should.not.equal('true'); + + done(); + }); + + it('Can serialize and deserialize numbers', function (done) { + var a, b, c; + + a = { test: 5 }; + b = model.serialize(a); + c = model.deserialize(b); + b.indexOf('\n').should.equal(-1); + c.test.should.equal(5); + c.test.should.not.equal('5'); + + done(); + }); + + it('Can serialize and deserialize null', function (done) { + var a, b, c; + + a = { test: null }; + b = model.serialize(a); + c = model.deserialize(b); + b.indexOf('\n').should.equal(-1); + assert.isNull(a.test); + + done(); + }); + + it('Can serialize and deserialize a date', function (done) { + var a, b, c + , d = new Date(); + + a = { test: d }; + b = model.serialize(a); + c = model.deserialize(b); + b.indexOf('\n').should.equal(-1); + c.test.constructor.name.should.equal('Date'); + c.test.getTime().should.equal(d.getTime()); + + done(); + }); + + + }); // ==== End of 'Serialization, deserialization' ==== // + +});