www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

commit 1c32db68dae445904f562ad7183d829ba56a0451
parent 5285fadded70581254465e2ed7e865fe0fc2e7a4
Author: Simon Kornblith <simon@simonster.com>
Date:   Sat,  7 Mar 2015 12:18:27 -0500

Unit testing infrastructure

Implements the beginnings of unit testing infrastructure using
mocha/chai. The unit tests can be run locally using test/runtests.sh,
although this will need tweaks to run on Windows. They should also run
on commit using Travis-CI.

The unit tests themselves live in test/tests. The index.js file
specifies separate test sets, which can be run individually by calling
test/runtests.sh <testsets>. Right now there is only a single unit
test, but hopefully we'll have more soon...

Diffstat:
M.gitmodules | 6++++++
A.travis.yml | 16++++++++++++++++
Atest/chrome.manifest | 7+++++++
Atest/components/zotero-unit.js | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/content/runtests.html | 15+++++++++++++++
Atest/content/runtests.js | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/install.rdf | 26++++++++++++++++++++++++++
Atest/resource/chai | 1+
Atest/resource/mocha | 1+
Atest/runtests.sh | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/tests/index.js | 3+++
Atest/tests/utilities.js | 20++++++++++++++++++++
12 files changed, 292 insertions(+), 0 deletions(-)

