Skip to content

Commit 7439ae3

Browse files
bigmontz2hdddg
authored andcommitted
test-backend: Move nativeToCypher, cypherToNative and ResultObserver to their own files
The change was done to improve the readability of the main.js. This pr also implement the cypherToNative for Float and Null and nativeToCypher for Bool and Int (which were not working properly)
1 parent b13ca42 commit 7439ae3

File tree

3 files changed

+153
-140
lines changed

3 files changed

+153
-140
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
const neo4j = require('neo4j-driver')
2+
3+
export function valueResponse (name, value) {
4+
return { name: name, data: { value: value } }
5+
}
6+
7+
export function nativeToCypher (x) {
8+
if (x == null) {
9+
return valueResponse('CypherNull', null)
10+
}
11+
switch (typeof x) {
12+
case 'number':
13+
if (Number.isInteger(x)) {
14+
return valueResponse('CypherInt', x)
15+
}
16+
break
17+
case 'string':
18+
return valueResponse('CypherString', x)
19+
case 'boolean':
20+
return valueResponse('CypherBool', x)
21+
case 'object':
22+
console.log(x)
23+
if (neo4j.isInt(x)) {
24+
// TODO: Broken!!!
25+
console.log(x)
26+
return valueResponse('CypherInt', x.toInt())
27+
}
28+
if (Array.isArray(x)) {
29+
const values = x.map(nativeToCypher)
30+
return valueResponse('CypherList', values)
31+
}
32+
if (x instanceof neo4j.types.Node) {
33+
const node = {
34+
id: nativeToCypher(x.identity),
35+
labels: nativeToCypher(x.labels),
36+
props: nativeToCypher(x.properties)
37+
}
38+
return { name: 'CypherNode', data: node }
39+
}
40+
// If all failed, interpret as a map
41+
const map = {}
42+
for (const [key, value] of Object.entries(x)) {
43+
map[key] = nativeToCypher(value)
44+
}
45+
return valueResponse('CypherMap', map)
46+
}
47+
console.log(`type of ${x} is ${typeof x}`)
48+
const err = 'Unable to convert ' + x + ' to cypher type'
49+
console.log(err)
50+
throw Error(err)
51+
}
52+
53+
export function cypherToNative (c) {
54+
const {
55+
name,
56+
data: { value }
57+
} = c
58+
switch (name) {
59+
case 'CypherString':
60+
return value
61+
case 'CypherInt':
62+
return value
63+
case 'CypherFloat':
64+
return value + 0.0
65+
case 'CypherNull':
66+
return value
67+
}
68+
console.log(`Type ${name} is not handle by cypherToNative`, c)
69+
const err = 'Unable to convert ' + c + ' to native type'
70+
console.log(err)
71+
throw Error(err)
72+
}

testkit-backend/main.js

