Merge pull request #1239 from tnajdek/master
Enable running tests against babelized code in build/dir
This commit is contained in:
commit
04db119ae8
31 changed files with 278 additions and 6837 deletions
9
.babelrc
9
.babelrc
|
@ -2,12 +2,17 @@
|
|||
"compact": false,
|
||||
"presets": [],
|
||||
"ignore": [
|
||||
"resource/require.js",
|
||||
"chrome/content/zotero/include.js",
|
||||
"resource/tinymce/tinymce.js",
|
||||
"chrome/content/zotero/xpcom/citeproc.js",
|
||||
"resource/csl-validator.js",
|
||||
"resource/react.js",
|
||||
"resource/react-dom.js"
|
||||
"resource/react-dom.js",
|
||||
"resource/bluebird.js",
|
||||
"test/resource/httpd.js",
|
||||
"test/resource/mocha.js",
|
||||
"test/resource/co-mocha.js"
|
||||
],
|
||||
"plugins": [
|
||||
"syntax-flow",
|
||||
|
@ -25,7 +30,7 @@
|
|||
[
|
||||
"transform-async-to-module-method",
|
||||
{
|
||||
"module": "resource://zotero/bluebird/bluebird.js",
|
||||
"module": "resource://zotero/bluebird.js",
|
||||
"method": "coroutine"
|
||||
}
|
||||
],
|
||||
|
|
|
@ -7,24 +7,4 @@ var Zotero = Components.classes['@zotero.org/Zotero;1']
|
|||
.getService(Components.interfaces.nsISupports)
|
||||
.wrappedJSObject;
|
||||
|
||||
|
||||
var require = (function() {
|
||||
var { Loader, Require, Module } = Components.utils.import('resource://gre/modules/commonjs/toolkit/loader.js');
|
||||
var requirer = Module('/', '/');
|
||||
|
||||
var loader = Loader({
|
||||
id: 'zotero/require',
|
||||
paths: {
|
||||
'': 'resource://zotero/',
|
||||
},
|
||||
globals: {
|
||||
document,
|
||||
console,
|
||||
navigator,
|
||||
window,
|
||||
Zotero
|
||||
}
|
||||
});
|
||||
|
||||
return Require(loader, requirer);
|
||||
})();
|
||||
Components.utils.import('resource://zotero/require.js');
|
|
@ -62,27 +62,7 @@ Services.scriptloader.loadSubScript("resource://zotero/polyfill.js");
|
|||
this.isMac;
|
||||
this.isWin;
|
||||
this.initialURL; // used by Schema to show the changelog on upgrades
|
||||
|
||||
// Load and configure Bluebird
|
||||
this.Promise = require('resource://zotero/bluebird/bluebird.js');
|
||||
this.Promise.config({
|
||||
warnings: true,
|
||||
longStackTraces: true,
|
||||
cancellation: true
|
||||
});
|
||||
this.Promise.onPossiblyUnhandledRejection(function (e, promise) {
|
||||
if (e.name == 'ZoteroPromiseInterrupt' || e.handledRejection) {
|
||||
return;
|
||||
}
|
||||
Zotero.debug('Possibly unhandled rejection:\n\n'
|
||||
+ (e.message
|
||||
? e.message + "\n\n" + e.stack.split(/\n/)
|
||||
// Filter out internal Bluebird calls
|
||||
.filter(line => !line.includes('bluebird'))
|
||||
.join('\n')
|
||||
: e), 1);
|
||||
throw e;
|
||||
});
|
||||
this.Promise = require('resource://zotero/bluebird.js');
|
||||
|
||||
this.getActiveZoteroPane = function() {
|
||||
var win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
|
@ -1958,7 +1938,12 @@ Zotero.Prefs = new function(){
|
|||
|
||||
// Register observer to handle pref changes
|
||||
this.register();
|
||||
|
||||
|
||||
// Unregister observer handling pref changes
|
||||
if (Zotero.addShutdownListener) {
|
||||
Zotero.addShutdownListener(this.unregister.bind(this));
|
||||
}
|
||||
|
||||
// Process pref version updates
|
||||
var fromVersion = this.get('prefVersion');
|
||||
if (!fromVersion) {
|
||||
|
|
|
@ -152,23 +152,11 @@ var isFirstLoadThisSession = true;
|
|||
var zContext = null;
|
||||
var initCallbacks = [];
|
||||
var zInitOptions = {};
|
||||
Components.utils.import('resource://zotero/require.js');
|
||||
|
||||
ZoteroContext = function() {}
|
||||
ZoteroContext.prototype = {
|
||||
require: (target) => {
|
||||
var { Loader, Require, Module } = Components.utils.import('resource://gre/modules/commonjs/toolkit/loader.js');
|
||||
var requirer = Module('/', '/');
|
||||
var globals = {};
|
||||
|
||||
Components.utils.import("resource://gre/modules/Timer.jsm", globals);
|
||||
|
||||
var loader = Loader({
|
||||
id: 'zotero/requireminimal',
|
||||
globals
|
||||
});
|
||||
|
||||
return (Require(loader, requirer))(target);
|
||||
},
|
||||
require,
|
||||
|
||||
/**
|
||||
* Convenience method to replicate window.alert()
|
||||
|
|
100
gulpfile.js
100
gulpfile.js
|
@ -10,17 +10,40 @@ const sass = require('gulp-sass');
|
|||
const os = require('os');
|
||||
const glob = require('glob');
|
||||
const Worker = require('tiny-worker');
|
||||
const NODE_ENV = process.env.NODE_ENV;
|
||||
const merge = require('merge-stream');
|
||||
const tap = require('gulp-tap');
|
||||
const rename = require("gulp-rename");
|
||||
const browserify = require('browserify');
|
||||
const reactPatcher = require('./gulp/gulp-react-patcher');
|
||||
const NODE_ENV = process.env.NODE_ENV;
|
||||
|
||||
const formatDirsforMatcher = dirs => {
|
||||
return dirs.length > 1 ? `{${dirs.join(',')}}` : dirs[0];
|
||||
};
|
||||
|
||||
// list of folders from where .js files are compiled and non-js files are symlinked
|
||||
const dirs = [
|
||||
'chrome', 'components', 'defaults', 'resource', 'resource/web-library'
|
||||
'chrome',
|
||||
'components',
|
||||
'defaults',
|
||||
'resource',
|
||||
'resource/web-library',
|
||||
'test',
|
||||
'test/resource/chai',
|
||||
'test/resource/chai-as-promised',
|
||||
'test/resource/mocha'
|
||||
];
|
||||
|
||||
// list of folders from where all files are symlinked
|
||||
// list of folders from which all files are symlinked
|
||||
const symlinkDirs = [
|
||||
'styles', 'translators'
|
||||
'styles',
|
||||
'translators',
|
||||
];
|
||||
|
||||
// list of folders which are copied to the build folder
|
||||
const copyDirs = [
|
||||
'test/tests/data' // browser follows symlinks when loading test data
|
||||
// triggering false-positive test results with mismatched URIs
|
||||
];
|
||||
|
||||
// list of files from root folder to symlink
|
||||
|
@ -28,7 +51,26 @@ const symlinkFiles = [
|
|||
'chrome.manifest', 'install.rdf', 'update.rdf'
|
||||
];
|
||||
|
||||
// these files will be browserified during the build
|
||||
const browserifyConfigs = [
|
||||
{
|
||||
src: 'node_modules/sinon/lib/sinon.js',
|
||||
dest: 'test/resource/sinon.js',
|
||||
config: {
|
||||
standalone: 'sinon'
|
||||
}
|
||||
},
|
||||
{
|
||||
src: 'node_modules/chai-as-promised/lib/chai-as-promised.js',
|
||||
dest: 'test/resource/chai-as-promised.js',
|
||||
config: {
|
||||
standalone: 'chaiAsPromised'
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
const jsGlob = `./\{${dirs.join(',')}\}/**/*.js`;
|
||||
const jsGlobIgnore = `./\{${symlinkDirs.concat(copyDirs).join(',')}\}/**/*.js`;
|
||||
|
||||
function onError(err) {
|
||||
gutil.log(gutil.colors.red('Error:'), err);
|
||||
|
@ -39,7 +81,25 @@ function onSuccess(msg) {
|
|||
gutil.log(gutil.colors.green('Build:'), msg);
|
||||
}
|
||||
|
||||
function getJS(source = jsGlob) {
|
||||
function getBrowserify() {
|
||||
const streams = browserifyConfigs.map(config => {
|
||||
return gulp
|
||||
.src(config.src)
|
||||
.pipe(tap(file => {
|
||||
file.contents = browserify(file.path, config.config).bundle();
|
||||
}))
|
||||
.pipe(rename(config.dest))
|
||||
.pipe(gulp.dest('build'));
|
||||
});
|
||||
|
||||
return merge.apply(merge, streams);
|
||||
}
|
||||
|
||||
function getJS(source, sourceIgnore) {
|
||||
if (sourceIgnore) {
|
||||
source = [source, '!' + sourceIgnore];
|
||||
}
|
||||
|
||||
return gulp.src(source, { base: '.' })
|
||||
.pipe(babel())
|
||||
.pipe(reactPatcher())
|
||||
|
@ -50,8 +110,8 @@ function getJS(source = jsGlob) {
|
|||
.pipe(gulp.dest('./build'));
|
||||
}
|
||||
|
||||
function getJSParallel(source = jsGlob) {
|
||||
const jsFiles = glob.sync(source);
|
||||
function getJSParallel(source, sourceIgnore) {
|
||||
const jsFiles = glob.sync(source, { ignore: sourceIgnore });
|
||||
const cpuCount = os.cpus().length;
|
||||
const threadCount = Math.min(cpuCount, jsFiles.length);
|
||||
let threadsActive = threadCount;
|
||||
|
@ -93,7 +153,8 @@ function getSymlinks() {
|
|||
const match = symlinkFiles
|
||||
.concat(dirs.map(d => `${d}/**`))
|
||||
.concat(symlinkDirs.map(d => `${d}/**`))
|
||||
.concat([`!{${dirs.join(',')}}/**/*.js`]);
|
||||
.concat([`!./${formatDirsforMatcher(dirs)}/**/*.js`])
|
||||
.concat([`!./${formatDirsforMatcher(copyDirs)}/**`]);
|
||||
|
||||
return gulp
|
||||
.src(match, { nodir: true, base: '.', read: false })
|
||||
|
@ -104,6 +165,15 @@ function getSymlinks() {
|
|||
.pipe(vfs.symlink('build/'));
|
||||
}
|
||||
|
||||
function getCopy() {
|
||||
return gulp
|
||||
.src(copyDirs.map(d => `${d}/**`), { base: '.' })
|
||||
.on('data', file => {
|
||||
onSuccess(`[cp] ${file.path.substr(__dirname.length + 1)}`);
|
||||
})
|
||||
.pipe(gulp.dest('build/'));
|
||||
}
|
||||
|
||||
function getSass() {
|
||||
return gulp
|
||||
.src('scss/*.scss')
|
||||
|
@ -122,14 +192,22 @@ gulp.task('symlink', ['clean'], () => {
|
|||
});
|
||||
|
||||
gulp.task('js', done => {
|
||||
getJSParallel(jsGlob).then(() => done());
|
||||
getJSParallel(jsGlob, jsGlobIgnore).then(() => done());
|
||||
});
|
||||
|
||||
gulp.task('browserify', () => {
|
||||
getBrowserify();
|
||||
});
|
||||
|
||||
gulp.task('copy', () => {
|
||||
getCopy();
|
||||
});
|
||||
|
||||
gulp.task('sass', () => {
|
||||
return getSass();
|
||||
});
|
||||
|
||||
gulp.task('build', ['js', 'sass', 'symlink']);
|
||||
gulp.task('build', ['js', 'sass', 'symlink', 'browserify', 'copy']);
|
||||
|
||||
gulp.task('dev', ['clean'], () => {
|
||||
var interval = 750;
|
||||
|
@ -137,7 +215,7 @@ gulp.task('dev', ['clean'], () => {
|
|||
let watcher = gulp.watch(jsGlob, { interval });
|
||||
|
||||
watcher.on('change', function(event) {
|
||||
getJS(event.path);
|
||||
getJS(event.path, jsGlobIgnore);
|
||||
});
|
||||
|
||||
gulp.watch('src/styles/*.scss', { interval }, ['sass']);
|
||||
|
|
14
package.json
14
package.json
|
@ -12,7 +12,7 @@
|
|||
},
|
||||
"license": "",
|
||||
"dependencies": {
|
||||
"bluebird": "^3.4.6",
|
||||
"bluebird": "3.4.7",
|
||||
"zotero-web-library": "next",
|
||||
"react": "^15.3.2",
|
||||
"react-dom": "^15.3.2"
|
||||
|
@ -30,17 +30,25 @@
|
|||
"babel-plugin-transform-async-to-module-method": "^6.16.0",
|
||||
"babel-plugin-transform-es2015-modules-commonjs": "^6.18.0",
|
||||
"babel-preset-react": "^6.16.0",
|
||||
"browserify": "^14.3.0",
|
||||
"chai": "^3.5.0",
|
||||
"chai-as-promised": "^6.0.0",
|
||||
"co-mocha": "^1.2.0",
|
||||
"del": "^2.2.2",
|
||||
"glob": "^7.1.2",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-babel": "^6.1.2",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-sass": "^3.1.0",
|
||||
"gulp-tap": "^1.0.1",
|
||||
"gulp-util": "^3.0.7",
|
||||
"merge-stream": "^1.0.1",
|
||||
"mocha": "^3.4.2",
|
||||
"sinon": "^2.3.1",
|
||||
"sinon-as-promised": "^4.0.3",
|
||||
"through2": "^2.0.1",
|
||||
"tiny-worker": "^2.1.1",
|
||||
"vinyl-buffer": "^1.0.0",
|
||||
"vinyl-fs": "^2.4.4",
|
||||
"vinyl-source-stream": "^1.1.0",
|
||||
"watchify": "^3.7.0"
|
||||
}
|
||||
}
|
||||
|
|
29
resource/bluebird.js
Normal file
29
resource/bluebird.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
'use strict';
|
||||
|
||||
var EXPORTED_SYMBOLS = ['Promise'];
|
||||
|
||||
var Promise = require('bluebird/promise')();
|
||||
|
||||
Promise.config({
|
||||
warnings: true,
|
||||
longStackTraces: true,
|
||||
cancellation: true
|
||||
});
|
||||
|
||||
// TEMP: Only turn on if debug logging enabled?
|
||||
Promise.onPossiblyUnhandledRejection((e, promise) => {
|
||||
if (e.name == 'ZoteroPromiseInterrupt' || e.handledRejection) {
|
||||
return;
|
||||
}
|
||||
|
||||
typeof Zotero !== 'undefined' && Zotero.debug('Possibly unhandled rejection:\n\n'
|
||||
+ (e.message
|
||||
? e.message + "\n\n" + e.stack.split(/\n/)
|
||||
// Filter out internal Bluebird calls
|
||||
.filter(line => !line.includes('bluebird'))
|
||||
.join('\n')
|
||||
: e), 1);
|
||||
throw e;
|
||||
});
|
||||
|
||||
module.exports = Promise;
|
|
@ -24,23 +24,9 @@
|
|||
*/
|
||||
|
||||
EXPORTED_SYMBOLS = ["ConcurrentCaller"];
|
||||
Components.utils.import('resource://zotero/require.js');
|
||||
|
||||
var require = (target) => {
|
||||
var { Loader, Require, Module } = Components.utils.import('resource://gre/modules/commonjs/toolkit/loader.js');
|
||||
var requirer = Module('/', '/');
|
||||
var globals = {};
|
||||
|
||||
Components.utils.import("resource://gre/modules/Timer.jsm", globals);
|
||||
|
||||
var loader = Loader({
|
||||
id: 'zotero/requireminimal',
|
||||
globals
|
||||
});
|
||||
|
||||
return (Require(loader, requirer))(target);
|
||||
};
|
||||
|
||||
var Promise = require('resource://zotero/bluebird/bluebird.js');
|
||||
var Promise = require('resource://zotero/bluebird.js');
|
||||
|
||||
/**
|
||||
* Call a fixed number of functions at once, queueing the rest until slots
|
||||
|
|
77
resource/require.js
Normal file
77
resource/require.js
Normal file
|
@ -0,0 +1,77 @@
|
|||
'use strict';
|
||||
|
||||
var EXPORTED_SYMBOLS = ['require'];
|
||||
|
||||
var require = (function() {
|
||||
var { Loader, Require, Module } = Components.utils.import('resource://gre/modules/commonjs/toolkit/loader.js');
|
||||
var requirer = Module('/', '/');
|
||||
var _runningTimers = {};
|
||||
var window = {};
|
||||
|
||||
window.setTimeout = function (func, ms) {
|
||||
var id = Math.floor(Math.random() * (1000000000000 - 1)) + 1
|
||||
var useMethodjit = Components.utils.methodjit;
|
||||
var timer = Components.classes["@mozilla.org/timer;1"]
|
||||
.createInstance(Components.interfaces.nsITimer);
|
||||
timer.initWithCallback({"notify":function() {
|
||||
// Remove timer from object so it can be garbage collected
|
||||
delete _runningTimers[id];
|
||||
|
||||
// Execute callback function
|
||||
try {
|
||||
func();
|
||||
} catch(err) {
|
||||
// Rethrow errors that occur so that they appear in the error
|
||||
// console with the appropriate name and line numbers. While the
|
||||
// the errors appear without this, the line numbers get eaten.
|
||||
var scriptError = Components.classes["@mozilla.org/scripterror;1"]
|
||||
.createInstance(Components.interfaces.nsIScriptError);
|
||||
scriptError.init(
|
||||
err.message || err.toString(),
|
||||
err.fileName || err.filename || null,
|
||||
null,
|
||||
err.lineNumber || null,
|
||||
null,
|
||||
scriptError.errorFlag,
|
||||
'component javascript'
|
||||
);
|
||||
Components.classes["@mozilla.org/consoleservice;1"]
|
||||
.getService(Components.interfaces.nsIConsoleService)
|
||||
.logMessage(scriptError);
|
||||
typeof Zotero !== 'undefined' && Zotero.debug(err.stack, 1);
|
||||
}
|
||||
}}, ms, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
|
||||
_runningTimers[id] = timer;
|
||||
return id;
|
||||
};
|
||||
|
||||
window.clearTimeout = function (id) {
|
||||
var timer = _runningTimers[id];
|
||||
if (timer) {
|
||||
timer.cancel();
|
||||
}
|
||||
delete _runningTimers[id];
|
||||
};
|
||||
|
||||
window.debug = function (msg) {
|
||||
dump(msg + "\n\n");
|
||||
};
|
||||
|
||||
var loader = Loader({
|
||||
id: 'zotero/require',
|
||||
paths: {
|
||||
'': 'resource://zotero/',
|
||||
},
|
||||
globals: {
|
||||
document: typeof document !== 'undefined' && document || {},
|
||||
console: typeof console !== 'undefined' && console || {},
|
||||
navigator: typeof navigator !== 'undefined' && navigator || {},
|
||||
window,
|
||||
setTimeout: window.setTimeout,
|
||||
clearTimeout: window.clearTimeout,
|
||||
Zotero: typeof Zotero !== 'undefined' && Zotero || {}
|
||||
}
|
||||
});
|
||||
|
||||
return Require(loader, requirer);
|
||||
})();
|
|
@ -6,11 +6,11 @@
|
|||
<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/chai-as-promised/lib/chai-as-promised.js"></script>
|
||||
<script src="resource://zotero-unit/mocha/mocha.js"></script>
|
||||
<script src="resource://zotero-unit/chai.js"></script>
|
||||
<script src="resource://zotero-unit/chai-as-promised.js"></script>
|
||||
<script src="resource://zotero-unit/mocha.js"></script>
|
||||
<script src="resource://zotero-unit/co-mocha.js"></script>
|
||||
<script src="resource://zotero-unit/sinon.js"></script>
|
||||
<script src="resource://zotero-unit/sinon-as-promised.js"></script>
|
||||
<script src="resource://zotero-unit/pako_inflate.js"></script>
|
||||
<script src="support.js" type="application/javascript;version=1.8"></script>
|
||||
<script src="runtests.js" type="application/javascript;version=1.8"></script>
|
||||
|
|
|
@ -184,19 +184,7 @@ mocha.setup({
|
|||
grep: ZoteroUnit.grep
|
||||
});
|
||||
|
||||
// Enable Bluebird generator support in Mocha
|
||||
(function () {
|
||||
var Runnable = Mocha.Runnable;
|
||||
var run = Runnable.prototype.run;
|
||||
Runnable.prototype.run = function (fn) {
|
||||
if (this.fn.constructor.name === 'GeneratorFunction') {
|
||||
this.fn = Zotero.Promise.coroutine(this.fn);
|
||||
} else if (typeof this.fn == 'function' && this.fn.isGenerator()) {
|
||||
throw new Error("Attempting to use a legacy generator in Mocha test");
|
||||
}
|
||||
return run.call(this, fn);
|
||||
};
|
||||
})();
|
||||
coMocha(Mocha);
|
||||
|
||||
before(function () {
|
||||
// Store all prefs set in runtests.sh
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
chai.use(chaiAsPromised);
|
||||
|
||||
// Useful "constants"
|
||||
var sqlDateTimeRe = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;
|
||||
var isoDateTimeRe = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/;
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Subproject commit b369f252432c3486a66a0e93f441e4abb133d229
|
|
@ -1 +0,0 @@
|
|||
Subproject commit c0d887605a6df879d7ff1700600ad450e6e09a84
|
1
test/resource/chai-as-promised
Symbolic link
1
test/resource/chai-as-promised
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../node_modules/chai-as-promised/lib
|
1
test/resource/chai.js
Symbolic link
1
test/resource/chai.js
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../node_modules/chai/chai.js
|
1
test/resource/co-mocha.js
Symbolic link
1
test/resource/co-mocha.js
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../node_modules/co-mocha/co-mocha.js
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 2a8594424c73ffeca41ef1668446372160528b4a
|
1
test/resource/mocha.js
Symbolic link
1
test/resource/mocha.js
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../node_modules/mocha/mocha.js
|
|
@ -1,250 +0,0 @@
|
|||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.sinonAsPromised = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
'use strict'
|
||||
|
||||
var Promise = window.Zotero.Promise
|
||||
var sinon = (window.sinon)
|
||||
|
||||
function methods (Promise) {
|
||||
return ['catch', 'finally'].concat(Object.keys(Promise.prototype)).filter(a => a != 'then');
|
||||
}
|
||||
function createThenable (Promise, resolver) {
|
||||
return methods(Promise).reduce(createMethod, {then: then})
|
||||
function createMethod (thenable, name) {
|
||||
thenable[name] = method(name)
|
||||
return thenable
|
||||
}
|
||||
function method (name) {
|
||||
return function () {
|
||||
var promise = this.then()
|
||||
return promise[name].apply(promise, arguments)
|
||||
}
|
||||
}
|
||||
function then (/*onFulfill, onReject*/) {
|
||||
var promise = new Promise(resolver)
|
||||
return promise.then.apply(promise, arguments)
|
||||
}
|
||||
}
|
||||
|
||||
function resolves (value) {
|
||||
return this.returns(createThenable(Promise, function (resolve) {
|
||||
resolve(value)
|
||||
}))
|
||||
}
|
||||
|
||||
sinon.stub.resolves = resolves
|
||||
sinon.behavior.resolves = resolves
|
||||
|
||||
function rejects (err) {
|
||||
if (typeof err === 'string') {
|
||||
err = new Error(err)
|
||||
}
|
||||
return this.returns(createThenable(Promise, function (resolve, reject) {
|
||||
reject(err)
|
||||
}))
|
||||
}
|
||||
|
||||
sinon.stub.rejects = rejects
|
||||
sinon.behavior.rejects = rejects
|
||||
|
||||
module.exports = function (_Promise_) {
|
||||
if (typeof _Promise_ !== 'function') {
|
||||
throw new Error('A Promise constructor must be provided')
|
||||
} else {
|
||||
Promise = _Promise_
|
||||
}
|
||||
return sinon
|
||||
}
|
||||
|
||||
},{"create-thenable":7,"native-promise-only":8}],2:[function(require,module,exports){
|
||||
/*!
|
||||
* object.omit <https://github.com/jonschlinkert/object.omit>
|
||||
*
|
||||
* Copyright (c) 2014-2015 Jon Schlinkert.
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var isObject = require('isobject');
|
||||
var forOwn = require('for-own');
|
||||
|
||||
module.exports = function omit(obj, props) {
|
||||
if (obj == null || !isObject(obj)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (props == null) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (typeof props === 'string') {
|
||||
props = [].slice.call(arguments, 1);
|
||||
}
|
||||
|
||||
var o = {};
|
||||
|
||||
if (!Object.keys(obj).length) {
|
||||
return o;
|
||||
}
|
||||
|
||||
forOwn(obj, function (value, key) {
|
||||
if (props.indexOf(key) === -1) {
|
||||
o[key] = value;
|
||||
}
|
||||
});
|
||||
return o;
|
||||
};
|
||||
},{"for-own":3,"isobject":5}],3:[function(require,module,exports){
|
||||
/*!
|
||||
* for-own <https://github.com/jonschlinkert/for-own>
|
||||
*
|
||||
* Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var forIn = require('for-in');
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
|
||||
module.exports = function forOwn(o, fn, thisArg) {
|
||||
forIn(o, function (val, key) {
|
||||
if (hasOwn.call(o, key)) {
|
||||
return fn.call(thisArg, o[key], key, o);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
},{"for-in":4}],4:[function(require,module,exports){
|
||||
/*!
|
||||
* for-in <https://github.com/jonschlinkert/for-in>
|
||||
*
|
||||
* Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function forIn(o, fn, thisArg) {
|
||||
for (var key in o) {
|
||||
if (fn.call(thisArg, o[key], key, o) === false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
},{}],5:[function(require,module,exports){
|
||||
/*!
|
||||
* isobject <https://github.com/jonschlinkert/isobject>
|
||||
*
|
||||
* Copyright (c) 2014 Jon Schlinkert, contributors.
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* is the value an object, and not an array?
|
||||
*
|
||||
* @param {*} `value`
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
module.exports = function isObject(o) {
|
||||
return o != null && typeof o === 'object'
|
||||
&& !Array.isArray(o);
|
||||
};
|
||||
},{}],6:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Concatenates two arrays, removing duplicates in the process and returns one array with unique values.
|
||||
* In case the elements in the array don't have a proper built in way to determine their identity,
|
||||
* a custom identity function must be provided.
|
||||
*
|
||||
* As an example, {Object}s all return '[ 'object' ]' when .toString()ed and therefore require a custom
|
||||
* identity function.
|
||||
*
|
||||
* @name exports
|
||||
* @function unique-concat
|
||||
* @param arr1 {Array} first batch of elements
|
||||
* @param arr2 {Array} second batch of elements
|
||||
* @param identity {Function} (optional) supply an alternative way to get an element's identity
|
||||
*/
|
||||
var go = module.exports = function uniqueConcat(arr1, arr2, identity) {
|
||||
|
||||
if (!arr1 || !arr2) throw new Error('Need two arrays to merge');
|
||||
if (!Array.isArray(arr1)) throw new Error('First argument is not an array, but a ' + typeof arr1);
|
||||
if (!Array.isArray(arr2)) throw new Error('Second argument is not an array, but a ' + typeof arr2);
|
||||
if (identity && typeof identity !== 'function') throw new Error('Third argument should be a function');
|
||||
|
||||
function hashify(acc, k) {
|
||||
acc[identity ? identity(k) : k] = k;
|
||||
return acc;
|
||||
}
|
||||
|
||||
var arr1Hash = arr1.reduce(hashify, {});
|
||||
var mergedHash = arr2.reduce(hashify, arr1Hash);
|
||||
|
||||
return Object.keys(mergedHash).map(function (key) { return mergedHash[key]; });
|
||||
};
|
||||
|
||||
},{}],7:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
||||
|
||||
exports['default'] = createThenable;
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _defineProperty(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); }
|
||||
|
||||
var _uniqueConcat = require('unique-concat');
|
||||
|
||||
var _uniqueConcat2 = _interopRequireDefault(_uniqueConcat);
|
||||
|
||||
var _objectOmit = require('object-omit');
|
||||
|
||||
var _objectOmit2 = _interopRequireDefault(_objectOmit);
|
||||
|
||||
'use strict';
|
||||
|
||||
function createThenable(Promise, resolver) {
|
||||
return methods(Promise).reduce(createMethod, { then: then });
|
||||
function createMethod(thenable, name) {
|
||||
return _extends(thenable, _defineProperty({}, name, method(name)));
|
||||
}
|
||||
function method(name) {
|
||||
return function () {
|
||||
var _then;
|
||||
|
||||
return (_then = this.then())[name].apply(_then, arguments);
|
||||
};
|
||||
}
|
||||
function then() {
|
||||
var _ref;
|
||||
|
||||
return (_ref = new Promise(resolver)).then.apply(_ref, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
function methods(Promise) {
|
||||
return _uniqueConcat2['default'](['catch', 'finally'], Object.keys(_objectOmit2['default'](Promise.prototype, 'then')));
|
||||
}
|
||||
module.exports = exports['default'];
|
||||
/*onFulfill, onReject*/
|
||||
},{"object-omit":2,"unique-concat":6}],8:[function(require,module,exports){
|
||||
(function (global){
|
||||
/*! Native Promise Only
|
||||
v0.7.8-a (c) Kyle Simpson
|
||||
MIT License: http://getify.mit-license.org
|
||||
*/
|
||||
!function(t,n,e){n[t]=n[t]||e(),"undefined"!=typeof module&&module.exports?module.exports=n[t]:"function"==typeof define&&define.amd&&define(function(){return n[t]})}("Promise","undefined"!=typeof global?global:this,function(){"use strict";function t(t,n){l.add(t,n),h||(h=y(l.drain))}function n(t){var n,e=typeof t;return null==t||"object"!=e&&"function"!=e||(n=t.then),"function"==typeof n?n:!1}function e(){for(var t=0;t<this.chain.length;t++)o(this,1===this.state?this.chain[t].success:this.chain[t].failure,this.chain[t]);this.chain.length=0}function o(t,e,o){var r,i;try{e===!1?o.reject(t.msg):(r=e===!0?t.msg:e.call(void 0,t.msg),r===o.promise?o.reject(TypeError("Promise-chain cycle")):(i=n(r))?i.call(r,o.resolve,o.reject):o.resolve(r))}catch(c){o.reject(c)}}function r(o){var c,u,a=this;if(!a.triggered){a.triggered=!0,a.def&&(a=a.def);try{(c=n(o))?(u=new f(a),c.call(o,function(){r.apply(u,arguments)},function(){i.apply(u,arguments)})):(a.msg=o,a.state=1,a.chain.length>0&&t(e,a))}catch(s){i.call(u||new f(a),s)}}}function i(n){var o=this;o.triggered||(o.triggered=!0,o.def&&(o=o.def),o.msg=n,o.state=2,o.chain.length>0&&t(e,o))}function c(t,n,e,o){for(var r=0;r<n.length;r++)!function(r){t.resolve(n[r]).then(function(t){e(r,t)},o)}(r)}function f(t){this.def=t,this.triggered=!1}function u(t){this.promise=t,this.state=0,this.triggered=!1,this.chain=[],this.msg=void 0}function a(n){if("function"!=typeof n)throw TypeError("Not a function");if(0!==this.__NPO__)throw TypeError("Not a promise");this.__NPO__=1;var o=new u(this);this.then=function(n,r){var i={success:"function"==typeof n?n:!0,failure:"function"==typeof r?r:!1};return i.promise=new this.constructor(function(t,n){if("function"!=typeof t||"function"!=typeof n)throw TypeError("Not a function");i.resolve=t,i.reject=n}),o.chain.push(i),0!==o.state&&t(e,o),i.promise},this["catch"]=function(t){return this.then(void 0,t)};try{n.call(void 0,function(t){r.call(o,t)},function(t){i.call(o,t)})}catch(c){i.call(o,c)}}var s,h,l,p=Object.prototype.toString,y="undefined"!=typeof setImmediate?function(t){return setImmediate(t)}:setTimeout;try{Object.defineProperty({},"x",{}),s=function(t,n,e,o){return Object.defineProperty(t,n,{value:e,writable:!0,configurable:o!==!1})}}catch(d){s=function(t,n,e){return t[n]=e,t}}l=function(){function t(t,n){this.fn=t,this.self=n,this.next=void 0}var n,e,o;return{add:function(r,i){o=new t(r,i),e?e.next=o:n=o,e=o,o=void 0},drain:function(){var t=n;for(n=e=h=void 0;t;)t.fn.call(t.self),t=t.next}}}();var g=s({},"constructor",a,!1);return a.prototype=g,s(g,"__NPO__",0,!1),s(a,"resolve",function(t){var n=this;return t&&"object"==typeof t&&1===t.__NPO__?t:new n(function(n,e){if("function"!=typeof n||"function"!=typeof e)throw TypeError("Not a function");n(t)})}),s(a,"reject",function(t){return new this(function(n,e){if("function"!=typeof n||"function"!=typeof e)throw TypeError("Not a function");e(t)})}),s(a,"all",function(t){var n=this;return"[object Array]"!=p.call(t)?n.reject(TypeError("Not an array")):0===t.length?n.resolve([]):new n(function(e,o){if("function"!=typeof e||"function"!=typeof o)throw TypeError("Not a function");var r=t.length,i=Array(r),f=0;c(n,t,function(t,n){i[t]=n,++f===r&&e(i)},o)})}),s(a,"race",function(t){var n=this;return"[object Array]"!=p.call(t)?n.reject(TypeError("Not an array")):new n(function(e,o){if("function"!=typeof e||"function"!=typeof o)throw TypeError("Not a function");c(n,t,function(t,n){e(n)},o)})}),a});
|
||||
|
||||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||||
},{}]},{},[1])(1)
|
||||
});
|
File diff suppressed because it is too large
Load diff
|
@ -109,12 +109,12 @@ TEMPDIR="`mktemp -d 2>/dev/null || mktemp -d -t 'zotero-unit'`"
|
|||
PROFILE="$TEMPDIR/profile"
|
||||
mkdir -p "$PROFILE/extensions"
|
||||
|
||||
makePath ZOTERO_UNIT_PATH "$CWD"
|
||||
echo "$ZOTERO_UNIT_PATH" > "$PROFILE/extensions/zotero-unit@zotero.org"
|
||||
|
||||
makePath ZOTERO_PATH "`dirname "$CWD"`"
|
||||
makePath ZOTERO_PATH "`dirname "$CWD"`/build"
|
||||
echo "$ZOTERO_PATH" > "$PROFILE/extensions/zotero@chnm.gmu.edu"
|
||||
|
||||
makePath ZOTERO_UNIT_PATH "$ZOTERO_PATH/test"
|
||||
echo "$ZOTERO_UNIT_PATH" > "$PROFILE/extensions/zotero-unit@zotero.org"
|
||||
|
||||
# Create data directory
|
||||
mkdir "$TEMPDIR/Zotero"
|
||||
|
||||
|
|
|
@ -188,7 +188,7 @@ describe("Zotero.DataDirectory", function () {
|
|||
yield populateDataDirectory(oldDir, null, automatic);
|
||||
|
||||
let origFunc = OS.File.move;
|
||||
let fileMoveStub = sinon.stub(OS.File, "move", function () {
|
||||
let fileMoveStub = sinon.stub(OS.File, "move").callsFake(function () {
|
||||
if (OS.Path.basename(arguments[0]) == storageFile1) {
|
||||
return Zotero.Promise.reject(new Error("Error"));
|
||||
}
|
||||
|
@ -241,7 +241,7 @@ describe("Zotero.DataDirectory", function () {
|
|||
yield populateDataDirectory(oldDir, null, automatic);
|
||||
|
||||
let origFunc = OS.File.move;
|
||||
let stub1 = sinon.stub(OS.File, "move", function () {
|
||||
let stub1 = sinon.stub(OS.File, "move").callsFake(function () {
|
||||
if (OS.Path.basename(arguments[0]) == dbFilename) {
|
||||
return Zotero.Promise.reject(new Error("Error"));
|
||||
}
|
||||
|
@ -371,7 +371,7 @@ describe("Zotero.DataDirectory", function () {
|
|||
yield populateDataDirectory(oldDir);
|
||||
|
||||
let origFunc = OS.File.move;
|
||||
let stub1 = sinon.stub(OS.File, "move", function () {
|
||||
let stub1 = sinon.stub(OS.File, "move").callsFake(function () {
|
||||
if (OS.Path.basename(arguments[0]) == storageFile1) {
|
||||
return Zotero.Promise.reject(new Error("Error"));
|
||||
}
|
||||
|
|
|
@ -128,12 +128,12 @@ describe("Zotero.FeedItem", function () {
|
|||
it("should require feed being set", function* () {
|
||||
let feedItem = new Zotero.FeedItem('book', { guid: Zotero.randomString() });
|
||||
// Defaults to user library ID
|
||||
yield assert.isRejected(feedItem.saveTx(), /^Error: Cannot add /);
|
||||
yield assert.isRejected(feedItem.saveTx(), /^Cannot add /);
|
||||
});
|
||||
it("should require GUID being set", function* () {
|
||||
let feedItem = new Zotero.FeedItem('book');
|
||||
feedItem.libraryID = feed.libraryID;
|
||||
yield assert.isRejected(feedItem.saveTx(), /^Error: GUID must be set before saving FeedItem$/);
|
||||
yield assert.isRejected(feedItem.saveTx(), /^GUID must be set before saving FeedItem$/);
|
||||
});
|
||||
it("should require a unique GUID", function* () {
|
||||
let guid = Zotero.randomString();
|
||||
|
@ -149,7 +149,7 @@ describe("Zotero.FeedItem", function () {
|
|||
it("should require item type being set", function* () {
|
||||
let feedItem = new Zotero.FeedItem(null, { guid: Zotero.randomString() });
|
||||
feedItem.libraryID = feed.libraryID;
|
||||
yield assert.isRejected(feedItem.saveTx(), /^Error: Item type must be set before saving$/);
|
||||
yield assert.isRejected(feedItem.saveTx(), /^Item type must be set before saving$/);
|
||||
});
|
||||
it("should save feed item", function* () {
|
||||
let guid = Zotero.randomString();
|
||||
|
|
|
@ -12,7 +12,7 @@ describe("Zotero.Feed", function() {
|
|||
describe("#constructor()", function() {
|
||||
it("should accept required fields as arguments", function* () {
|
||||
let feed = new Zotero.Feed();
|
||||
yield assert.isRejected(feed.saveTx(), /^Error: Feed name not set$/);
|
||||
yield assert.isRejected(feed.saveTx(), /^Feed name not set$/);
|
||||
|
||||
feed = new Zotero.Feed({
|
||||
name: 'Test ' + Zotero.randomString(),
|
||||
|
@ -93,28 +93,28 @@ describe("Zotero.Feed", function() {
|
|||
});
|
||||
it("should throw if name or url are missing", function *() {
|
||||
let feed = new Zotero.Feed();
|
||||
yield assert.isRejected(feed.saveTx(), /^Error: Feed name not set$/);
|
||||
yield assert.isRejected(feed.saveTx(), /^Feed name not set$/);
|
||||
|
||||
feed.name = 'Test ' + Zotero.randomString();
|
||||
yield assert.isRejected(feed.saveTx(), /^Error: Feed URL not set$/);
|
||||
yield assert.isRejected(feed.saveTx(), /^Feed URL not set$/);
|
||||
|
||||
feed = new Zotero.Feed();
|
||||
feed.url = 'http://' + Zotero.randomString() + '.com';
|
||||
yield assert.isRejected(feed.saveTx(), /^Error: Feed name not set$/);
|
||||
yield assert.isRejected(feed.saveTx(), /^Feed name not set$/);
|
||||
});
|
||||
it("should not allow saving a feed with the same url", function *() {
|
||||
let url = 'http://' + Zotero.randomString() + '.com';
|
||||
let feed1 = yield createFeed({ url });
|
||||
|
||||
let feed2 = new Zotero.Feed({ name: 'Test ' + Zotero.randomString(), url });
|
||||
yield assert.isRejected(feed2.saveTx(), /^Error: Feed for URL already exists: /);
|
||||
yield assert.isRejected(feed2.saveTx(), /^Feed for URL already exists: /);
|
||||
|
||||
// Perform check with normalized URL
|
||||
feed2.url = url + '/';
|
||||
yield assert.isRejected(feed2.saveTx(), /^Error: Feed for URL already exists: /);
|
||||
yield assert.isRejected(feed2.saveTx(), /^Feed for URL already exists: /);
|
||||
|
||||
feed2.url = url.toUpperCase();
|
||||
yield assert.isRejected(feed2.saveTx(), /^Error: Feed for URL already exists: /);
|
||||
yield assert.isRejected(feed2.saveTx(), /^Feed for URL already exists: /);
|
||||
});
|
||||
it("should allow saving a feed with the same name", function *() {
|
||||
let name = 'Test ' + Zotero.randomString();
|
||||
|
@ -405,11 +405,11 @@ describe("Zotero.Feed", function() {
|
|||
})
|
||||
it("should not allow adding collections", function* () {
|
||||
let collection = new Zotero.Collection({ name: 'test', libraryID: feed.libraryID });
|
||||
yield assert.isRejected(collection.saveTx({ skipEditCheck: true }), /^Error: Cannot add /);
|
||||
yield assert.isRejected(collection.saveTx({ skipEditCheck: true }), /^Cannot add /);
|
||||
});
|
||||
it("should not allow adding saved search", function* () {
|
||||
let search = new Zotero.Search({ name: 'test', libraryID: feed.libraryID });
|
||||
yield assert.isRejected(search.saveTx({ skipEditCheck: true }), /^Error: Cannot add /);
|
||||
yield assert.isRejected(search.saveTx({ skipEditCheck: true }), /^Cannot add /);
|
||||
});
|
||||
it("should allow adding feed item", function* () {
|
||||
let feedItem = new Zotero.FeedItem('book', { guid: Zotero.randomString() });
|
||||
|
|
|
@ -4,7 +4,7 @@ describe("Zotero.Group", function () {
|
|||
describe("#constructor()", function() {
|
||||
it("should accept required parameters", function* () {
|
||||
let group = new Zotero.Group();
|
||||
yield assert.isRejected(group.saveTx(), "fails without required parameters");
|
||||
yield assert.isRejected(group.saveTx()); // fails without required parameters
|
||||
|
||||
let groupID = Zotero.Utilities.rand(10000, 1000000);
|
||||
let groupName = "Test " + Zotero.Utilities.randomString();
|
||||
|
|
|
@ -300,14 +300,20 @@ describe("Zotero.Integration", function () {
|
|||
}
|
||||
setAddEditItems(testItems[0]);
|
||||
|
||||
sinon.stub(Zotero.Integration, 'getApplication', function(agent, command, docID) {
|
||||
sinon.stub(Zotero.Integration, 'getApplication').callsFake(function(agent, command, docID) {
|
||||
if (!applications[docID]) {
|
||||
applications[docID] = new DocumentPluginDummy.Application();
|
||||
}
|
||||
return applications[docID];
|
||||
});
|
||||
|
||||
displayDialogStub = sinon.stub(Zotero.Integration, 'displayDialog', function(doc, dialogName, prefs, io) {
|
||||
displayDialogStub = sinon.stub(Zotero.Integration, 'displayDialog',
|
||||
// @TODO: This sinon.stub syntax is deprecated!
|
||||
// However when using callsFake tests won't work. This is due to a
|
||||
// possible bug that reset() erases callsFake.
|
||||
// @NOTE: https://github.com/sinonjs/sinon/issues/1341
|
||||
// displayDialogStub.callsFake(function(doc, dialogName, prefs, io) {
|
||||
function(doc, dialogName, prefs, io) {
|
||||
var ioResult = dialogResults[dialogName.substring(dialogName.lastIndexOf('/')+1, dialogName.length-4)];
|
||||
if (typeof ioResult == 'function') {
|
||||
ioResult = ioResult(doc, dialogName);
|
||||
|
@ -389,7 +395,7 @@ describe("Zotero.Integration", function () {
|
|||
var styleInstallStub = sinon.stub(Zotero.Styles, "install").resolves();
|
||||
var style = Zotero.Styles.get(styleID);
|
||||
var styleGetCalledOnce = false;
|
||||
var styleGetStub = sinon.stub(Zotero.Styles, 'get', function() {
|
||||
var styleGetStub = sinon.stub(Zotero.Styles, 'get').callsFake(function() {
|
||||
if (!styleGetCalledOnce) {
|
||||
styleGetCalledOnce = true;
|
||||
return false;
|
||||
|
@ -422,7 +428,7 @@ describe("Zotero.Integration", function () {
|
|||
var styleInstallStub = sinon.stub(Zotero.Styles, "install").resolves();
|
||||
var style = Zotero.Styles.get(styleID);
|
||||
var styleGetCalledOnce = false;
|
||||
var styleGetStub = sinon.stub(Zotero.Styles, 'get', function() {
|
||||
var styleGetStub = sinon.stub(Zotero.Styles, 'get').callsFake(function() {
|
||||
if (!styleGetCalledOnce) {
|
||||
styleGetCalledOnce = true;
|
||||
return false;
|
||||
|
|
|
@ -146,7 +146,7 @@ describe("Zotero.Libraries", function() {
|
|||
assert.equal(Zotero.Libraries.isEditable(group.libraryID), startState, 'reverts state');
|
||||
});
|
||||
it("should throw for invalid library ID", function() {
|
||||
return assert.isRejected(Zotero.Libraries.setEditable(-1), /^Error: Invalid library ID /);
|
||||
return assert.isRejected(Zotero.Libraries.setEditable(-1), /^Invalid library ID /);
|
||||
});
|
||||
});
|
||||
describe("#isFilesEditable()", function() {
|
||||
|
@ -176,7 +176,7 @@ describe("Zotero.Libraries", function() {
|
|||
yield Zotero.Libraries.setEditable(group.libraryID, editableStartState);
|
||||
});
|
||||
it("should throw for invalid library ID", function* () {
|
||||
return assert.isRejected(Zotero.Libraries.setFilesEditable(-1), /^Error: Invalid library ID /);
|
||||
return assert.isRejected(Zotero.Libraries.setFilesEditable(-1), /^Invalid library ID /);
|
||||
});
|
||||
});
|
||||
describe("#isGroupLibrary()", function() {
|
||||
|
|
|
@ -157,7 +157,7 @@ describe("Zotero.Library", function() {
|
|||
describe("#save()", function() {
|
||||
it("should require mandatory parameters to be set", function* () {
|
||||
let library = new Zotero.Library({ editable: true, filesEditable: true });
|
||||
yield assert.isRejected(library.saveTx(), /^Error: libraryType must be set before saving/, 'libraryType is mandatory');
|
||||
yield assert.isRejected(library.saveTx(), /^libraryType must be set before saving/, 'libraryType is mandatory');
|
||||
|
||||
// Required group params
|
||||
let groupID = Zotero.Utilities.rand(1000, 10000);
|
||||
|
@ -165,10 +165,10 @@ describe("Zotero.Library", function() {
|
|||
let description = '';
|
||||
let version = Zotero.Utilities.rand(1000, 10000);
|
||||
library = new Zotero.Group({ filesEditable: true, groupID, name , description, version });
|
||||
yield assert.isRejected(library.saveTx(), /^Error: editable must be set before saving/, 'editable is mandatory');
|
||||
yield assert.isRejected(library.saveTx(), /^editable must be set before saving/, 'editable is mandatory');
|
||||
|
||||
library = new Zotero.Group({ editable: true, groupID, name , description, version });
|
||||
yield assert.isRejected(library.saveTx(), /^Error: filesEditable must be set before saving/, 'filesEditable is mandatory');
|
||||
yield assert.isRejected(library.saveTx(), /^filesEditable must be set before saving/, 'filesEditable is mandatory');
|
||||
|
||||
library = new Zotero.Group({ editable: true, filesEditable: true, groupID, name , description, version });
|
||||
yield assert.isFulfilled(library.saveTx());
|
||||
|
@ -217,7 +217,7 @@ describe("Zotero.Library", function() {
|
|||
|
||||
it("should not allow erasing permanent libraries", function* () {
|
||||
let library = Zotero.Libraries.get(Zotero.Libraries.userLibraryID);
|
||||
yield assert.isRejected(library.eraseTx(), /^Error: Cannot erase library of type 'user'$/, "does not allow erasing user library");
|
||||
yield assert.isRejected(library.eraseTx(), /^Cannot erase library of type 'user'$/, "does not allow erasing user library");
|
||||
});
|
||||
|
||||
it("should not allow erasing unsaved libraries", function* () {
|
||||
|
|
|
@ -464,7 +464,7 @@ describe("Connector Server", function () {
|
|||
});
|
||||
|
||||
it('should import a style with application/vnd.citationstyles.style+xml content-type', function* () {
|
||||
sinon.stub(Zotero.Styles, 'install', function(style) {
|
||||
sinon.stub(Zotero.Styles, 'install').callsFake(function(style) {
|
||||
var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
|
||||
.createInstance(Components.interfaces.nsIDOMParser),
|
||||
doc = parser.parseFromString(style, "application/xml");
|
||||
|
|
|
@ -286,7 +286,7 @@ describe("Zotero.Sync.Storage.Local", function () {
|
|||
|
||||
// Stub functions to simulate OS.Path.basename() behavior on Windows
|
||||
var basenameOrigFunc = OS.Path.basename.bind(OS.Path);
|
||||
var basenameStub = sinon.stub(OS.Path, "basename", (path) => {
|
||||
var basenameStub = sinon.stub(OS.Path, "basename").callsFake((path) => {
|
||||
// Split on colon
|
||||
if (path.endsWith("a:b.txt")) {
|
||||
return "b.txt";
|
||||
|
@ -294,7 +294,7 @@ describe("Zotero.Sync.Storage.Local", function () {
|
|||
return basenameOrigFunc(path);
|
||||
});
|
||||
var pathToFileOrigFunc = Zotero.File.pathToFile.bind(Zotero.File);
|
||||
var pathToFileStub = sinon.stub(Zotero.File, "pathToFile", (path) => {
|
||||
var pathToFileStub = sinon.stub(Zotero.File, "pathToFile").callsFake((path) => {
|
||||
if (path.includes(":")) {
|
||||
throw new Error("Path contains colon");
|
||||
}
|
||||
|
@ -476,7 +476,7 @@ describe("Zotero.Sync.Storage.Local", function () {
|
|||
|
||||
// Stub functions to simulate OS.Path.basename() behavior on Windows
|
||||
var basenameOrigFunc = OS.Path.basename.bind(OS.Path);
|
||||
var basenameStub = sinon.stub(OS.Path, "basename", (path) => {
|
||||
var basenameStub = sinon.stub(OS.Path, "basename").callsFake((path) => {
|
||||
// Split on colon
|
||||
if (path.endsWith("a:b.html")) {
|
||||
return "b.html";
|
||||
|
@ -484,7 +484,7 @@ describe("Zotero.Sync.Storage.Local", function () {
|
|||
return basenameOrigFunc(path);
|
||||
});
|
||||
var pathToFileOrigFunc = Zotero.File.pathToFile.bind(Zotero.File);
|
||||
var pathToFileStub = sinon.stub(Zotero.File, "pathToFile", (path) => {
|
||||
var pathToFileStub = sinon.stub(Zotero.File, "pathToFile").callsFake((path) => {
|
||||
if (path.includes(":")) {
|
||||
throw new Error("Path contains colon");
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ describe("Zotero.Styles", function() {
|
|||
|
||||
it("should install the style from url", function* () {
|
||||
var getContentsFromURLAsync = Zotero.File.getContentsFromURLAsync;
|
||||
sinon.stub(Zotero.File, 'getContentsFromURLAsync', function(style) {
|
||||
sinon.stub(Zotero.File, 'getContentsFromURLAsync').callsFake(function(style) {
|
||||
if (style.url == styleID) {
|
||||
return Zotero.Promise.resolve(style);
|
||||
} else {
|
||||
|
|
Loading…
Add table
Reference in a new issue