diff --git a/.gitmodules b/.gitmodules @@ -7,3 +7,9 @@ [submodule "styles"] path = styles url = git://github.com/zotero/bundled-styles.git +[submodule "test/resource/chai"] + path = test/resource/chai + url = https://github.com/chaijs/chai.git +[submodule "test/resource/mocha"] + path = test/resource/mocha + url = https://github.com/mochajs/mocha.git diff --git a/.travis.yml b/.travis.yml @@ -0,0 +1,16 @@ +language: cpp +compiler: + - gcc +env: + matrix: + - FIREFOXVERSION="36.0.1" + - FIREFOXVERSION="31.5.0esr" +notifications: + email: false +before_install: + - export DISPLAY=:99.0 + - sh -e /etc/init.d/xvfb start + - wget http://ftp.mozilla.org/pub/firefox/releases/${FIREFOXVERSION}/linux-x86_64/en-US/firefox-${FIREFOXVERSION}.tar.bz2 + - tar -xjf firefox-${FIREFOXVERSION}.tar.bz2 +script: + - test/runtests.sh -x firefox/firefox diff --git a/test/chrome.manifest b/test/chrome.manifest @@ -0,0 +1,7 @@ +content zotero-unit content/ +resource zotero-unit resource/ +resource zotero-unit-tests tests/ + +component {b8570031-be5e-46e8-9785-38cd50a5d911} components/zotero-unit.js +contract @mozilla.org/commandlinehandler/general-startup;1?type=zotero-unit {b8570031-be5e-46e8-9785-38cd50a5d911} +category command-line-handler m-zotero-unit @mozilla.org/commandlinehandler/general-startup;1?type=zotero-unit diff --git a/test/components/zotero-unit.js b/test/components/zotero-unit.js @@ -0,0 +1,51 @@ +"use strict"; +/* + ***** BEGIN LICENSE BLOCK ***** + + Copyright © 2012 Center for History and New Media + George Mason University, Fairfax, Virginia, USA + http://zotero.org + + This file is part of Zotero. + + Zotero is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Zotero is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with Zotero. If not, see <http://www.gnu.org/licenses/>. + + ***** END LICENSE BLOCK ***** +*/ +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); + +function ZoteroUnit() { + this.wrappedJSObject = this; +} +ZoteroUnit.prototype = { + /* nsICommandLineHandler */ + handle:function(cmdLine) { + this.tests = cmdLine.handleFlagWithParam("test", false); + }, + + dump:function(x) { + dump(x); + }, + + contractID: "@mozilla.org/commandlinehandler/general-startup;1?type=zotero-unit", + classDescription: "Zotero Unit Command Line Handler", + classID: Components.ID("{b8570031-be5e-46e8-9785-38cd50a5d911}"), + service: true, + _xpcom_categories: [{category:"command-line-handler", entry:"m-zotero-unit"}], + QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsICommandLineHandler, + Components.interfaces.nsISupports]) +}; + + +var NSGetFactory = XPCOMUtils.generateNSGetFactory([ZoteroUnit]); diff --git a/test/content/runtests.html b/test/content/runtests.html @@ -0,0 +1,14 @@ +<html> +<head> + <meta charset="utf-8"></meta> + <title>Zotero Unit Tests</title> +</head> +<body> + <script src="jquery.js"></script> + <script src="chrome://zotero/content/include.js"></script> + <script src="resource://zotero-unit/chai/chai.js"></script> + <script src="resource://zotero-unit/mocha/mocha.js"></script> + <script src="resource://zotero-unit-tests/index.js"></script> + <script src="runtests.js" version="application/javascript;version=1.8"></script> +</body> +</html> +\ No newline at end of file diff --git a/test/content/runtests.js b/test/content/runtests.js @@ -0,0 +1,88 @@ +Components.utils.import("resource://gre/modules/FileUtils.jsm"); +Components.utils.import("resource://gre/modules/osfile.jsm") + +var ZoteroUnit = Components.classes["@mozilla.org/commandlinehandler/general-startup;1?type=zotero-unit"]. + getService(Components.interfaces.nsISupports). + wrappedJSObject; +var dump = ZoteroUnit.dump; + +function quit(failed) { + // Quit with exit status + if(!failed) { + OS.File.writeAtomic(FileUtils.getFile("ProfD", ["success"]).path, Uint8Array(0)); + } + Components.classes['@mozilla.org/toolkit/app-startup;1']. + getService(Components.interfaces.nsIAppStartup). + quit(Components.interfaces.nsIAppStartup.eForceQuit); +} + +function Reporter(runner) { + var indents = 0, passed = 0, failed = 0; + + function indent() { + return Array(indents).join(' '); + } + + runner.on('start', function(){}); + + runner.on('suite', function(suite){ + ++indents; + dump(indent()+suite.title+"\n"); + }); + + runner.on('suite end', function(suite){ + --indents; + if (1 == indents) dump("\n"); + }); + + runner.on('pending', function(test){ + dump(indent()+"pending -"+test.title); + }); + + runner.on('pass', function(test){ + passed++; + var msg = "\r"+indent()+Mocha.reporters.Base.symbols.ok+" "+test.title; + if ('fast' != test.speed) { + msg += " ("+Math.round(test.duration)+" ms)"; + } + dump(msg+"\n"); + }); + + runner.on('fail', function(test, err){ + failed++; + dump("\r"+indent()+Mocha.reporters.Base.symbols.err+" "+test.title+"\n"); + }); + + runner.on('end', function() { + dump(passed+"/"+(passed+failed)+" tests passed.\n"); + quit(failed != 0); + }); +} + +// Setup Mocha +mocha.setup({ui:"bdd", reporter:Reporter}); +var assert = chai.assert, + expect = chai.expect; + +// Set up tests to run +if(ZoteroUnit.tests) { + document.body.appendChild(document.createTextNode("Running tests...")); + var torun = ZoteroUnit.tests == "all" ? Object.keys(TESTS) : ZoteroUnit.tests.split(","); + + for(var key of torun) { + if(!TESTS[key]) { + dump("Invalid test set "+torun+"\n"); + quit(true); + } + for(var test of TESTS[key]) { + var el = document.createElement("script"); + el.type = "application/javascript;version=1.8"; + el.src = "resource://zotero-unit-tests/"+test; + document.body.appendChild(el); + } + } +} + +window.onload = function() { + mocha.run(); +}; +\ No newline at end of file diff --git a/test/install.rdf b/test/install.rdf @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:em="http://www.mozilla.org/2004/em-rdf#"> + + <Description about="urn:mozilla:install-manifest"> + + <em:id>zotero-unit@zotero.org</em:id> + <em:name>Zotero Unit Tests</em:name> + <em:version>1.0</em:version> + <em:creator>Center for History and New Media</em:creator> + <em:developer>Simon Kornblith</em:developer> + <em:homepageURL>http://www.zotero.org</em:homepageURL> + <em:iconURL>chrome://zotero/skin/zotero-new-z-48px.png</em:iconURL> + <em:type>2</em:type> <!-- type=extension --> + + <!-- Firefox --> + <em:targetApplication> + <Description> + <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> + <em:minVersion>31.0</em:minVersion> + <em:maxVersion>38.*</em:maxVersion> + </Description> + </em:targetApplication> + + </Description> +</RDF> diff --git a/test/resource/chai b/test/resource/chai @@ -0,0 +1 @@ +Subproject commit d7cafca0232756f767275bb00e66930a7823b027 diff --git a/test/resource/mocha b/test/resource/mocha @@ -0,0 +1 @@ +Subproject commit 65fc80ecd96ca2159a792aff089bbc273d4bd86d diff --git a/test/runtests.sh b/test/runtests.sh @@ -0,0 +1,56 @@ +#!/bin/bash +CWD="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +if [ "`uname`" == "Darwin" ]; then + FX_EXECUTABLE="/Applications/Firefox.app/Contents/MacOS/firefox" +else + FX_EXECUTABLE="firefox" +fi + +function usage { + cat >&2 <<DONE +Usage: $0 [-x FX_EXECUTABLE] [TESTS...] +Options + -x FX_EXECUTABLE path to Firefox executable (default: $FX_EXECUTABLE) + TESTS set of tests to run (default: all) +DONE + exit 1 +} + +while getopts "x:" opt; do + case $opt in + x) + FX_EXECUTABLE="$OPTARG" + ;; + *) + usage + ;; + esac + shift $((OPTIND-1)); OPTIND=1 +done + +if [ -z $1 ]; then + TESTS="all" +else + ARGS=("${@:1}") + function join { local IFS="$1"; shift; echo "$*"; } + TESTS="$(join , "${ARGS[@]}")" +fi + +# Set up profile directory +PROFILE="`mktemp -d 2>/dev/null || mktemp -d -t 'zotero-unit'`" +mkdir "$PROFILE/extensions" +echo "$CWD" > "$PROFILE/extensions/zotero-unit@zotero.org" +echo "`dirname "$CWD"`" > "$PROFILE/extensions/zotero@chnm.gmu.edu" +echo 'user_pref("extensions.autoDisableScopes", 0);' > "$PROFILE/prefs.js" + +MOZ_NO_REMOTE=1 NO_EM_RESTART=1 "$FX_EXECUTABLE" -profile "$PROFILE" \ + -chrome chrome://zotero-unit/content/runtests.html -test "$TESTS" + +# Check for success +test -e "$PROFILE/success" +STATUS=$? + +# Clean up +rm -rf "$PROFILE" +exit $STATUS +\ No newline at end of file diff --git a/test/tests/index.js b/test/tests/index.js @@ -0,0 +1,3 @@ +var TESTS = { + "utilities":["utilities.js"] +}; diff --git a/test/tests/utilities.js b/test/tests/utilities.js @@ -0,0 +1,20 @@ +describe("Zotero.Utilities", function() { + describe("cleanAuthor", function() { + it('should parse author names', function() { + for(let useComma of [false, true]) { + for(let first_expected of [["First", "First"], + ["First Middle", "First Middle"], + ["F. R. S.", "F. R. S."], + ["F.R.S.", "F. R. S."], + ["F R S", "F. R. S."], + ["FRS", "F. R. S."]]) { + let [first, expected] = first_expected; + let str = useComma ? "Last, "+first : first+" Last"; + let author = Zotero.Utilities.cleanAuthor(str, "author", useComma); + assert.equal(author.firstName, expected); + assert.equal(author.lastName, "Last"); + } + } + }); + }); +});