From c519a4722395b83f322d97ad680b2be90ed50e6d Mon Sep 17 00:00:00 2001 From: kpdecker Date: Wed, 22 Jun 2016 08:07:03 -0500 Subject: [PATCH] Add support for sparse javascript objects For objects, silently drop undefined fields. For arrays, convert undefined entries to null. (Supporting true undefined values in arrays would require protocol changes, so null seems good enough for now) Related to #91 --- src/v1/internal/packstream.js | 18 ++++++++++++++---- test/v1/types.test.js | 6 ++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/v1/internal/packstream.js b/src/v1/internal/packstream.js index de9ebc54f..8c0de75fd 100644 --- a/src/v1/internal/packstream.js +++ b/src/v1/internal/packstream.js @@ -96,17 +96,27 @@ class Packer { } else if (x instanceof Array) { this.packListHeader(x.length); for(let i = 0; i < x.length; i++) { - this.pack(x[i]); + this.pack(x[i] === undefined ? null : x[i]); } } else if (x instanceof Structure) { this.packStruct( x.signature, x.fields ); } else if (typeof(x) == "object") { let keys = Object.keys(x); - this.packMapHeader(keys.length); + + let count = 0; + for(let i = 0; i < keys.length; i++) { + if (x[keys[i]] !== undefined) { + count++; + } + } + + this.packMapHeader(count); for(let i = 0; i < keys.length; i++) { let key = keys[i]; - this.packString(key); - this.pack(x[key]); + if (x[key] !== undefined) { + this.packString(key); + this.pack(x[key]); + } } } else { throw newError("Cannot pack this value: " + x); diff --git a/test/v1/types.test.js b/test/v1/types.test.js index e8876334c..664f7eee5 100644 --- a/test/v1/types.test.js +++ b/test/v1/types.test.js @@ -49,6 +49,7 @@ describe('string values', function() { describe('list values', function() { it('should support empty lists ', testVal( [] ) ); + it('should support sparse lists ', testVal( [ undefined, 4 ], [ null, 4 ] ) ); it('should support float lists ', testVal( [ 1,2,3 ] ) ); it('should support boolean lists ', testVal( [ true, false ] ) ); it('should support string lists ', testVal( [ "", "hello!" ] ) ); @@ -59,6 +60,7 @@ describe('list values', function() { describe('map values', function() { it('should support empty maps ', testVal( {} ) ); it('should support basic maps ', testVal( {a:1, b:{}, c:[], d:{e:1}} ) ); + it('should support sparse maps ', testVal( {foo: undefined, bar: null}, {bar: null} ) ); }); describe('node values', function() { @@ -131,14 +133,14 @@ describe('path values', function() { }); }); -function testVal( val ) { +function testVal( val, expected ) { return function( done ) { var driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "neo4j")); var session = driver.session(); session.run("RETURN {val} as v", {val: val}) .then( function( result ) { - expect( result.records[0].get('v') ).toEqual( val ); + expect( result.records[0].get('v') ).toEqual( expected || val ); driver.close(); done(); }).catch(function(err) { console.log(err); });