Skip to content

Commit eb55bf0

Browse files
committed
Passing test for createNode
1 parent 087a41b commit eb55bf0

File tree

12 files changed

+111
-118
lines changed

12 files changed

+111
-118
lines changed

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
dist
22
node_modules
33
package-lock.json
4-
test/.design.js
5-
test/.quick.js
4+
test/.test

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"request": "launch",
2121
"name": "AVA specific",
2222
"program": "${workspaceFolder}/node_modules/ava/profile.js",
23-
"args": ["test/djson_escape.js"],
23+
"args": ["test/createNode.js"],
2424
"skipFiles": ["<node_internals>/**/*.js"]
2525
}
2626
]

src/api/applyPatchFactory.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ export default function applyPatchFactory(patchers) {
2828

2929
destiny[prop] = isPlainObject(origin_value) // immutable
3030
? applyPatch({}, origin_value).result
31-
: isArray(origin_value) // Shall we merge arrays or just copy? Don't know
32-
? merge([], origin_value)
31+
: isArray(origin_value)
32+
? merge([], origin_value) // Shall we merge arrays or just copy? Don't know
3333
: origin_value
3434

3535
oldValue = patchers.reduce(

src/api/createNodeFactory.js

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
import { isFunction, isInteger, is, isArray } from '../util/is'
1+
import { isFunction, isInteger, isArray } from '../util/is'
22
import createRequest from '../util/createRequest'
33
import localProcedureCall from '../util/localProcedureCall'
4+
import converter from '../util/converter'
45
import { NAME_REMOTE_FUNCTION } from '../const'
6+
import { getUniqueKey } from '../util/get'
57

6-
export default function createNodeFactory(DJSON) {
7-
const Func = DJSON.Function
8-
const stringify = DJSON.stringify
9-
const parse = DJSON.parse
10-
11-
return function createNode() {
8+
export default function createNodeFactory({ encoders, decoders }) {
9+
return function createNode({
10+
serialize = v => v,
11+
deserialize = v => v
12+
} = {}) {
1213
const requests = {}
1314
const local_functions_id = {}
1415
const local_functions_map = new Map()
@@ -35,7 +36,7 @@ export default function createNodeFactory(DJSON) {
3536
req.node = api
3637
req.destroy = () => delete requests[request_id]
3738
requests[request_id] = req
38-
api.send(stringify(data, stringifyReplacer))
39+
api.send(serialize(encode(data)))
3940
return req
4041
}
4142
Object.defineProperty(f, 'name', {
@@ -56,12 +57,11 @@ export default function createNodeFactory(DJSON) {
5657

5758
function message(msg) {
5859
// console.log(api.ENV, msg)
59-
const tof = is(msg)
60-
if (api.opened && tof == 'string' && msg[0] === '[') {
60+
if (api.opened) {
6161
try {
62-
msg = parse(msg, parseReplacer)
62+
msg = decode(deserialize(msg))
6363
} catch (e) {
64-
// Invalid array to parse
64+
// Invalid array to deserialize or decode
6565
return false
6666
}
6767

@@ -78,10 +78,10 @@ export default function createNodeFactory(DJSON) {
7878
req.then(value => {
7979
response.push(0) // no errors
8080
if (value !== undefined) response.push(value)
81-
api.send(stringify(response, stringifyReplacer))
81+
api.send(serialize(encode(response)))
8282
}).catch(error => {
8383
response.push(error) // error
84-
api.send(stringify(response, stringifyReplacer))
84+
api.send(serialize(encode(response)))
8585
})
8686
args = isArray(args) ? args : []
8787
args.push(req)
@@ -109,23 +109,33 @@ export default function createNodeFactory(DJSON) {
109109
api.opened = false
110110
}
111111

112-
function stringifyReplacer(key, f) {
113-
if (Func.isValidToStringify(f) && f.name !== NAME_REMOTE_FUNCTION) {
114-
const function_id = local_functions_map.has(f)
115-
? local_functions_map.get(f)
116-
: registerLocalFunction(f)
117-
return Func.stringifyReplacer(function_id)
112+
function encode(object) {
113+
const encodeFunction = ({ value }) => {
114+
if (isFunction(value)) {
115+
if (value.name === NAME_REMOTE_FUNCTION) return null
116+
const function_id = local_functions_map.has(value)
117+
? local_functions_map.get(value)
118+
: registerLocalFunction(value)
119+
return { ['$function']: function_id }
120+
}
121+
return value
118122
}
119-
return f
123+
return converter(object, encoders.concat(encodeFunction))
120124
}
121125

122-
function parseReplacer(key, value) {
123-
if (Func.isValidToParse(value)) {
124-
const function_id = value[Func.key]
125-
const f = remote_functions_id[function_id]
126-
return isFunction(f) ? f : createRemoteFunction(function_id)
126+
function decode(object) {
127+
const decodeFunction = ({ value }) => {
128+
if (
129+
getUniqueKey(value) === '$function' &&
130+
isInteger(value['$function'])
131+
) {
132+
const function_id = value['$function']
133+
const f = remote_functions_id[function_id]
134+
return isFunction(f) ? f : createRemoteFunction(function_id)
135+
}
136+
return value
127137
}
128-
return value
138+
return converter(object, decoders.concat(decodeFunction))
129139
}
130140

131141
const api = {

src/const.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export const NAME_REMOTE_FUNCTION = '~dopRemoteFunction'
22

33
export const ESCAPE_KEY = '$escape'
44
export const DELETE_KEY = '$delete'
5+
export const FUNCTION_KEY = '$function'

src/index.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ import Delete from './types/Delete'
99
function factory() {
1010
const TYPE = { Delete }
1111
const patchers = [Delete.patch]
12-
const encode = (object, encoders = [Delete.encode]) =>
13-
converter(object, encoders)
14-
const decode = (object, decoders = [Delete.decode]) =>
15-
converter(object, decoders)
12+
const encoders = [Delete.encode]
13+
const decoders = [Delete.decode]
14+
const encode = (object, list = encoders) => converter(object, list)
15+
const decode = (object, list = decoders) => converter(object, list)
1616

1717
const applyPatch = applyPatchFactory(patchers)
1818
const createStore = createStoreFactory(applyPatch)
19-
const createNode = createNodeFactory(TYPE)
19+
const createNode = createNodeFactory({ encoders, decoders })
2020

2121
return {
2222
factory,

src/types/Delete.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Delete.patch = function({ destiny, prop, oldValue, had_prop }) {
1717
return oldValue
1818
}
1919

20-
Delete.encode = function({ value, origin, destiny, prop }) {
20+
Delete.encode = function({ value }) {
2121
if (value instanceof Delete) {
2222
return { [DELETE_KEY]: 1 } // we don't go deeper
2323
} else if (isValidToDecode({ value })) {
@@ -26,7 +26,7 @@ Delete.encode = function({ value, origin, destiny, prop }) {
2626
return value
2727
}
2828

29-
Delete.decode = function({ value, origin, destiny, prop }) {
29+
Delete.decode = function({ value }) {
3030
if (isValidToDecode({ value })) {
3131
return new Delete()
3232
} else if (

src/types/Function.js

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,15 @@
11
import { getUniqueKey } from '../util/get'
22
import { isInteger, isFunction } from '../util/is'
3+
import { FUNCTION_KEY, ESCAPE_KEY } from '../const'
34

4-
export default function factoryFunction({ types }) {
5-
const key = '$function'
5+
const Func = {}
66

7-
// Constructor/Creator
8-
function Func() {}
7+
Func.encode = function({ value, origin, destiny, prop }) {}
98

10-
// Mandatory
11-
Func.key = key
9+
Func.decode = function({ value, origin, destiny, prop }) {}
1210

13-
// Mandatory
14-
Func.isValidToStringify = function(value) {
15-
return isFunction(value)
16-
}
11+
function isValidToDecode({ value }) {}
1712

18-
// Mandatory
19-
Func.stringify = function(value) {
20-
// We ignore this because will be replaced on createNode
21-
return value
22-
}
13+
function isValidToEscape({ value }) {}
2314

24-
// Mandatory
25-
Func.isValidToParse = function(value) {
26-
const unique_key = getUniqueKey(value, types)
27-
return unique_key === key && isInteger(value[key])
28-
}
29-
30-
// Mandatory
31-
Func.parse = function(value) {
32-
// We ignore this because will be replaced on createNode
33-
return value
34-
}
35-
36-
Func.stringifyReplacer = function(function_id) {
37-
return { [key]: function_id }
38-
}
39-
40-
return Func
41-
}
15+
export default Func

src/util/converter.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import forEachObject from '../util/forEachObject'
22
import { mergeMutator } from '../util/merge'
3+
import { isArray } from '../util/is'
34

4-
export default function converter(object, converters) {
5-
const destiny = {}
5+
export default function converter(origin, converters) {
6+
const destiny = isArray(origin) ? [] : {}
67
forEachObject(
7-
object,
8+
origin,
89
({ origin, prop, destiny, path }) => {
910
const value = converters.reduce(
1011
(value, converter) =>

test/api.js

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
1-
import test from 'ava'
2-
import dop from '../'
3-
import { createNode, isRemoteFunction } from '../'
4-
5-
const exported = [
6-
'factory',
7-
'merge',
8-
'encode',
9-
'decode',
10-
'applyPatch',
11-
'createNode',
12-
'createStore',
13-
'TYPE',
14-
'isRemoteFunction'
15-
]
16-
17-
test('Checking exported params', function(t) {
18-
t.deepEqual(Object.keys(dop), exported)
19-
})
20-
21-
test('Checking factory', function(t) {
22-
const dopcopy = dop.factory()
23-
t.deepEqual(Object.keys(dop), Object.keys(dopcopy))
24-
t.is(dop.factory, dopcopy.factory)
25-
t.not(dop.createNode, dopcopy.createNode)
26-
})
27-
28-
test('isRemoteFunction', async t => {
29-
const node = createNode()
30-
const callClient = node.open()
31-
t.is(callClient.name, '~dopRemoteFunction')
32-
t.true(isRemoteFunction(callClient))
33-
t.false(isRemoteFunction(() => {}))
34-
t.false(isRemoteFunction('other'))
35-
})
1+
import test from 'ava'
2+
import dop from '../'
3+
import { createNode, isRemoteFunction } from '../'
4+
5+
const exported = [
6+
'factory',
7+
'merge',
8+
'encode',
9+
'decode',
10+
'applyPatch',
11+
'createNode',
12+
'createStore',
13+
'TYPE',
14+
'isRemoteFunction'
15+
]
16+
17+
test('Checking exported params', function(t) {
18+
t.deepEqual(Object.keys(dop), exported)
19+
})
20+
21+
test('Checking factory', function(t) {
22+
const dopcopy = dop.factory()
23+
t.deepEqual(Object.keys(dop), Object.keys(dopcopy))
24+
t.is(dop.factory, dopcopy.factory)
25+
t.not(dop.createNode, dopcopy.createNode)
26+
})
27+
28+
test('isRemoteFunction', async t => {
29+
const node = createNode()
30+
const callClient = node.open()
31+
t.is(callClient.name, '~dopRemoteFunction')
32+
t.true(isRemoteFunction(callClient))
33+
t.false(isRemoteFunction(() => {}))
34+
t.false(isRemoteFunction('other'))
35+
})

0 commit comments

Comments
 (0)