From 3ff1d7779c96002ea455e01a58982ad1850a5948 Mon Sep 17 00:00:00 2001 From: Luke Sneeringer Date: Wed, 29 Mar 2017 09:40:11 -0700 Subject: [PATCH 1/2] Additional Spanner tests. This commit provides tests for every missed line in the spanner package. Additionally, it brings branch coverage to 100% in codec.js and partial-result-stream.js. --- packages/spanner/test/codec.js | 20 ++++ .../spanner/test/partial-result-stream.js | 101 +++++++++++++++--- 2 files changed, 107 insertions(+), 14 deletions(-) diff --git a/packages/spanner/test/codec.js b/packages/spanner/test/codec.js index ddae72fd821..1fcb6f58c8f 100644 --- a/packages/spanner/test/codec.js +++ b/packages/spanner/test/codec.js @@ -441,5 +441,25 @@ describe('codec', function() { assert.strictEqual(encoded, 10); }); + + it('should encode each key in a dictionary-like object', function() { + var obj = { + f: new codec.Float(10), + i: new codec.Int(10), + }; + var encoded = codec.encode(obj); + assert.deepEqual(encoded, {f: 10, i: '10'}); + }); + + it('should only encode public properties of objects', function() { + var obj = { + hasOwnProperty: function(key) { return key === 'public' }, + _private: new codec.Int(10), + public: new codec.Int(10), + } + var encoded = codec.encode(obj); + assert.deepEqual(encoded._private, obj._private); + assert.deepEqual(encoded.public, 10); + }) }); }); diff --git a/packages/spanner/test/partial-result-stream.js b/packages/spanner/test/partial-result-stream.js index d050c18a115..7d2f84fa7c2 100644 --- a/packages/spanner/test/partial-result-stream.js +++ b/packages/spanner/test/partial-result-stream.js @@ -76,6 +76,15 @@ describe('PartialResultStream', function() { {} ] }; + var RESULT_WITHOUT_VALUE = { + resumeToken: '...', + values: [] + } + var RESULT_WITH_MULTIPLE_ROWS = { + metadata: {rowType: {fields: [{name: 'foo'}]}}, + resumeToken: '...', + values: [1, 2], + } before(function() { partialResultStreamModule = proxyquire('../src/partial-result-stream.js', { @@ -134,21 +143,22 @@ describe('PartialResultStream', function() { fakeRequestStream.push(null); }); - it('should not queue more than 10 results', function(done) { - fakeRequestStream.push(RESULT_WITHOUT_TOKEN); // 1 - fakeRequestStream.push(RESULT_WITHOUT_TOKEN); // 2 - fakeRequestStream.push(RESULT_WITHOUT_TOKEN); // 3 - fakeRequestStream.push(RESULT_WITHOUT_TOKEN); // 4 - fakeRequestStream.push(RESULT_WITHOUT_TOKEN); // 5 - - fakeRequestStream.push(RESULT_WITHOUT_TOKEN); // 6 - fakeRequestStream.push(RESULT_WITHOUT_TOKEN); // 7 - fakeRequestStream.push(RESULT_WITHOUT_TOKEN); // 8 - fakeRequestStream.push(RESULT_WITHOUT_TOKEN); // 9 - fakeRequestStream.push(RESULT_WITHOUT_TOKEN); // 10 + it('should effectively skip rows without values', function(done) { + fakeRequestStream.push(RESULT_WITHOUT_VALUE); + fakeRequestStream.push(null); - fakeRequestStream.push(RESULT_WITHOUT_TOKEN); // 11 + partialResultStream + .on('error', done) + .pipe(concat(function(rows) { + assert.strictEqual(rows.length, 0); + done(); + })); + }); + it('should not queue more than 10 results', function(done) { + for (var i = 0; i < 11; i += 1) { + fakeRequestStream.push(RESULT_WITHOUT_TOKEN); + } fakeRequestStream.push(null); partialResultStream @@ -225,6 +235,28 @@ describe('PartialResultStream', function() { })); }); + it('should correctly handle multiple rows', function(done) { + var formattedRows = [[ + {}, + {} + ]]; + + partialResultStreamModule.formatRow_ = function() { + return formattedRows; + }; + + fakeRequestStream.push(RESULT_WITH_TOKEN); + fakeRequestStream.push(null); + + partialResultStream + .on('error', done) + .pipe(concat(function(rows) { + assert.strictEqual(rows[0], formattedRows[0][0]); + assert.strictEqual(rows[1], formattedRows[0][1]); + done(); + })); + }); + it('should resume if there was an error', function(done) { // This test will emit four rows total: // - Two rows @@ -323,6 +355,22 @@ describe('PartialResultStream', function() { partialResultStream.abort(); }); + it('should silently no-op abort if no active request', function(done) { + // If no request is ever made, then there should be no active + // stream to be aborted. + fakeRequestStream.abort = function() { + done(new Error('No request ever made; nothing to abort.')); + }; + + // Create a partial result stream and then abort it, without + // ever sending a request. + var partialResultStream = partialResultStreamModule(function() { + return fakeRequestStream; + }); + partialResultStream.abort(); + done(); + }); + it('should let user abort the most recent request', function(done) { fakeRequestStream.abort = function() { done(new Error('Wrong stream was aborted.')); @@ -384,6 +432,31 @@ describe('PartialResultStream', function() { values: VALUES }; + it('should omit rows from JSON representation with no name', function() { + // Define the second field to have no name. + var row = { + metadata: {rowType: {fields: [ + {name: 'field-1'}, {} + ]}}, + values: ['value-1', 'value-2'], + }; + // Override our `decode` function to pass through the value. + decodeValueOverride = function(value) { + return value; + }; + + // Format the row. + var formattedRows = partialResultStreamModule.formatRow_(row); + + // Both fields should exist in the formattedRows array. + assert.strictEqual(formattedRows.length, 2); + assert.strictEqual(formattedRows[0].value, 'value-1'); + assert.strictEqual(formattedRows[1].value, 'value-2'); + + // Only the field with a name should exist in the JSON serialization. + assert.deepEqual(formattedRows.toJSON(), {'field-1': 'value-1'}); + }); + it('should chunk rows with more values than fields', function() { decodeValueOverride = function(value) { return value; @@ -457,4 +530,4 @@ describe('PartialResultStream', function() { }); }); }); -}); \ No newline at end of file +}); From f6cca186563c850003d3a06fa7abc3b794c14c5f Mon Sep 17 00:00:00 2001 From: Luke Sneeringer Date: Wed, 29 Mar 2017 09:48:31 -0700 Subject: [PATCH 2/2] Address linting issues. --- packages/spanner/test/codec.js | 8 +++++--- packages/spanner/test/partial-result-stream.js | 7 +------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/spanner/test/codec.js b/packages/spanner/test/codec.js index 1fcb6f58c8f..ea49e38d341 100644 --- a/packages/spanner/test/codec.js +++ b/packages/spanner/test/codec.js @@ -453,13 +453,15 @@ describe('codec', function() { it('should only encode public properties of objects', function() { var obj = { - hasOwnProperty: function(key) { return key === 'public' }, + hasOwnProperty: function(key) { // jshint ignore:line + return key === 'public'; + }, _private: new codec.Int(10), public: new codec.Int(10), - } + }; var encoded = codec.encode(obj); assert.deepEqual(encoded._private, obj._private); assert.deepEqual(encoded.public, 10); - }) + }); }); }); diff --git a/packages/spanner/test/partial-result-stream.js b/packages/spanner/test/partial-result-stream.js index 7d2f84fa7c2..3aab249a11b 100644 --- a/packages/spanner/test/partial-result-stream.js +++ b/packages/spanner/test/partial-result-stream.js @@ -79,12 +79,7 @@ describe('PartialResultStream', function() { var RESULT_WITHOUT_VALUE = { resumeToken: '...', values: [] - } - var RESULT_WITH_MULTIPLE_ROWS = { - metadata: {rowType: {fields: [{name: 'foo'}]}}, - resumeToken: '...', - values: [1, 2], - } + }; before(function() { partialResultStreamModule = proxyquire('../src/partial-result-stream.js', {