diff --git a/etc/arangodb/arangod.conf.in b/etc/arangodb/arangod.conf.in index 84754e14dc..98c22e26d9 100644 --- a/etc/arangodb/arangod.conf.in +++ b/etc/arangodb/arangod.conf.in @@ -40,7 +40,7 @@ threads = 3 [javascript] startup-directory = @PKGDATADIR@/js action-directory = @PKGDATADIR@/js/actions -modules-path = @PKGDATADIR@/js/server/modules;@PKGDATADIR@/js/common/modules;@PKGDATADIR@/js/node-0.11.0 +modules-path = @PKGDATADIR@/js/server/modules;@PKGDATADIR@/js/common/modules;@PKGDATADIR@/js/node app-path = @PKGDATADIR@/js/apps [ruby] diff --git a/etc/arangodb/arangosh.conf.in b/etc/arangodb/arangosh.conf.in index fb0710fa1e..8769acfca1 100644 --- a/etc/arangodb/arangosh.conf.in +++ b/etc/arangodb/arangosh.conf.in @@ -3,4 +3,4 @@ endpoint = tcp://localhost:8529 [javascript] startup-directory = @PKGDATADIR@/js -modules-path = @PKGDATADIR@/js/client/modules;@PKGDATADIR@/js/common/modules;;@PKGDATADIR@/js/node-0.11.0 +modules-path = @PKGDATADIR@/js/client/modules;@PKGDATADIR@/js/common/modules;;@PKGDATADIR@/js/node diff --git a/etc/relative/arangod.conf b/etc/relative/arangod.conf index d8250717ae..8dfc37e8e2 100644 --- a/etc/relative/arangod.conf +++ b/etc/relative/arangod.conf @@ -16,7 +16,7 @@ threads = 3 [javascript] startup-directory = ./js action-directory = ./js/actions -modules-path = ./js/server/modules;./js/common/modules;.js/node-0.11.0 +modules-path = ./js/server/modules;./js/common/modules;.js/node app-path = ./js/apps [ruby] diff --git a/etc/relative/arangosh.conf b/etc/relative/arangosh.conf index 8892bf9c8b..96e3cbf458 100644 --- a/etc/relative/arangosh.conf +++ b/etc/relative/arangosh.conf @@ -1,3 +1,3 @@ [javascript] startup-directory = ./js -modules-path = ./js/client/modules;./js/common/modules;./js/node-0.11.0 +modules-path = ./js/client/modules;./js/common/modules;./js/node diff --git a/js/common/bootstrap/module-fs.js b/js/common/bootstrap/module-fs.js index 170149f36d..e2424918f7 100644 --- a/js/common/bootstrap/module-fs.js +++ b/js/common/bootstrap/module-fs.js @@ -32,7 +32,7 @@ /// /// Parts of the code are based on: /// -// Copyright Joyent, Inc. and other Node contributors. +/// Copyright Joyent, Inc. and other Node contributors. /// /// Permission is hereby granted, free of charge, to any person obtaining a /// copy of this software and associated documentation files (the diff --git a/js/common/modules/util.js b/js/common/modules/util.js new file mode 100644 index 0000000000..9b77892622 --- /dev/null +++ b/js/common/modules/util.js @@ -0,0 +1,93 @@ +/*jslint indent: 2, maxlen: 120, vars: true, white: true, plusplus: true, regexp: true, nonpropdel: true, sloppy: true */ +/*global require, FS_MAKE_DIRECTORY, FS_MOVE, FS_REMOVE, FS_REMOVE_DIRECTORY, FS_LIST, + FS_REMOVE_RECURSIVE_DIRECTORY, FS_EXISTS, FS_IS_DIRECTORY, FS_IS_FILE, FS_FILESIZE, + FS_GET_TEMP_FILE, FS_GET_TEMP_PATH, FS_LIST_TREE, FS_UNZIP_FILE, FS_ZIP_FILE, + SYS_READ, SYS_SAVE, PATH_SEPARATOR, HOME */ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief node helper module "utils" +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany +/// +/// Licensed 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. +/// +/// Copyright holder is triAGENS GmbH, Cologne, Germany +/// +/// @author Dr. Frank Celler +/// @author Copyright 2010-2013, triAGENS GmbH, Cologne, Germany +/// +/// Parts of the code are based on: +/// +/// Copyright Joyent, Inc. and other Node contributors. +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the +/// "Software"), to deal in the Software without restriction, including +/// without limitation the rights to use, copy, modify, merge, publish, +/// distribute, sublicense, and/or sell copies of the Software, and to permit +/// persons to whom the Software is furnished to do so, subject to the +/// following conditions: +/// +/// The above copyright notice and this permission notice shall be included +/// in all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +/// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +/// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +/// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +/// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +/// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +/// USE OR OTHER DEALINGS IN THE SOFTWARE. +//////////////////////////////////////////////////////////////////////////////// + +// ----------------------------------------------------------------------------- +// --SECTION-- Module "uitls" +// ----------------------------------------------------------------------------- + +// ----------------------------------------------------------------------------- +// --SECTION-- public functions +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @addtogroup Node +/// @{ +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +/// @brief inherits the prototype methods from one constructor into another. +//////////////////////////////////////////////////////////////////////////////// + +exports.inherits = function(ctor, superCtor) { + ctor.super_ = superCtor; + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); +}; + +// ----------------------------------------------------------------------------- +// --SECTION-- END-OF-FILE +// ----------------------------------------------------------------------------- + +// Local Variables: +// mode: outline-minor +// outline-regexp: "/// @brief\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}\\|/\\*jslint" +// End: diff --git a/js/node/assert.js b/js/node/assert.js new file mode 100644 index 0000000000..a2afdcfb0b --- /dev/null +++ b/js/node/assert.js @@ -0,0 +1,334 @@ +// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 +// +// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! +// +// Originally from narwhal.js (http://narwhaljs.org) +// Copyright (c) 2009 Thomas Robinson <280north.com> +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the 'Software'), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// UTILITY +var util = require('util'); +var pSlice = Array.prototype.slice; + +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = module.exports = ok; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({ message: message, +// actual: actual, +// expected: expected }) + +assert.AssertionError = function AssertionError(options) { + this.name = 'AssertionError'; + this.message = options.message; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + var stackStartFunction = options.stackStartFunction || fail; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, stackStartFunction); + } +}; + +// assert.AssertionError instanceof Error +util.inherits(assert.AssertionError, Error); + +function replacer(key, value) { + if (value === undefined) { + return '' + value; + } + if (typeof value === 'number' && (isNaN(value) || !isFinite(value))) { + return value.toString(); + } + if (typeof value === 'function' || value instanceof RegExp) { + return value.toString(); + } + return value; +} + +function truncate(s, n) { + if (typeof s == 'string') { + return s.length < n ? s : s.slice(0, n); + } else { + return s; + } +} + +assert.AssertionError.prototype.toString = function() { + if (this.message) { + return [this.name + ':', this.message].join(' '); + } else { + return [ + this.name + ':', + truncate(JSON.stringify(this.actual, replacer), 128), + this.operator, + truncate(JSON.stringify(this.expected, replacer), 128) + ].join(' '); + } +}; + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. + +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} + +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; + +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, !!guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. + +function ok(value, message) { + if (!!!value) fail(value, true, message, '==', assert.ok); +} +assert.ok = ok; + +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, '==', assert.equal); +}; + +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); + +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, '!=', assert.notEqual); + } +}; + +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); + +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, 'deepEqual', assert.deepEqual); + } +}; + +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) { + if (actual.length != expected.length) return false; + + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; + } + + return true; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (actual instanceof Date && expected instanceof Date) { + return actual.getTime() === expected.getTime(); + + // 7.3 If the expected value is a RegExp object, the actual value is + // equivalent if it is also a RegExp object with the same source and + // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). + } else if (actual instanceof RegExp && expected instanceof RegExp) { + return actual.source === expected.source && + actual.global === expected.global && + actual.multiline === expected.multiline && + actual.lastIndex === expected.lastIndex && + actual.ignoreCase === expected.ignoreCase; + + // 7.4. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (typeof actual != 'object' && typeof expected != 'object') { + return actual == expected; + + // 7.5 For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} + +function isUndefinedOrNull(value) { + return value === null || value === undefined; +} + +function isArguments(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv(a, b) { + if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) + return false; + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + //~~~I've managed to break Object.keys through screwy arguments passing. + // Converting to array solves the problem. + if (isArguments(a)) { + if (!isArguments(b)) { + return false; + } + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + try { + var ka = Object.keys(a), + kb = Object.keys(b), + key, i; + } catch (e) {//happens when one is a string literal and the other isn't + return false; + } + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key])) return false; + } + return true; +} + +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); + +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); + } +}; + +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); + +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, '===', assert.strictEqual); + } +}; + +// 10. The strict non-equality assertion tests for strict inequality, as +// determined by !==. assert.notStrictEqual(actual, expected, message_opt); + +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, '!==', assert.notStrictEqual); + } +}; + +function expectedException(actual, expected) { + if (!actual || !expected) { + return false; + } + + if (Object.prototype.toString.call(expected) == '[object RegExp]') { + return expected.test(actual); + } else if (actual instanceof expected) { + return true; + } else if (expected.call({}, actual) === true) { + return true; + } + + return false; +} + +function _throws(shouldThrow, block, expected, message) { + var actual; + + if (typeof expected === 'string') { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + + (message ? ' ' + message : '.'); + + if (shouldThrow && !actual) { + fail(actual, expected, 'Missing expected exception' + message); + } + + if (!shouldThrow && expectedException(actual, expected)) { + fail(actual, expected, 'Got unwanted exception' + message); + } + + if ((shouldThrow && actual && expected && + !expectedException(actual, expected)) || (!shouldThrow && actual)) { + throw actual; + } +} + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert.throws = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); +}; + +assert.ifError = function(err) { if (err) {throw err;}};