Lines changed: 2 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -1,146 +1,8 @@
11
var neo4j = require('neo4j-driver')
22
var net = require('net')
33
var readline = require('readline')
4-
5-
function valueResponse (name, value) {
6-
return { name: name, data: { value: value } }
7-
}
8-
9-
function nativeToCypher (x) {
10-
if (x == null) {
11-
return valueResponse('CypherNull', null)
12-
}
13-
switch (typeof x) {
14-
case 'number':
15-
if (Number.isInteger(x)) {
16-
return valueResponse('CypherNull', x)
17-
}
18-
break
19-
case 'string':
20-
return valueResponse('CypherString', x)
21-
case 'object':
22-
if (neo4j.isInt(x)) {
23-
// TODO: Broken!!!
24-
return valueResponse('CypherInt', x.toInt())
25-
}
26-
if (Array.isArray(x)) {
27-
const values = x.map(nativeToCypher)
28-
return valueResponse('CypherList', values)
29-
}
30-
if (x instanceof neo4j.types.Node) {
31-
const node = {
32-
id: nativeToCypher(x.identity),
33-
labels: nativeToCypher(x.labels),
34-
props: nativeToCypher(x.properties)
35-
}
36-
return { name: 'CypherNode', data: node }
37-
}
38-
// If all failed, interpret as a map
39-
const map = {}
40-
for (const [key, value] of Object.entries(x)) {
41-
map[key] = nativeToCypher(value)
42-
}
43-
return valueResponse('CypherMap', map)
44-
}
45-
46-
const err = 'Unable to convert ' + x + ' to cypher type'
47-
console.log(err)
48-
throw Error(err)
49-
}
50-
51-
function cypherToNative (c) {
52-
const {
53-
name,
54-
data: { value }
55-
} = c
56-
switch (name) {
57-
case 'CypherString':
58-
return value
59-
case 'CypherInt':
60-
return value
61-
}
62-
const err = 'Unable to convert ' + c + ' to native type'
63-
console.log(err)
64-
throw Error(err)
65-
}
66-
67-
class ResultObserver {
68-
constructor () {
69-
this.keys = null
70-
this._stream = []
71-
this.summary = null
72-
this._err = null
73-
this._promise = null
74-
this.onKeys = this.onKeys.bind(this)
75-
this.onNext = this.onNext.bind(this)
76-
this.onCompleted = this.onCompleted.bind(this)
77-
this.onError = this.onError.bind(this)
78-
}
79-
80-
onKeys (keys) {
81-
this.keys = keys
82-
}
83-
84-
onNext (record) {
85-
this._stream.push(record)
86-
this._fulfill()
87-
}
88-
89-
onCompleted (summary) {
90-
this._summary = summary
91-
this._fulfill()
92-
}
93-
94-
onError (e) {
95-
this._stream.push(e)
96-
this._fulfill()
97-
}
98-
99-
// Returns a promise, only one outstanding next!
100-
next () {
101-
return new Promise((resolution, rejection) => {
102-
this._promise = {
103-
resolve: resolution,
104-
reject: rejection
105-
}
106-
this._fulfill()
107-
})
108-
}
109-
110-
_fulfill () {
111-
if (!this._promise) {
112-
return
113-
}
114-
115-
// The stream contains something
116-
if (this._stream.length) {
117-
const x = this._stream.shift()
118-
if (!(x instanceof neo4j.types.Record)) {
119-
// For further calls, use this (stream should be empty after this)
120-
this._err = x
121-
this._promise.reject(x)
122-
this._promise = null
123-
return
124-
}
125-
this._promise.resolve(x)
126-
this._promise = null
127-
return
128-
}
129-
130-
// There has been an error, continue to return that error
131-
if (this._err) {
132-
this._promise.reject(this._err)
133-
this._promise = null
134-
return
135-
}
136-
137-
// All records have been received
138-
if (this._summary) {
139-
this._promise.resolve(null)
140-
this._promise = null
141-
}
142-
}
143-
}
4+
const { nativeToCypher, cypherToNative } = require('./cypher-native-binders')
5+
const { ResultObserver } = require('./result-observer')
1446

1457
class Backend {
1468
constructor ({ writer }) {

testkit-backend/result-observer.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
const neo4j = require('neo4j-driver')
2+
3+
export class ResultObserver {
4+
constructor () {
5+
this.keys = null
6+
this._stream = []
7+
this.summary = null
8+
this._err = null
9+
this._promise = null
10+
this.onKeys = this.onKeys.bind(this)
11+
this.onNext = this.onNext.bind(this)
12+
this.onCompleted = this.onCompleted.bind(this)
13+
this.onError = this.onError.bind(this)
14+
}
15+
16+
onKeys (keys) {
17+
this.keys = keys
18+
}
19+
20+
onNext (record) {
21+
this._stream.push(record)
22+
this._fulfill()
23+
}
24+
25+
onCompleted (summary) {
26+
this._summary = summary
27+
this._fulfill()
28+
}
29+
30+
onError (e) {
31+
this._stream.push(e)
32+
this._fulfill()
33+
}
34+
35+
// Returns a promise, only one outstanding next!
36+
next () {
37+
return new Promise((resolution, rejection) => {
38+
this._promise = {
39+
resolve: resolution,
40+
reject: rejection
41+
}
42+
this._fulfill()
43+
})
44+
}
45+
46+
_fulfill () {
47+
if (!this._promise) {
48+
return
49+
}
50+
51+
// The stream contains something
52+
if (this._stream.length) {
53+
const x = this._stream.shift()
54+
if (!(x instanceof neo4j.types.Record)) {
55+
// For further calls, use this (stream should be empty after this)
56+
this._err = x
57+
this._promise.reject(x)
58+
this._promise = null
59+
return
60+
}
61+
this._promise.resolve(x)
62+
this._promise = null
63+
return
64+
}
65+
66+
// There has been an error, continue to return that error
67+
if (this._err) {
68+
this._promise.reject(this._err)
69+
this._promise = null
70+
return
71+
}
72+
73+
// All records have been received
74+
if (this._summary) {
75+
this._promise.resolve(null)
76+
this._promise = null
77+
}
78+
}
79+
}

0 commit comments

Comments
 (0)