From b3c7ecbe2f91b85c0c0162f4fbb8b4d46bb30ba5 Mon Sep 17 00:00:00 2001 From: Jesse Schwartzentruber Date: Mon, 10 Apr 2017 13:49:32 -0400 Subject: [PATCH] Switch from qunit (node) and slimerjs to karma which supports running qunit tests in firefox and chrome. Maintaining code to work in node for testing only will be error-prone. --- .travis.yml | 6 +-- Gruntfile.js | 24 ++++++++++ karma.conf.js | 55 +++++++++++++++++++++++ package.json | 17 +++++++ random/mersennetwister.js | 2 - tests/index.html | 4 ++ tests/random/mersennetwister.js | 5 +-- tests/random/random.js | 40 ++++++++--------- tests/run-qunit.js | 80 --------------------------------- 9 files changed, 122 insertions(+), 111 deletions(-) create mode 100644 Gruntfile.js create mode 100644 karma.conf.js create mode 100644 package.json delete mode 100644 tests/run-qunit.js diff --git a/.travis.yml b/.travis.yml index 59d5f5d..622d2a7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js env: - - SLIMERJSLAUNCHER=$(which firefox) DISPLAY=:99.0 + - DISPLAY=:99.0 CHROME_BIN=chromium-browser branches: only: - master @@ -10,7 +10,3 @@ addons: firefox: latest before_script: - sh -e /etc/init.d/xvfb start - - npm install -g slimerjs qunitjs -script: - - qunit tests - - slimerjs tests/run-qunit.js tests/index.html diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..fedfc5d --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,24 @@ +module.exports = function(grunt) { + + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + + karma: { + unit: { + configFile: 'karma.conf.js' + } + }, + coveralls: { + options: { + coverageDir: 'tests/coverage/', + force: true + } + } + }); + + grunt.loadNpmTasks('grunt-karma'); + grunt.loadNpmTasks('grunt-karma-coveralls'); + + grunt.registerTask('test', ['karma', 'coveralls']); + +}; diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 0000000..7887f5d --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,55 @@ +module.exports = function(config) { + var configuration = { + basePath: './tests', + + frameworks: ['qunit'], + + files: [ + '../random/*.js', + '**/*.js' + ], + + exclude: [ + ], + + preprocessors: { + '../!(tests)/*.js': ['coverage'] + }, + + reporters: ['progress', 'coverage'], + + port: 9876, + + colors: true, + + logLevel: config.LOG_INFO, + + autoWatch: true, + + browsers: ['Chrome', 'Firefox'], + + singleRun: true, + + browserNoActivityTimeout: 30000, + + customLaunchers: { + Chrome_travis_ci: { + base: 'Chrome', + flags: ['--no-sandbox'] + } + }, + + coverageReporter: { + reporters: [ + { type: "lcov", dir: "coverage/" }, + { type: 'text-summary' } + ] + }, + }; + + if (process.env.TRAVIS) { + configuration.browsers = ['Chrome_travis_ci']; + } + + config.set(configuration); +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..d86650e --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "octo", + "devDependencies": { + "grunt": "*", + "grunt-karma": "*", + "grunt-karma-coveralls": "*", + "karma": "*", + "karma-chrome-launcher": "*", + "karma-coverage": "*", + "karma-firefox-launcher": "*", + "karma-qunit": "*", + "qunitjs": "*" + }, + "scripts": { + "test": "grunt test --verbose" + } +} diff --git a/random/mersennetwister.js b/random/mersennetwister.js index f537461..bbd8611 100644 --- a/random/mersennetwister.js +++ b/random/mersennetwister.js @@ -84,5 +84,3 @@ function MersenneTwister() return this.int32() * (1.0 / 4294967296.0); } } - -try{ module.exports.MersenneTwister = MersenneTwister; }catch(e){} diff --git a/tests/index.html b/tests/index.html index 1735602..a1ba9b7 100644 --- a/tests/index.html +++ b/tests/index.html @@ -10,7 +10,11 @@
+ + + + diff --git a/tests/random/mersennetwister.js b/tests/random/mersennetwister.js index b0d5972..7f5a772 100644 --- a/tests/random/mersennetwister.js +++ b/tests/random/mersennetwister.js @@ -1,10 +1,7 @@ -let MT; -try{ MT = require("../../random/mersennetwister.js"); }catch(e){ MT = window; } - /* XXX: translate some of the dieharder tests here? */ QUnit.test("MersenneTwister test distribution", function(assert) { - let mt = new MT.MersenneTwister(); + let mt = new MersenneTwister(); mt.seed(new Date().getTime()); for (let i = 0; i < 100; ++i) { let a = [], again = false; diff --git a/tests/random/random.js b/tests/random/random.js index 1010858..96f3491 100644 --- a/tests/random/random.js +++ b/tests/random/random.js @@ -1,31 +1,31 @@ -let MT; -try { MT = require("../../random/mersennetwister.js"); } catch(e) { MT = window; } - -QUnit.test("Random.init() with no seed value", function() { - Random.init(); - ok(Random.seed, "random seed is not null."); +/* +QUnit.test("random.init() with no seed value", function(assert) { + random.init(); + assert.ok(random.seed, "random seed is not null."); }); -QUnit.test("Random.init() with provided seed", function() { - var seed = new Date().getTime(); - Random.init(seed); - assert.equal(Random.seed, seed, "seed is correct"); +QUnit.test("random.init() with provided seed", function(assert) { + let seed = new Date().getTime(); + random.init(seed); + assert.equal(random.seed, seed, "seed is correct"); }); +*/ -QUnit.test("Random.range() PRNG reproducibility", function() { - var seed, result1, result2; +QUnit.test("random.range() PRNG reproducibility", function(assert) { + let seed, result1, result2; seed = new Date().getTime(); - Random.init(seed); - result1 = Random.range(1, 20); - Random.init(seed); - result2 = Random.range(1, 20); + random.init(seed); + result1 = random.range(1, 20); + random.init(seed); + result2 = random.range(1, 20); assert.equal(result1, result2, "both results are the same") }); -QUinit.test("Random.choose() with equal distribution", function() { - var i, tmp, foo = 0, bar = 0; - for(i = 0; i < 100; i++) { - tmp = Random.choose([[1, 'foo'], [1, 'bar']]); +QUnit.test("random.choose() with equal distribution", function(assert) { + let foo = 0, bar = 0; + random.init(new Date().getTime()); + for (let i = 0; i < 100; ++i) { + let tmp = random.choose([[1, 'foo'], [1, 'bar']]); if (tmp == "foo") { foo += 1; } if (tmp == "bar") { bar += 1; } } diff --git a/tests/run-qunit.js b/tests/run-qunit.js deleted file mode 100644 index fb7fbc0..0000000 --- a/tests/run-qunit.js +++ /dev/null @@ -1,80 +0,0 @@ -try{ var system = require('system'); } catch(e) {} - -if (system !== undefined) { - -/** - * Wait until the test condition is true or a timeout occurs. Useful for waiting - * on a server response or for a ui change (fadeIn, etc.) to occur. - * - * @param testFx javascript condition that evaluates to a boolean, - * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or - * as a callback function. - * @param onReady what to do when testFx condition is fulfilled, - * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or - * as a callback function. - * @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used. - */ -function waitFor(testFx, onReady, timeOutMillis) { - var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3001, //< Default Max Timout is 3s - start = new Date().getTime(), - condition = false, - interval = setInterval(function() { - if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) { - // If not time-out yet and condition not yet fulfilled - condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code - } else { - if(!condition) { - // If condition still not fulfilled (timeout but condition is 'false') - console.log("'waitFor()' timeout"); - phantom.exit(1); - } else { - // Condition fulfilled (timeout and/or condition is 'true') - console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms."); - typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled - clearInterval(interval); //< Stop this interval - } - } - }, 100); //< repeat check every 250ms -}; - - -if (system.args.length !== 2) { - console.log('Usage: run-qunit.js URL'); - phantom.exit(1); -} - -var page = require('webpage').create(); - -// Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this") -page.onConsoleMessage = function(msg) { - console.log(msg); -}; - -page.open(system.args[1], function(status){ - if (status !== "success") { - console.log("Unable to access network"); - phantom.exit(1); - } else { - waitFor(function(){ - return page.evaluate(function(){ - var el = document.getElementById('qunit-testresult'); - if (el && el.innerText.match('completed')) { - return true; - } - return false; - }); - }, function(){ - var failedNum = page.evaluate(function(){ - var el = document.getElementById('qunit-testresult'); - console.log(el.innerText); - try { - return el.getElementsByClassName('failed')[0].innerHTML; - } catch (e) { } - return 10000; - }); - phantom.exit((parseInt(failedNum, 10) > 0) ? 1 : 0); - }); - } -}); - -}