diff --git a/packages/testkit-backend/src/request-handlers.js b/packages/testkit-backend/src/request-handlers.js index 34b09b206..0b3064c7d 100644 --- a/packages/testkit-backend/src/request-handlers.js +++ b/packages/testkit-backend/src/request-handlers.js @@ -125,7 +125,6 @@ export function SessionRun (context, data, wire) { .then(_ => { const result = session.run(cypher, params, { metadata, timeout }) const resultObserver = new ResultObserver({ sessionId, result }) - result.subscribe(resultObserver) const id = context.addResultObserver(resultObserver) wire.writeResponse('Result', { id }) }) @@ -169,6 +168,22 @@ export function ResultConsume (context, data, wire) { .catch(e => wire.writeError(e)) } +export function ResultList (context, data, wire) { + const { resultId } = data + + const resultObserver = context.getResultObserver(resultId) + const result = resultObserver.result + + result + .then(({ records }) => { + const cypherRecords = records.map(rec => { + return { values: Array.from(rec.values()).map(nativeToCypher) } + }) + wire.writeResponse('RecordList', { records: cypherRecords}) + }) + .catch(error => wire.writeError(error)) +} + export function SessionReadTransaction (context, data, wire) { const { sessionId, txMeta: metadata } = data const session = context.getSession(sessionId) @@ -194,7 +209,6 @@ export function TransactionRun (context, data, wire) { } const result = tx.tx.run(cypher, params) const resultObserver = new ResultObserver({ result }) - result.subscribe(resultObserver) const id = context.addResultObserver(resultObserver) wire.writeResponse('Result', { id }) } @@ -285,6 +299,7 @@ export function GetFeatures (_context, _params, wire) { 'Feature:Bolt:4.2', 'Feature:Bolt:4.3', 'Feature:Bolt:4.4', + 'Feature:API:Result.List', ...SUPPORTED_TLS ] }) diff --git a/packages/testkit-backend/src/result-observer.js b/packages/testkit-backend/src/result-observer.js index c899f55e2..5d5b6d4b2 100644 --- a/packages/testkit-backend/src/result-observer.js +++ b/packages/testkit-backend/src/result-observer.js @@ -14,6 +14,7 @@ export default class ResultObserver { this.onCompleted = this.onCompleted.bind(this) this.onError = this.onError.bind(this) this._completitionPromise = null + this._subscribed = false } onKeys (keys) { @@ -39,8 +40,13 @@ export default class ResultObserver { this._completitionPromise = null } + get result () { + return this._result + } + // Returns a promise, only one outstanding next! next () { + this._subscribe() return new Promise((resolve, reject) => { this._promise = { resolve, @@ -51,6 +57,7 @@ export default class ResultObserver { } completitionPromise () { + this._subscribe() return new Promise((resolve, reject) => { if (this._summary) { resolve(this._summary) @@ -110,4 +117,11 @@ export default class ResultObserver { promise.reject(err) } } + + _subscribe () { + if (!this._subscribed) { + this._result.subscribe(this) + this._subscribed = true + } + } } diff --git a/packages/testkit-backend/src/skipped-tests.js b/packages/testkit-backend/src/skipped-tests.js index d78c49684..778acf6c3 100644 --- a/packages/testkit-backend/src/skipped-tests.js +++ b/packages/testkit-backend/src/skipped-tests.js @@ -94,6 +94,18 @@ const skippedTests = [ ifEquals( 'neo4j.sessionrun.TestSessionRun.test_partial_iteration' ) + ), + skip( + 'Driver does not support mixing Result.subscribe with Result.then', + ifEquals( + 'stub.iteration.test_result_list.TestResultList.test_tx_run_result_list_pulls_all_records_at_once_next_before_list' + ), + ifEquals( + 'stub.iteration.test_result_list.TestResultList.test_tx_func_result_list_pulls_all_records_at_once_next_before_list' + ), + ifEquals( + 'stub.iteration.test_result_list.TestResultList.test_session_run_result_list_pulls_all_records_at_once_next_before_list' + ) ) ]