Merge pull request #65 from yosimasu/feature/json-string-packer
Support JSONStringPacker
This commit is contained in:
commit
a812e4648a
|
@ -0,0 +1,94 @@
|
|||
// Copyright IBM Corp. 2014,2016. All Rights Reserved.
|
||||
// Node module: loopback-connector
|
||||
// This file is licensed under the MIT License.
|
||||
// License text available at https://opensource.org/licenses/MIT
|
||||
|
||||
'use strict';
|
||||
|
||||
var createPromiseCallback = require('./utils').createPromiseCallback;
|
||||
|
||||
module.exports = JSONStringPacker;
|
||||
|
||||
var ISO_DATE_REGEXP = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*))(?:Z|(\+|-)([\d|:]*))?$/;
|
||||
|
||||
/**
|
||||
* Create a new Packer instance that can be used to convert between JavaScript
|
||||
* objects and a JsonString representation in a String.
|
||||
*
|
||||
* @param {String} encoding Buffer encoding refer to https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings
|
||||
*/
|
||||
function JSONStringPacker(encoding) {
|
||||
this.encoding = encoding || 'base64';
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the provided value to a `JsonString`.
|
||||
*
|
||||
* @param {*} value Any value (string, number, object)
|
||||
* @callback {Function} cb The callback to receive the parsed result.
|
||||
* @param {Error} err
|
||||
* @param {Buffer} data The encoded value
|
||||
* @promise
|
||||
*/
|
||||
JSONStringPacker.prototype.encode = function(value, cb) {
|
||||
var encoding = this.encoding;
|
||||
|
||||
cb = cb || createPromiseCallback();
|
||||
try {
|
||||
var data = JSON.stringify(value, function(key, value) {
|
||||
if (Buffer.isBuffer(this[key])) {
|
||||
return {
|
||||
type: 'Buffer',
|
||||
data: this[key].toString(encoding),
|
||||
};
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
});
|
||||
|
||||
setImmediate(function() {
|
||||
cb(null, data);
|
||||
});
|
||||
} catch (err) {
|
||||
setImmediate(function() {
|
||||
cb(err);
|
||||
});
|
||||
}
|
||||
return cb.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decode the JsonString value back to a JavaScript value.
|
||||
* @param {String} jsonString The JsonString input.
|
||||
* @callback {Function} cb The callback to receive the composed value.
|
||||
* @param {Error} err
|
||||
* @param {*} value Decoded value.
|
||||
* @promise
|
||||
*/
|
||||
JSONStringPacker.prototype.decode = function(jsonString, cb) {
|
||||
var encoding = this.encoding;
|
||||
|
||||
cb = cb || createPromiseCallback();
|
||||
try {
|
||||
var value = JSON.parse(jsonString, function(k, v) {
|
||||
if (v && v.type && v.type === 'Buffer') {
|
||||
return new Buffer(v.data, encoding);
|
||||
}
|
||||
|
||||
if (ISO_DATE_REGEXP.exec(v)) {
|
||||
return new Date(v);
|
||||
}
|
||||
|
||||
return v;
|
||||
});
|
||||
|
||||
setImmediate(function() {
|
||||
cb(null, value);
|
||||
});
|
||||
} catch (err) {
|
||||
setImmediate(function() {
|
||||
cb(err);
|
||||
});
|
||||
}
|
||||
return cb.promise;
|
||||
};
|
|
@ -0,0 +1,72 @@
|
|||
// Copyright IBM Corp. 2016. All Rights Reserved.
|
||||
// Node module: loopback-connector
|
||||
// This file is licensed under the MIT License.
|
||||
// License text available at https://opensource.org/licenses/MIT
|
||||
|
||||
'use strict';
|
||||
|
||||
var JSONStringPacker = require('../lib/json-string-packer');
|
||||
var expect = require('chai').expect;
|
||||
|
||||
describe('JSONStringPacker', function() {
|
||||
var packer;
|
||||
|
||||
beforeEach(function createPacker() {
|
||||
packer = new JSONStringPacker();
|
||||
});
|
||||
|
||||
describe('encode()', function() {
|
||||
it('supports invocation with a callback', function(done) {
|
||||
packer.encode('a-value', done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('decode()', function() {
|
||||
it('supports invocation with a callback', function(done) {
|
||||
packer.encode('a-value', function(err, jsonString) {
|
||||
if (err) return done(err);
|
||||
packer.decode(jsonString, function(err, result) {
|
||||
if (err) return done(err);
|
||||
expect(result).to.eql('a-value');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('roundtrip', function() {
|
||||
var TEST_CASES = {
|
||||
String: 'a-value',
|
||||
Object: { a: 1, b: 2 },
|
||||
Buffer: new Buffer([1, 2, 3]),
|
||||
Date: new Date('2016-08-03T11:53:03.470Z'),
|
||||
Integer: 12345,
|
||||
Float: 12.345,
|
||||
Boolean: false,
|
||||
};
|
||||
|
||||
Object.keys(TEST_CASES).forEach(function(tc) {
|
||||
it('works for ' + tc + ' values', function() {
|
||||
var value = TEST_CASES[tc];
|
||||
return encodeAndDecode(value)
|
||||
.then(function(result) {
|
||||
expect(result).to.eql(value);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('works for nested properties', function() {
|
||||
return encodeAndDecode(TEST_CASES)
|
||||
.then(function(result) {
|
||||
expect(result).to.eql(TEST_CASES);
|
||||
});
|
||||
});
|
||||
|
||||
function encodeAndDecode(value) {
|
||||
return packer.encode(value)
|
||||
.then(function(binary) {
|
||||
return packer.decode(binary);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue