diff --git a/UnitTests/Makefile.unittests b/UnitTests/Makefile.unittests index bab2c44507..9a4dcf0285 100755 --- a/UnitTests/Makefile.unittests +++ b/UnitTests/Makefile.unittests @@ -486,7 +486,7 @@ SHELL_COMMON = \ @top_srcdir@/js/common/tests/shell-errors.js \ @top_srcdir@/js/common/tests/shell-fs.js \ @top_srcdir@/js/common/tests/shell-env.js \ - @top_srcdir@/js/common/tests/shell-foxx-manager-install-spec.js \ + @top_srcdir@/js/common/tests/shell-foxx-manager-install-jasmine-spec.js \ @top_srcdir@/js/common/tests/shell-general-graph.js \ @top_srcdir@/js/common/tests/shell-graph-algorithms.js \ @top_srcdir@/js/common/tests/shell-graph-measurement.js \ @@ -513,7 +513,7 @@ SHELL_COMMON = \ @top_srcdir@/js/common/tests/shell-hash-index-noncluster.js \ @top_srcdir@/js/common/tests/shell-fulltext.js \ @top_srcdir@/js/common/tests/shell-graph.js \ - @top_srcdir@/js/common/tests/shell-query-timecritical-spec.js + @top_srcdir@/js/common/tests/shell-query-timecritical-jasmine-spec.js ################################################################################ ### @brief SHELL SERVER TESTS (BASICS) @@ -535,8 +535,8 @@ SHELL_SERVER_ONLY = \ @top_srcdir@/js/server/tests/shell-foxx-model.js \ @top_srcdir@/js/server/tests/shell-foxx-model-events-spec.js \ @top_srcdir@/js/server/tests/shell-foxx-preprocessor.js \ - @top_srcdir@/js/server/tests/shell-foxx-query-spec.js \ - @top_srcdir@/js/server/tests/shell-foxx-repository-spec.js \ + @top_srcdir@/js/server/tests/shell-foxx-query-jasmine-spec.js \ + @top_srcdir@/js/server/tests/shell-foxx-repository-jasmine-spec.js \ @top_srcdir@/js/server/tests/shell-foxx-template-middleware.js \ @top_srcdir@/js/server/tests/shell-routing.js \ @top_srcdir@/js/server/tests/shell-skiplist-index.js \ diff --git a/js/client/tests/shell-foxx-manager-nightly-spec.js b/js/client/tests/shell-foxx-manager-nightly-jasmine-spec.js similarity index 100% rename from js/client/tests/shell-foxx-manager-nightly-spec.js rename to js/client/tests/shell-foxx-manager-nightly-jasmine-spec.js diff --git a/js/common/modules/@arangodb/mocha-runner.js b/js/common/modules/@arangodb/mocha-runner.js new file mode 100644 index 0000000000..fadf5db828 --- /dev/null +++ b/js/common/modules/@arangodb/mocha-runner.js @@ -0,0 +1,182 @@ +'use strict'; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief ArangoDB Mocha integration +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2016 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 Alan Plum +/// @author Copyright 2016, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +var Module = require('module'); +var ArangoError = require('@arangodb').ArangoError; +var errors = require('@arangodb').errors; +var runTests = require('@arangodb/mocha').run; +var internal = require('internal'); +var print = internal.print; +var colors = internal.COLORS; + +module.exports = function (files, throwOnFail) { + const results = runTests(run, files, 'suite'); + print(); + logSuite(results); + logStats(results.stats); + print(); + if (throwOnFail && results.stats.failures) { + var failure = findSuiteFailure(results); + var error = new Error('Test failure'); + error.cause = failure; + throw error; + } + return results.stats.failures === 0; +}; + +function logStats(stats) { + print( + ( + stats.failures + ? ( + colors.COLOR_RED + + '[FAIL]' + + colors.COLOR_RESET + ) + : ( + colors.COLOR_GREEN + + '[PASS]' + + colors.COLOR_RESET + ) + ) + + ' Completed ' + + colors.COLOR_BOLD_WHITE + + stats.tests + + colors.COLOR_RESET + + ' tests in ' + + colors.COLOR_BOLD_WHITE + + stats.duration + 'ms' + + colors.COLOR_RESET + + ' ( ' + + colors.COLOR_GREEN + + stats.passes + + colors.COLOR_RESET + + ' | ' + + colors.COLOR_RED + + stats.failures + + colors.COLOR_RESET + + ' )' + ); +} + +function logSuite(suite, indentLevel) { + if (!indentLevel) { + indentLevel = 0; + } + if (suite.title) { + print( + indent(indentLevel - 1) + + colors.COLOR_BOLD_WHITE + + suite.title + + colors.COLOR_RESET + ); + } + for (let test of suite.tests) { + if (test.result === 'pass') { + print( + indent(indentLevel) + + colors.COLOR_GREEN + + '[PASS] ' + + test.title + + colors.COLOR_RESET + ); + } else { + print( + indent(indentLevel) + + colors.COLOR_RED + + '[' + test.result.toUpperCase() + '] ' + + test.title + + colors.COLOR_RESET + ); + for (let line of test.err.stack.split(/\n/)) { + print( + indent(indentLevel + 1) + + colors.COLOR_RED + + line + + colors.COLOR_RESET + ); + } + } + } + for (let sub of suite.suites) { + logSuite(sub, indentLevel + 1); + } + if (suite.suites.length) { + print(); + } +} + +function indent(level, indentWith) { + if (!indentWith) { + indentWith = ' '; + } + let padding = ''; + for (let i = 0; i < level; i++) { + padding += indentWith; + } + return padding; +} + +function findSuiteFailure(suite) { + for (let test of suite.tests) { + if (test.result !== 'pass') { + return test.err; + } + } + for (let sub of suite.suites) { + let failure = findSuiteFailure(sub); + if (failure) { + return failure; + } + } +} + +function run(filename, context) { + var module = new Module(filename); + + if (context) { + Object.keys(context).forEach(function (key) { + module.context[key] = context[key]; + }); + } + + try { + module.load(filename); + return module.exports; + } catch(e) { + var err = new ArangoError({ + errorNum: errors.ERROR_FAILED_TO_EXECUTE_SCRIPT.code, + errorMessage: errors.ERROR_FAILED_TO_EXECUTE_SCRIPT.message + + '\nFile: ' + filename + }); + err.stack = e.stack; + err.cause = e; + throw err; + } +} diff --git a/js/common/modules/@arangodb/mocha.js b/js/common/modules/@arangodb/mocha.js new file mode 100644 index 0000000000..18785e82a4 --- /dev/null +++ b/js/common/modules/@arangodb/mocha.js @@ -0,0 +1,216 @@ +'use strict'; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief ArangoDB Mocha integration +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2015-2016 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 Alan Plum +/// @author Copyright 2015-2016, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +var interfaces = require('mocha/lib/interfaces'); +var MochaContext = require('mocha/lib/context'); +var MochaSuite = require('mocha/lib/suite'); +var MochaRunner = require('mocha/lib/runner'); +var BaseReporter = require('mocha/lib/reporters/base'); +var DefaultReporter = require('mocha/lib/reporters/json'); + +function notIn(arr) { + return function (item) { + return arr.indexOf(item) === -1; + }; +} + +function deleteFrom(obj) { + return function (key) { + delete obj[key]; + }; +} + +var reporters = { + stream: StreamReporter, + suite: SuiteReporter, + default: DefaultReporter +}; + +exports.run = function runMochaTests(run, files, reporterName) { + if (!Array.isArray(files)) { + files = [files]; + } + + if (reporterName && !reporters[reporterName]) { + throw new Error( + 'Unknown test reporter: ' + reporterName + + ' Known reporters: ' + Object.keys(reporters).join(', ') + ); + } + + var suite = new MochaSuite('', new MochaContext()); + + Object.keys(interfaces).forEach(function (key) { + interfaces[key](suite); + }); + + var options = {}; + var mocha = {options: options}; + + // Clean up after chai.should(), etc + var globals = Object.getOwnPropertyNames(global); + var objectProps = Object.getOwnPropertyNames(Object.prototype); + // Monkeypatch process.stdout.write for mocha's JSON reporter + var _stdoutWrite = global.process.stdout.write; + global.process.stdout.write = function () {}; + + var Reporter = reporterName ? reporters[reporterName] : reporters.default; + var reporter, runner; + + try { + files.forEach(function (file) { + var context = {}; + suite.emit('pre-require', context, file, mocha); + suite.emit('require', run(file, context), file, mocha); + suite.emit('post-require', global, file, mocha); + }); + + runner = new MochaRunner(suite, false); + reporter = new Reporter(runner, options); + runner.run(); + } finally { + Object.getOwnPropertyNames(global) + .filter(notIn(globals)) + .forEach(deleteFrom(global)); + Object.getOwnPropertyNames(Object.prototype) + .filter(notIn(objectProps)) + .forEach(deleteFrom(Object.prototype)); + global.process.stdout.write = _stdoutWrite; + } + + return runner.testResults || reporter.stats; +}; + +function StreamReporter(runner) { + var self = this; + BaseReporter.call(this, runner); + var items = []; + var total = runner.total; + runner.on('start', function () { + items.push(['start', {total: total}]); + }); + runner.on('pass', function (test) { + var t = clean(test); + delete t.err; + items.push(['pass', t]); + }); + runner.on('fail', function (test, err) { + var t = clean(test); + t.err = err.message; + items.push(['fail', t]); + }); + runner.on('end', function () { + items.push(['end', self.stats]); + }); + runner.testResults = items; +} + +function SuiteReporter(runner) { + var self = this; + BaseReporter.call(this, runner); + var suites = []; + var currentSuite; + runner.on('suite', function (suite) { + var s = { + title: suite.title, + tests: [], + suites: [] + }; + suites.unshift(s); + if (currentSuite) { + currentSuite.suites.push(s); + } + currentSuite = s; + }); + runner.on('suite end', function () { + var last = suites.shift(); + currentSuite = suites[0] || last; + }); + runner.on('pending', function (test) { + var t = clean(test); + delete t.fullTitle; + t.result = 'pending'; + currentSuite.tests.push(t); + }); + runner.on('pass', function (test) { + var t = clean(test); + delete t.fullTitle; + t.result = 'pass'; + currentSuite.tests.push(t); + }); + runner.on('fail', function (test) { + var t = clean(test); + delete t.fullTitle; + t.result = 'fail'; + currentSuite.tests.push(t); + }); + runner.on('end', function () { + runner.testResults = { + stats: self.stats, + suites: currentSuite ? currentSuite.suites : [], + tests: currentSuite ? currentSuite.tests : [] + }; + }); +} + +// via https://github.com/mochajs/mocha/blob/c6747a/lib/reporters/json.js +// Copyright (c) 2011-2015 TJ Holowaychuk +// The MIT License + +/** + * Return a plain-object representation of `test` + * free of cyclic properties etc. + * + * @param {Object} test + * @return {Object} + * @api private + */ + +function clean(test) { + return { + title: test.title, + fullTitle: test.fullTitle(), + duration: test.duration, + err: errorJSON(test.err || {}) + }; +} + +/** + * Transform `error` into a JSON object. + * @param {Error} err + * @return {Object} + */ + +function errorJSON(err) { + var res = {}; + Object.getOwnPropertyNames(err).forEach(function(key) { + res[key] = err[key]; + }, err); + return res; +} diff --git a/js/common/modules/@arangodb/testrunner.js b/js/common/modules/@arangodb/testrunner.js index 42c84f8a80..1ad45cc3fe 100644 --- a/js/common/modules/@arangodb/testrunner.js +++ b/js/common/modules/@arangodb/testrunner.js @@ -56,7 +56,7 @@ function runJSUnityTests(tests) { } //////////////////////////////////////////////////////////////////////////////// -/// @brief runs all jsunity tests +/// @brief runs all jasmine tests //////////////////////////////////////////////////////////////////////////////// function runJasmineTests(testFiles, options) { @@ -70,6 +70,21 @@ function runJasmineTests(testFiles, options) { return result; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief runs all mocha tests +//////////////////////////////////////////////////////////////////////////////// + +function runMochaTests(testFiles) { + var result = true; + + if (testFiles.length > 0) { + print('\nRunning Mocha Tests: ' + testFiles.join(', ')); + result = require('@arangodb/mocha-runner')(testFiles); + } + + return result; +} + //////////////////////////////////////////////////////////////////////////////// /// @brief runs tests from command-line //////////////////////////////////////////////////////////////////////////////// @@ -80,13 +95,22 @@ function runCommandLineTests(opts) { jasmineReportFormat = options.jasmineReportFormat || 'progress', unitTests = internal.unitTests(), isSpecRegEx = /.+-spec.*\.js/, + isJasmineRegEx = /.+-jasmine-spec.*\.js/, isSpec = function (unitTest) { return isSpecRegEx.test(unitTest); }, - jasmine = _.filter(unitTests, isSpec), - jsUnity = _.reject(unitTests, isSpec); + isJasmine = function (unitTest) { + return isJasmineRegEx.test(unitTest); + }, + jasmine = _.filter(unitTests, isJasmine), + jsUnity = _.reject(unitTests, isSpec), + mocha = _.reject(_.filter(unitTests, isSpec), isJasmine); - result = runJSUnityTests(jsUnity) && runJasmineTests(jasmine, { format: jasmineReportFormat }); + result = ( + runJSUnityTests(jsUnity) + && runJasmineTests(jasmine, { format: jasmineReportFormat }) + && runMochaTests(mocha) + ); internal.setUnitTestsResult(result); } diff --git a/js/common/tests/shell-foxx-manager-install-spec.js b/js/common/tests/shell-foxx-manager-install-jasmine-spec.js similarity index 100% rename from js/common/tests/shell-foxx-manager-install-spec.js rename to js/common/tests/shell-foxx-manager-install-jasmine-spec.js diff --git a/js/common/tests/shell-query-timecritical-spec.js b/js/common/tests/shell-query-timecritical-jasmine-spec.js similarity index 100% rename from js/common/tests/shell-query-timecritical-spec.js rename to js/common/tests/shell-query-timecritical-jasmine-spec.js diff --git a/js/server/modules/@arangodb/aql-helper.js b/js/server/modules/@arangodb/aql-helper.js index 8552ff986c..dc8c625f82 100644 --- a/js/server/modules/@arangodb/aql-helper.js +++ b/js/server/modules/@arangodb/aql-helper.js @@ -243,7 +243,8 @@ function assertQueryError (errorCode, query, bindVars) { } catch (e) { assertTrue(e.errorNum !== undefined, "unexpected error format while calling [" + query + "]"); - assertEqual(errorCode, e.errorNum, "unexpected error code (" + e.errorMessage + "): "); + assertEqual(errorCode, e.errorNum, "unexpected error code (" + e.errorMessage + + "while executing: " + query + "expecting: " + errorCode + "): " ); } } diff --git a/js/server/modules/@arangodb/foxx/mocha.js b/js/server/modules/@arangodb/foxx/mocha.js index 7db2d02b79..823dff6635 100644 --- a/js/server/modules/@arangodb/foxx/mocha.js +++ b/js/server/modules/@arangodb/foxx/mocha.js @@ -7,7 +7,7 @@ /// /// DISCLAIMER /// -/// Copyright 2015 triAGENS GmbH, Cologne, Germany +/// Copyright 2015-2016 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. @@ -24,87 +24,20 @@ /// Copyright holder is triAGENS GmbH, Cologne, Germany /// /// @author Alan Plum -/// @author Copyright 2015, triAGENS GmbH, Cologne, Germany +/// @author Copyright 2015-2016, triAGENS GmbH, Cologne, Germany //////////////////////////////////////////////////////////////////////////////// var fs = require('fs'); var Minimatch = require('minimatch').Minimatch; -var interfaces = require('mocha/lib/interfaces'); -var MochaContext = require('mocha/lib/context'); -var MochaSuite = require('mocha/lib/suite'); -var MochaRunner = require('mocha/lib/runner'); -var BaseReporter = require('mocha/lib/reporters/base'); -var DefaultReporter = require('mocha/lib/reporters/json'); var isWindows = require('internal').platform.substr(0, 3) === 'win'; -function notIn(arr) { - return function (item) { - return arr.indexOf(item) === -1; - }; -} +const mocha = require('@arangodb/mocha'); -function deleteFrom(obj) { - return function (key) { - delete obj[key]; - }; -} - -var reporters = { - stream: StreamReporter, - suite: SuiteReporter, - default: DefaultReporter -}; - -exports.run = function runMochaTests(app, reporterName) { - if (reporterName && !reporters[reporterName]) { - throw new Error( - 'Unknown test reporter: ' + reporterName - + ' Known reporters: ' + Object.keys(reporters).join(', ') - ); +exports.run = function runFoxxTests(app, reporterName) { + function run(file, context) { + return app.run(file, {context: context}); } - - var suite = new MochaSuite('', new MochaContext()); - - Object.keys(interfaces).forEach(function (key) { - interfaces[key](suite); - }); - - var options = {}; - var mocha = {options: options}; - var files = findTestFiles(app); - - // Clean up after chai.should(), etc - var globals = Object.getOwnPropertyNames(global); - var objectProps = Object.getOwnPropertyNames(Object.prototype); - // Monkeypatch process.stdout.write for mocha's JSON reporter - var _stdoutWrite = global.process.stdout.write; - global.process.stdout.write = function () {}; - - var Reporter = reporterName ? reporters[reporterName] : reporters.default; - var reporter, runner; - - try { - files.forEach(function (file) { - var context = {}; - suite.emit('pre-require', context, file, mocha); - suite.emit('require', app.run(file, {context: context}), file, mocha); - suite.emit('post-require', global, file, mocha); - }); - - runner = new MochaRunner(suite, false); - reporter = new Reporter(runner, options); - runner.run(); - } finally { - Object.getOwnPropertyNames(global) - .filter(notIn(globals)) - .forEach(deleteFrom(global)); - Object.getOwnPropertyNames(Object.prototype) - .filter(notIn(objectProps)) - .forEach(deleteFrom(Object.prototype)); - global.process.stdout.write = _stdoutWrite; - } - - return runner.testResults || reporter.stats; + return mocha.run(run, findTestFiles(app), reporterName); }; function isNotPattern(pattern) { @@ -134,111 +67,3 @@ function findTestFiles(app) { }) && fs.isFile(fs.join(basePath, path)); }); } - -function StreamReporter(runner) { - var self = this; - BaseReporter.call(this, runner); - var items = []; - var total = runner.total; - runner.on('start', function () { - items.push(['start', {total: total}]); - }); - runner.on('pass', function (test) { - var t = clean(test); - delete t.err; - items.push(['pass', t]); - }); - runner.on('fail', function (test, err) { - var t = clean(test); - t.err = err.message; - items.push(['fail', t]); - }); - runner.on('end', function () { - items.push(['end', self.stats]); - }); - runner.testResults = items; -} - -function SuiteReporter(runner) { - var self = this; - BaseReporter.call(this, runner); - var suites = []; - var currentSuite; - runner.on('suite', function (suite) { - var s = { - title: suite.title, - tests: [], - suites: [] - }; - suites.unshift(s); - if (currentSuite) { - currentSuite.suites.push(s); - } - currentSuite = s; - }); - runner.on('suite end', function () { - var last = suites.shift(); - currentSuite = suites[0] || last; - }); - runner.on('pending', function (test) { - var t = clean(test); - delete t.fullTitle; - t.result = 'pending'; - currentSuite.tests.push(t); - }); - runner.on('pass', function (test) { - var t = clean(test); - delete t.fullTitle; - t.result = 'pass'; - currentSuite.tests.push(t); - }); - runner.on('fail', function (test) { - var t = clean(test); - delete t.fullTitle; - t.result = 'fail'; - currentSuite.tests.push(t); - }); - runner.on('end', function () { - runner.testResults = { - stats: self.stats, - suites: currentSuite ? currentSuite.suites : [], - tests: currentSuite ? currentSuite.tests : [] - }; - }); -} - -// via https://github.com/mochajs/mocha/blob/c6747a/lib/reporters/json.js -// Copyright (c) 2011-2015 TJ Holowaychuk -// The MIT License - -/** - * Return a plain-object representation of `test` - * free of cyclic properties etc. - * - * @param {Object} test - * @return {Object} - * @api private - */ - -function clean(test) { - return { - title: test.title, - fullTitle: test.fullTitle(), - duration: test.duration, - err: errorJSON(test.err || {}) - }; -} - -/** - * Transform `error` into a JSON object. - * @param {Error} err - * @return {Object} - */ - -function errorJSON(err) { - var res = {}; - Object.getOwnPropertyNames(err).forEach(function(key) { - res[key] = err[key]; - }, err); - return res; -} \ No newline at end of file diff --git a/js/server/modules/@arangodb/testing.js b/js/server/modules/@arangodb/testing.js index ce24b06cbf..02f1f3de89 100644 --- a/js/server/modules/@arangodb/testing.js +++ b/js/server/modules/@arangodb/testing.js @@ -894,7 +894,7 @@ function runThere (options, instanceInfo, file) { t = 'var runTest = require("jsunity").runTest; '+ 'return runTest(' + JSON.stringify(file) + ', true);'; } - else { + else if (file.indexOf("-jasmine-spec") !== -1) { var jasmineReportFormat = options.jasmineReportFormat || 'progress'; t = 'var executeTestSuite = require("jasmine").executeTestSuite; '+ 'try {' + @@ -908,6 +908,19 @@ function runThere (options, instanceInfo, file) { '};' + '}'; } + else { + t = 'var runTest = require("@arangodb/mocha-runner"); ' + + 'try {' + + 'return { status: runTest(' + JSON.stringify(file) + ', true), message: "Success" };' + + ' } catch (e) {' + + 'var error = e.cause || e;' + + 'return {' + + ' status: false,' + + ' message: error.message,' + + ' stack: error.stack' + + '};' + + '}'; + } var o = makeAuthorizationHeaders(options); o.method = "POST"; o.timeout = 3600; diff --git a/js/server/tests/shell-foxx-model-events-spec.js b/js/server/tests/shell-foxx-model-events-spec.js index ffc9ac6611..781360f5ea 100644 --- a/js/server/tests/shell-foxx-model-events-spec.js +++ b/js/server/tests/shell-foxx-model-events-spec.js @@ -1,86 +1,83 @@ -/*jshint globalstrict:false, strict:false */ -/*global describe, expect, it, beforeEach, createSpyObj */ +/*global describe, it, beforeEach*/ +'use strict'; -var FoxxRepository = require("@arangodb/foxx/repository").Repository, - Model = require("@arangodb/foxx/model").Model; +var sinon = require('sinon'); +var expect = require('expect.js'); +var FoxxRepository = require("@arangodb/foxx/repository").Repository; +var Model = require("@arangodb/foxx/model").Model; describe('Model Events', function () { - 'use strict'; - var collection, instance, repository; beforeEach(function () { - collection = createSpyObj('collection', [ - 'update', - 'save', - 'type', - 'remove' - ]); - collection.type.and.returnValue(2); + collection = { + update: function() {}, + save: function() {}, + type: sinon.stub().returns(2), + remove: function() {} + }; instance = new Model({ random: '', beforeCalled: false, afterCalled: false }); repository = new FoxxRepository(collection, {model: Model}); }); it('should be possible to subscribe and emit events', function () { - expect(instance.on).toBeDefined(); - expect(instance.emit).toBeDefined(); + expect(instance.on).to.be.a('function'); + expect(instance.emit).to.be.a('function'); }); it('should emit beforeCreate and afterCreate events when creating the model', function () { addHooks(instance, 'Create'); - expect(repository.save(instance)).toEqual(instance); - expect(instance.get('beforeCalled')).toBe(true); - expect(instance.get('afterCalled')).toBe(true); + expect(repository.save(instance)).to.eql(instance); + expect(instance.get('beforeCalled')).to.be(true); + expect(instance.get('afterCalled')).to.be(true); }); it('should emit beforeSave and afterSave events when creating the model', function () { addHooks(instance, 'Save'); - expect(repository.save(instance)).toEqual(instance); - expect(instance.get('beforeCalled')).toBe(true); - expect(instance.get('afterCalled')).toBe(true); + expect(repository.save(instance)).to.eql(instance); + expect(instance.get('beforeCalled')).to.be(true); + expect(instance.get('afterCalled')).to.be(true); }); it('should emit beforeUpdate and afterUpdate events when updating the model', function () { var newData = { newAttribute: 'test' }; addHooks(instance, 'Update', newData); - expect(repository.update(instance, newData)).toEqual(instance); - expect(instance.get('beforeCalled')).toBe(true); - expect(instance.get('afterCalled')).toBe(true); + expect(repository.update(instance, newData)).to.eql(instance); + expect(instance.get('beforeCalled')).to.be(true); + expect(instance.get('afterCalled')).to.be(true); }); it('should emit beforeSave and afterSave events when updating the model', function () { var newData = { newAttribute: 'test' }; addHooks(instance, 'Save', newData); - expect(repository.update(instance, newData)).toEqual(instance); - expect(instance.get('beforeCalled')).toBe(true); - expect(instance.get('afterCalled')).toBe(true); + expect(repository.update(instance, newData)).to.eql(instance); + expect(instance.get('beforeCalled')).to.be(true); + expect(instance.get('afterCalled')).to.be(true); }); it('should emit beforeRemove and afterRemove events when removing the model', function () { addHooks(instance, 'Remove'); repository.remove(instance); - expect(instance.get('beforeCalled')).toBe(true); - expect(instance.get('afterCalled')).toBe(true); + expect(instance.get('beforeCalled')).to.be(true); + expect(instance.get('afterCalled')).to.be(true); }); }); function addHooks(model, ev, dataToReceive) { - 'use strict'; - var random = String(Math.floor(Math.random() * 1000)); model.on('before' + ev, function (data) { - expect(this).toEqual(model); - expect(data).toEqual(dataToReceive); + expect(this).to.eql(model); + expect(data).to.eql(dataToReceive); this.set('random', random); this.set('beforeCalled', true); }); model.on('after' + ev, function (data) { - expect(this).toEqual(model); - expect(data).toEqual(dataToReceive); + expect(this).to.eql(model); + expect(data).to.eql(dataToReceive); this.set('afterCalled', true); - expect(this.get('beforeCalled')).toBe(true); - expect(this.get('random')).toEqual(random); + expect(this.get('beforeCalled')).to.be(true); + expect(this.get('random')).to.eql(random); }); -} \ No newline at end of file +} diff --git a/js/server/tests/shell-foxx-query-spec.js b/js/server/tests/shell-foxx-query-jasmine-spec.js similarity index 100% rename from js/server/tests/shell-foxx-query-spec.js rename to js/server/tests/shell-foxx-query-jasmine-spec.js diff --git a/js/server/tests/shell-foxx-repository-spec.js b/js/server/tests/shell-foxx-repository-jasmine-spec.js similarity index 100% rename from js/server/tests/shell-foxx-repository-spec.js rename to js/server/tests/shell-foxx-repository-jasmine-spec.js