This is an automated email from the ASF dual-hosted git repository. spmallette pushed a commit to branch TINKERPOP-1959-tp33 in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit a72c6fb8e939b31b2a779aa743daad762d0e5fe6 Author: Matthew Allen <[email protected]> AuthorDate: Sat Sep 1 07:53:13 2018 +0100 Client and Translator classes for better handling of scripts --- .../glv/GraphTraversalSource.template | 11 --- gremlin-javascript/glv/TraversalSource.template | 11 --- .../main/javascript/gremlin-javascript/index.js | 6 +- .../gremlin-javascript/lib/driver/client.js | 65 +++++++++++++ .../lib/driver/driver-remote-connection.js | 17 +--- .../lib/driver/remote-connection.js | 21 +---- .../gremlin-javascript/lib/process/bytecode.js | 67 ------------- .../lib/process/graph-traversal.js | 11 --- .../gremlin-javascript/lib/process/translator.js | 91 ++++++++++++++++++ .../gremlin-javascript/lib/process/traversal.js | 11 --- .../javascript/gremlin-javascript/test/helper.js | 5 + .../test/integration/client-tests.js | 65 +++++++++++++ .../test/integration/traversal-test.js | 18 ---- .../gremlin-javascript/test/unit/eval-test.js | 104 --------------------- .../test/unit/translator-test.js | 61 ++++++++++++ 15 files changed, 297 insertions(+), 267 deletions(-) diff --git a/gremlin-javascript/glv/GraphTraversalSource.template b/gremlin-javascript/glv/GraphTraversalSource.template index 1d3dd5d..58be16c 100644 --- a/gremlin-javascript/glv/GraphTraversalSource.template +++ b/gremlin-javascript/glv/GraphTraversalSource.template @@ -84,17 +84,6 @@ class GraphTraversalSource { return new GraphTraversal(this.graph, new TraversalStrategies(this.traversalStrategies), b); } <% } %> - - - /** - * Send a Gremlin-Groovy script to the server. If a script is not passed in - * then the bytecode instructions will be converted to a script and sent. - * @param {string} script The script to send to server - * @param {array} bindings Map of bindings - */ - eval(script, bindings) { - return (new GraphTraversal(this.graph, new TraversalStrategies(this.traversalStrategies), new Bytecode(this.bytecode))).eval(script, bindings); - } } /** diff --git a/gremlin-javascript/glv/TraversalSource.template b/gremlin-javascript/glv/TraversalSource.template index 9824273..f3c7795 100644 --- a/gremlin-javascript/glv/TraversalSource.template +++ b/gremlin-javascript/glv/TraversalSource.template @@ -79,17 +79,6 @@ class Traversal { } /** - * Send a Gremlin-Groovy script to the server. If a script is not passed in - * then the bytecode instructions will be converted to a script and sent. - * @param {string} script The script to send to server - * @param {array} bindings Map of bindings - */ - eval(script, bindings) { - this.bytecode.addStep('eval', [ script, bindings ]); - return this._applyStrategies().then(() => this._getNext()); - } - - /** * Synchronous iterator of traversers including * @private */ diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/index.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/index.js index c2e810d..ffc7f0c 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/index.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/index.js @@ -29,8 +29,10 @@ const graph = require('./lib/structure/graph'); const gs = require('./lib/structure/io/graph-serializer'); const rc = require('./lib/driver/remote-connection'); const Bytecode = require('./lib/process/bytecode'); +const Translator = require('./lib/process/translator'); const utils = require('./lib/utils'); const DriverRemoteConnection = require('./lib/driver/driver-remote-connection'); +const Client = require('./lib/driver/client'); const Authenticator = require('./lib/driver/auth/authenticator'); const PlainTextSaslAuthenticator = require('./lib/driver/auth/plain-text-sasl-authenticator'); @@ -40,6 +42,7 @@ module.exports = { RemoteStrategy: rc.RemoteStrategy, RemoteTraversal: rc.RemoteTraversal, DriverRemoteConnection: DriverRemoteConnection, + Client: Client, auth: { Authenticator: Authenticator, PlainTextSaslAuthenticator: PlainTextSaslAuthenticator @@ -66,7 +69,8 @@ module.exports = { t: t.t, GraphTraversal: gt.GraphTraversal, GraphTraversalSource: gt.GraphTraversalSource, - statics: gt.statics + statics: gt.statics, + Translator: Translator }, structure: { io: { diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.js new file mode 100644 index 0000000..89d9347 --- /dev/null +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.js @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +'use strict'; + +const DriverRemoteConnection = require('./driver-remote-connection'); +const Bytecode = require('../process/bytecode'); + +class Client extends DriverRemoteConnection { + /** + * Creates a new instance of DriverRemoteConnection. + * @param {String} url The resource uri. + * @param {Object} [options] The connection options. + * @param {Array} [options.ca] Trusted certificates. + * @param {String|Array|Buffer} [options.cert] The certificate key. + * @param {String} [options.mimeType] The mime type to use. + * @param {String|Buffer} [options.pfx] The private key, certificate, and CA certs. + * @param {GraphSONReader} [options.reader] The reader to use. + * @param {Boolean} [options.rejectUnauthorized] Determines whether to verify or not the server certificate. + * @param {String} [options.traversalSource] The traversal source. Defaults to: 'g'. + * @param {GraphSONWriter} [options.writer] The writer to use. + * @param {Authenticator} [options.authenticator] The authentication handler to use. + * @constructor + */ + constructor(url, options) { + super(url, options); + } + + /** override */ + submit(message, bindings) { + if (typeof message === 'string' || message instanceof String) { + const args = { + 'gremlin': message, + 'bindings': bindings, + 'language': 'gremlin-groovy', + 'accept': 'application/json', + 'aliases': { 'g': this.traversalSource } + }; + + return super.submit(null, 'eval', args, null, ''); + } + + if (message instanceof Bytecode) { + return super.submit(message); + } + } + +} + +module.exports = Client; diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js index fb66aae..81d5124 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js @@ -132,22 +132,13 @@ class DriverRemoteConnection extends RemoteConnection { 'op': op || 'bytecode', // if using op eval need to ensure processor stays unset if caller didn't set it. 'processor': (!processor && op !== 'eval') ? 'traversal' : processor, - 'args': this._getArgs(args || { - 'gremlin': this._writer.adaptObject(bytecode) - }, - op - ) + 'args': args || { + 'gremlin': this._writer.adaptObject(bytecode), + 'aliases': { 'g': this.traversalSource } + } }); } - _getArgs(args, op) { - if (args.aliases === undefined) { - args.aliases = { 'g': this.traversalSource }; - } - - return args; - } - _handleMessage(data) { const response = this._reader.read(JSON.parse(data.toString())); if (response.requestId === null || response.requestId === undefined) { diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js index 96db161..c675c42 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js @@ -68,26 +68,7 @@ class RemoteStrategy extends TraversalStrategy { return Promise.resolve(); } - let instructions = traversal.getBytecode(); - let op = 'bytecode'; - let processor = 'traversal'; - let args = null; - - // check if the last instruction is an eval statement - if (instructions.stepInstructions.length && instructions.stepInstructions[instructions.stepInstructions.length-1][0] === 'eval') { - const script = instructions.toScript(); - op = 'eval'; - processor = ''; - args = { - 'gremlin': script.script, - 'bindings': script.bindings, - 'language': 'gremlin-groovy', - 'accept': 'application/json', - }; - instructions = null; - } - - return this.connection.submit(instructions, op, args, null, processor).then(function (remoteTraversal) { + return this.connection.submit(traversal.getBytecode()).then(function (remoteTraversal) { traversal.sideEffects = remoteTraversal.sideEffects; traversal.traversers = remoteTraversal.traversers; }); diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/bytecode.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/bytecode.js index fe96568..e7fdd40 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/bytecode.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/bytecode.js @@ -91,73 +91,6 @@ class Bytecode { (this.stepInstructions.length > 0 ? JSON.stringify(this.stepInstructions) : '') ); } - - /** - * Returns a script representations of the step instructions that can be used by standard eval operation. - * @returns {Object} An object containing a script string and bindings map. - */ - toScript() { - let bindings = {}; - let script = 'g'; - let length = this.stepInstructions.length; - - // if eval was passed a script then simply execute the given script. - if (this.stepInstructions[length - 1][0] === 'eval' - && this.stepInstructions[length - 1][1] !== undefined - && this.stepInstructions[length - 1][1] !== null - ) { - return { - script: this.stepInstructions[length - 1][1], - bindings: this.stepInstructions[length - 1][2] - } - } - - if (this.stepInstructions[length - 1][0] === 'eval') { - this.stepInstructions.pop(); - length = this.stepInstructions.length; - } - - // build the script from the glv instructions. - let paramIdx = 1; - for (let i = 0; i < length; i++) { - const params = this.stepInstructions[i].slice(1); - script = script + '.' + this.stepInstructions[i][0] + '('; - - if (params.length) { - for (let k = 0; k < params.length; k++) { - if (k > 0) { - script = script + ', '; - } - - if (Object(params[k]) === params[k]) { - script = script + params[k].toString(); - } else { - const prop = `p${paramIdx++}`; - script = script + prop; - - if (typeof params[k] === 'number') { - if (Number.isInteger(params[k])) { - bindings[prop] = Number.parseInt(params[k]); - } else { - bindings[prop] = Number.parseFloat(params[k]); - } - } else if (params[k] === undefined) { - bindings[prop] = null; - } else { - bindings[prop] = params[k]; - } - } - } - } - - script = script + ')'; - } - - return { - script, - bindings - }; - } } module.exports = Bytecode; diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js index c73405e..edeb2cb 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js @@ -172,17 +172,6 @@ class GraphTraversalSource { return new GraphTraversal(this.graph, new TraversalStrategies(this.traversalStrategies), b); } - - - /** - * Send a Gremlin-Groovy script to the server. If a script is not passed in - * then the bytecode instructions will be converted to a script and sent. - * @param {string} script The script to send to server - * @param {array} bindings Map of bindings - */ - eval(script, bindings) { - return (new GraphTraversal(this.graph, new TraversalStrategies(this.traversalStrategies), new Bytecode(this.bytecode))).eval(script, bindings); - } } /** diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/translator.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/translator.js new file mode 100644 index 0000000..dfd4b69 --- /dev/null +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/translator.js @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +'use strict'; + +/** + * Class to translate glv bytecode steps into executable Gremlin-Groovy script + */ +class Translator { + constructor(traversalSource) { + this._traversalSource = traversalSource; + } + + getTraversalSource() { + return this._traversalSource; + } + + getTargetLanguage() { + return "gremlin-groovy"; + } + + of(traversalSource) { + this._traversalSource = traversalSource; + } + + /** + * Returns a script representation of the given bytecode instructions. + * @param {Object} bytecode The bytecode object containing step instructions. + * @returns {string} Gremlin-Groovy script + */ + translate(bytecode) { + let script = this._traversalSource; + let instructions = bytecode.stepInstructions; + + // build the script from the glv instructions. + for (let i = 0; i < instructions.length; i++) { + const params = instructions[i].slice(1); + script += '.' + instructions[i][0] + '('; + + if (params.length) { + for (let k = 0; k < params.length; k++) { + if (k > 0) { + script += ', '; + } + + if (Object(params[k]) === params[k]) { + if (params[k].toString() === '[object Object]') { + Object.keys(params[k]).forEach(function(key, index) { + if (index > 0) script += ', '; + script += '(\'' + key + '\', '; + if (params[k][key] instanceof String || typeof params[k][key] === 'string') { + script += '\'' + params[k][key] + '\''; + } else { + script += params[k][key]; + } + script += ')'; + }); + } else { + script += params[k].toString(); + } + } else if (params[k] === undefined) { + script += ''; + } else { + script += '\'' + params[k] + '\''; + } + } + } + + script += ')'; + } + + return script; + } +} + +module.exports = Translator; \ No newline at end of file diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js index 9b88232..5ec2db5 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js @@ -79,17 +79,6 @@ class Traversal { } /** - * Send a Gremlin-Groovy script to the server. If a script is not passed in - * then the bytecode instructions will be converted to a script and sent. - * @param {string} script The script to send to server - * @param {array} bindings Map of bindings - */ - eval(script, bindings) { - this.bytecode.addStep('eval', [ script, bindings ]); - return this._applyStrategies().then(() => this._getNext()); - } - - /** * Synchronous iterator of traversers including * @private */ diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/helper.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/helper.js index 899a8ad..b2a61d2 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/helper.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/helper.js @@ -24,6 +24,7 @@ const os = require('os'); const DriverRemoteConnection = require('../lib/driver/driver-remote-connection'); +const Client = require('../lib/driver/client'); const PlainTextSaslAuthenticator = require('../lib/driver/auth/plain-text-sasl-authenticator'); exports.getConnection = function getConnection(traversalSource) { @@ -37,4 +38,8 @@ exports.getSecureConnectionWithPlainTextSaslAuthenticator = function getConnecti authenticator: authenticator, rejectUnauthorized: false }); +}; + +exports.getClient = function getClient(traversalSource) { + return new Client('ws://localhost:45940/gremlin', { traversalSource: traversalSource }); }; \ No newline at end of file diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/client-tests.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/client-tests.js new file mode 100644 index 0000000..83f4baa --- /dev/null +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/client-tests.js @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +'use strict'; + +const assert = require('assert'); +const Bytecode = require('../../lib/process/bytecode'); +const graphModule = require('../../lib/structure/graph'); +const helper = require('../helper'); + +let connection; + +describe('Client', function () { + before(function () { + connection = helper.getClient('gmodern'); + return connection.open(); + }); + after(function () { + return connection.close(); + }); + describe('#submit()', function () { + it('should send bytecode', function () { + return connection.submit(new Bytecode().addStep('V', []).addStep('tail', [])) + .then(function (response) { + assert.ok(response); + assert.ok(response.traversers); + assert.strictEqual(response.traversers.length, 1); + assert.ok(response.traversers[0].object instanceof graphModule.Vertex); + }); + }); + it('should send and parse a script', function () { + return connection.submit('g.V().tail()') + .then(function (response) { + assert.ok(response); + assert.ok(response.traversers); + assert.strictEqual(response.traversers.length, 1); + assert.ok(response.traversers[0] instanceof graphModule.Vertex); + }); + }); + it('should send and parse a script with bindings', function () { + return connection.submit('x + x', {x: 3}) + .then(function (response) { + assert.ok(response); + assert.ok(response.traversers); + assert.strictEqual(response.traversers[0], 6); + }); + }); + }); +}); \ No newline at end of file diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/traversal-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/traversal-test.js index cfdc4f0..920d998 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/traversal-test.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/traversal-test.js @@ -66,22 +66,4 @@ describe('Traversal', function () { }); }); }); - describe('#eval()', function() { - it('should submit the traversal as a script and return a result', function() { - var g = new Graph().traversal().withRemote(connection); - return g.V().count().eval().then(function (item) { - assert.ok(item); - assert.strictEqual(item.done, true); - assert.strictEqual(typeof item.value, 'number'); - }); - }); - - it('should submit a script and bindings and return a result', function() { - var g = new Graph().traversal().withRemote(connection); - return g.eval('g.V(v1)', { v1: 1 }).then(function (item) { - assert.ok(item); - assert.ok(item.value instanceof Vertex); - }); - }); - }); }); \ No newline at end of file diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/eval-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/eval-test.js deleted file mode 100644 index c3c87fb..0000000 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/eval-test.js +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -'use strict'; - -const assert = require('assert'); -const expect = require('chai').expect; -const graph = require('../../lib/structure/graph'); -const t = require('../../lib/process/traversal'); -const TraversalStrategies = require('../../lib/process/traversal-strategy').TraversalStrategies; -const Bytecode = require('../../lib/process/bytecode'); - -describe('Traversal', function () { - - describe('#getBytecode#toScript()', function () { - it('should add steps and produce valid script representation', function () { - const g = new graph.Graph().traversal(); - const script = g.V().out('created').getBytecode().toScript(); - assert.ok(script); - assert.strictEqual(script.script, 'g.V().out(p1)'); - }); - - it('should add steps and produce valid script representation with parameter bindings', function () { - const g = new graph.Graph().traversal(); - const script = g.addV('name', 'Lilac').getBytecode().toScript(); - assert.ok(script); - assert.strictEqual(script.script, 'g.addV(p1, p2)'); - assert.ok(script.bindings); - assert.deepStrictEqual(script.bindings, { p1: 'name', p2: 'Lilac' }); - }); - - it('should add steps containing enum and produce valid script representation', function () { - const g = new graph.Graph().traversal(); - const script = g.V().order().by('age', t.order.decr).getBytecode().toScript(); - assert.ok(script); - assert.strictEqual(script.script, 'g.V().order().by(p1, decr)'); - }); - - it('should add steps containing a predicate and produce valid script representation', function () { - const g = new graph.Graph().traversal(); - const script = g.V().hasLabel('person').has('age', t.P.gt(30)).getBytecode().toScript(); - assert.ok(script); - assert.strictEqual(script.script, 'g.V().hasLabel(p1).has(p2, gt(30))'); - }); - - it('should take a script and return that script along with passed in bindings', function () { - const g = new graph.Graph().traversal(); - const bytecode = g.addV('name', 'Lilac').getBytecode(); - const script = bytecode.addStep('eval', [ - 'g.addV(\'name\', name).property(\'created\', date)', - { name: 'Lilac', created: '2018-01-01T00:00:00.000z' } - ]).toScript(); - assert.ok(script); - assert.strictEqual(script.script, 'g.addV(\'name\', name).property(\'created\', date)'); - assert.deepStrictEqual(script.bindings, { name: 'Lilac', created: '2018-01-01T00:00:00.000z' }); - }); - }); - - describe('#eval()', function () { - it('should apply the strategies and return a Promise with the iterator item', function () { - const strategyMock = { - apply: function (traversal) { - traversal.traversers = [ new t.Traverser(1, 1), new t.Traverser(2, 1) ]; - return Promise.resolve(); - } - }; - const strategies = new TraversalStrategies(); - strategies.addStrategy(strategyMock); - const traversal = new t.Traversal(null, strategies, new Bytecode()); - return traversal.eval(null, null, null) - .then(function (item) { - assert.strictEqual(item.value, 1); - assert.strictEqual(item.done, false); - return traversal.eval(null, null, null); - }) - .then(function (item) { - assert.strictEqual(item.value, 2); - assert.strictEqual(item.done, false); - return traversal.eval(null, null, null); - }) - .then(function (item) { - assert.strictEqual(item.value, null); - assert.strictEqual(item.done, true); - return traversal.eval(null, null, null); - }); - }); - }); -}); diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/translator-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/translator-test.js new file mode 100644 index 0000000..b5310bf --- /dev/null +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/translator-test.js @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +'use strict'; + +const assert = require('assert'); +const expect = require('chai').expect; +const graph = require('../../lib/structure/graph'); +const t = require('../../lib/process/traversal'); +const TraversalStrategies = require('../../lib/process/traversal-strategy').TraversalStrategies; +const Bytecode = require('../../lib/process/bytecode'); +const Translator = require('../../lib/process/translator'); + +describe('Translator', function () { + + describe('#translate()', function () { + it('should produce valid script representation from bytecode glv steps', function () { + const g = new graph.Graph().traversal(); + const script = new Translator('g').translate(g.V().out('created').getBytecode()); + assert.ok(script); + assert.strictEqual(script, 'g.V().out(\'created\')'); + }); + + it('should produce valid script representation from bytecode glv steps containing parameter bindings', function () { + const g = new graph.Graph().traversal(); + const script = new Translator('g').translate(g.addV({'name': 'Lilac'}).getBytecode()); + assert.ok(script); + assert.strictEqual(script, 'g.addV((\'name\', \'Lilac\'))'); + }); + + it('should produce valid script representation from bytecode glv steps containing enum', function () { + const g = new graph.Graph().traversal(); + const script = new Translator('g').translate(g.V().order().by('age', t.order.decr).getBytecode()); + assert.ok(script); + assert.strictEqual(script, 'g.V().order().by(\'age\', decr)'); + }); + + it('should produce valid script representation from bytecode glv steps containing a predicate', function () { + const g = new graph.Graph().traversal(); + const script = new Translator('g').translate(g.V().hasLabel('person').has('age', t.P.gt(30)).getBytecode()); + assert.ok(script); + assert.strictEqual(script, 'g.V().hasLabel(\'person\').has(\'age\', gt(30))'); + }); + }); +});
