diff --git a/.github/workflows/jest.yaml b/.github/workflows/jest.yaml
index 0bbe2978043..634c87272e2 100644
--- a/.github/workflows/jest.yaml
+++ b/.github/workflows/jest.yaml
@@ -31,7 +31,5 @@ jobs:
run: yarn run gulp client
working-directory: client
- name: Run Unit Tests
- run: yarn run qunit
- working-directory: client
- run: yarn jest
working-directory: client
diff --git a/client/.eslintrc.json b/client/.eslintrc.json
index a02efdbb365..b05eefa6c72 100644
--- a/client/.eslintrc.json
+++ b/client/.eslintrc.json
@@ -59,7 +59,7 @@
"vuejs-accessibility/no-autofocus": "error",
"vuejs-accessibility/tabindex-no-positive": "error"
},
- "ignorePatterns": ["dist", "src/qunit", "src/mocha", "src/libs", "src/nls", "src/legacy"],
+ "ignorePatterns": ["dist", "src/libs", "src/nls", "src/legacy"],
"overrides": [
{
"files": ["**/*.vue"],
diff --git a/client/README.md b/client/README.md
index 4eff98fefb4..667eb23b05e 100644
--- a/client/README.md
+++ b/client/README.md
@@ -122,10 +122,6 @@ utils](https://vue-test-utils.vuejs.org/) to mount individual components in a
test bed and check them for rendered features. Please use jest-based mocking
for isolating test functionality.
-A set of older qUnit tests also exist which will be phased-out as the code they
-support is replaced with modern component-based implementations. In the
-meantime, we still run the qunit tests in sequence.
-
### Running the tests
#### At Build-Time
@@ -145,15 +141,7 @@ commands.
This is what CI is going to run, and also what 'make client-test' invokes,
executing all the client tests:
- yarn run test
-
-You can also bypass qunit and single-run all of the jest tests like so:
-
- yarn run jest
-
-Or, if you want to run just the qunit tests:
-
- yarn run qunit
+ yarn test
##### Watch and rerun jest unit tests every time a source file changes
diff --git a/client/package.json b/client/package.json
index 9c40106e496..3197b653dfe 100644
--- a/client/package.json
+++ b/client/package.json
@@ -128,10 +128,9 @@
"format": "prettier --write . --cache",
"format-check": "prettier --check .",
"prettier": "yarn run format",
- "test": "yarn run qunit && yarn run jest",
+ "test": "yarn run jest",
"jest": "jest --config tests/jest/jest.config.js",
"jest-watch": "jest --config tests/jest/jest.config.js --watch",
- "qunit": "karma start tests/karma/karma.config.qunit.js",
"eslint-precommit": "eslint -c .eslintrc.json --quiet --ext .js,.vue,.ts src tests/jest/standalone",
"eslint": "eslint -c .eslintrc.json --ext .js,.vue,.ts src tests/jest/standalone"
},
@@ -170,16 +169,10 @@
"jest-environment-jsdom": "^29.3.1",
"jest-location-mock": "^1.0.9",
"json-loader": "^0.5.7",
- "karma": "^6.3.16",
- "karma-chrome-launcher": "^3.1.0",
- "karma-polyfill": "^1.1.0",
- "karma-qunit": "^4.1.2",
- "karma-webpack": "^5.0.0",
"mini-css-extract-plugin": "^2.5.3",
"postcss-loader": "^7.0.2",
"prettier": "^2.8.3",
"process": "^0.11.10",
- "qunit": "^2.17.2",
"raw-loader": "^4.0.2",
"sass": "^1.58.0",
"sass-loader": "^13.2.0",
diff --git a/client/src/app/app.test.js b/client/src/app/app.test.js
new file mode 100644
index 00000000000..71fc91e4a3b
--- /dev/null
+++ b/client/src/app/app.test.js
@@ -0,0 +1,69 @@
+import { getGalaxyInstance, setGalaxyInstance } from "app";
+import Backbone from "backbone";
+import galaxyOptions from "@tests/test-data/bootstrapped";
+
+export function setupTestGalaxy(galaxyOptions_ = null) {
+ galaxyOptions_ = galaxyOptions_ || galaxyOptions;
+ setGalaxyInstance((GalaxyApp) => {
+ const galaxy = new GalaxyApp(galaxyOptions_);
+ galaxy.currHistoryPanel = {
+ model: new Backbone.Model(),
+ };
+ return galaxy;
+ });
+}
+
+describe("App base construction/initializiation defaults", () => {
+ beforeEach(() => {
+ setupTestGalaxy(galaxyOptions);
+ });
+
+ test("App base construction/initializiation defaults", function () {
+ const app = getGalaxyInstance();
+ expect(app.options && typeof app.options === "object").toBeTruthy();
+ expect(app.config && typeof app.config === "object").toBeTruthy();
+ expect(app.user && typeof app.config === "object").toBeTruthy();
+ expect(app.localize).toBe(window._l);
+ });
+
+ test("App base default options", function () {
+ const app = getGalaxyInstance();
+ expect(app.options !== undefined && typeof app.options === "object").toBeTruthy();
+ expect(app.options.root).toBe("/");
+ expect(app.options.patchExisting).toBe(true);
+ });
+
+ test("App base extends from Backbone.Events", function () {
+ const app = getGalaxyInstance();
+ ["on", "off", "trigger", "listenTo", "stopListening"].forEach(function (fn) {
+ expect(Object.prototype.hasOwnProperty.call(app, fn) && typeof app[fn] === "function").toBeTruthy();
+ });
+ });
+
+ // // We no longer want this behavior, but leaving the test to express that
+ test("App base will patch in attributes from existing Galaxy objects", function () {
+ const existingApp = getGalaxyInstance();
+ existingApp.foo = 123;
+
+ const newApp = setGalaxyInstance((GalaxyApp) => {
+ return new GalaxyApp();
+ });
+
+ expect(newApp.foo === 123).toBeTruthy();
+ });
+
+ test("App base config", function () {
+ const app = getGalaxyInstance();
+ expect(app.config && typeof app.config === "object").toBeTruthy();
+ expect(app.config.allow_user_deletion).toBe(false);
+ expect(app.config.allow_user_creation).toBe(true);
+ expect(app.config.wiki_url).toBe("https://galaxyproject.org/");
+ expect(app.config.ftp_upload_site).toBe(null);
+ });
+
+ test("App base user", function () {
+ const app = getGalaxyInstance();
+ expect(app.user !== undefined && typeof app.user === "object").toBeTruthy();
+ expect(app.user.isAdmin() === false).toBeTruthy();
+ });
+});
diff --git a/client/src/app/base-mvc.js b/client/src/app/base-mvc.js
index 961a02ff590..c547942779e 100644
--- a/client/src/app/base-mvc.js
+++ b/client/src/app/base-mvc.js
@@ -1,42 +1,8 @@
import $ from "jquery";
import _ from "underscore";
import Backbone from "backbone";
-import addLogging from "utils/add-logging";
import _l from "utils/localization";
-//==============================================================================
-/** @class Mixin to add logging capabilities to an object.
- * Designed to allow switching an objects log output off/on at one central
- * statement. Can be used with plain browser console (or something more
- * complex like an AJAX logger).
- *
NOTE: currently only uses the console.debug log function
- * (as opposed to debug, error, warn, etc.)
- * @name LoggableMixin
- *
- * @example
- * // Add to your models/views at the definition using chaining:
- * var MyModel = Backbone.Model.extend( LoggableMixin ).extend({ // ... });
- *
- * // or - more explicitly AFTER the definition:
- * var MyModel = Backbone.Model.extend({
- * logger : console
- * // ...
- * this.log( '$#%& it! - broken already...' );
- * })
- * _.extend( MyModel.prototype, LoggableMixin )
- *
- */
-var LoggableMixin = /** @lends LoggableMixin# */ {
- // replace null with console (if available) to see all logs for a particular view/model
- /** The logging object whose log function will be used to output
- * messages. Null will supress all logging. Commonly set to console.
- */
- logger: null,
- /** @type {String} a namespace for filtering/focusing log output */
- _logNamespace: ".",
-};
-addLogging(LoggableMixin);
-
//==============================================================================
/** Backbone model that syncs to the browser's sessionStorage API.
* This all largely happens behind the scenes and no special calls are required.
@@ -196,7 +162,7 @@ var SearchableModelMixin = {
/** search the attribute with key attrKey for the string searchFor; T/F if found */
searchAttribute: function (attrKey, searchFor) {
var attrVal = this.get(attrKey);
- //this.debug( 'searchAttribute', attrKey, attrVal, searchFor );
+ //console.debug( 'searchAttribute', attrKey, attrVal, searchFor );
// bail if empty searchFor or unsearchable values
if (!searchFor || attrVal === undefined || attrVal === null) {
return false;
@@ -210,7 +176,7 @@ var SearchableModelMixin = {
/** deep(er) search for array attributes; T/F if found */
_searchArrayAttribute: function (array, searchFor) {
- //this.debug( '_searchArrayAttribute', array, searchFor );
+ //console.debug( '_searchArrayAttribute', array, searchFor );
searchFor = searchFor.toLowerCase();
//precondition: searchFor has already been validated as non-empty string
//precondition: assumes only 1 level array
@@ -575,7 +541,6 @@ function buildComparator(attribute_name, options) {
//==============================================================================
export default {
- LoggableMixin: LoggableMixin,
SessionStorageModel: SessionStorageModel,
mixin: mixin,
SearchableModelMixin: SearchableModelMixin,
diff --git a/client/src/app/galaxy.js b/client/src/app/galaxy.js
index 0b506a86abf..e84180f6de5 100644
--- a/client/src/app/galaxy.js
+++ b/client/src/app/galaxy.js
@@ -1,10 +1,7 @@
import $ from "jquery";
import _ from "underscore";
import Backbone from "backbone";
-import BASE_MVC from "./base-mvc";
import userModel from "./user-model";
-import metricsLogger from "utils/metrics-logger";
-import addLogging from "utils/add-logging";
import { localize, _setUserLocale, _getUserLocale } from "utils/localization";
import { getGalaxyInstance } from "app";
import { create, dialog } from "utils/data";
@@ -12,7 +9,6 @@ import { create, dialog } from "utils/data";
// ============================================================================
/** Base galaxy client-side application.
* Iniitializes:
- * logger : the logger/metrics-logger
* localize : the string localizer
* config : the current configuration (any k/v in
* galaxy.ini available from the configuration API)
@@ -22,29 +18,9 @@ export function GalaxyApp(options = {}, bootstrapped = {}) {
this._init(options, bootstrapped);
}
-// add logging shortcuts for this object
-addLogging(GalaxyApp, "GalaxyApp");
-
-// a debug flag can be set via local storage and made available during script/page loading
-const DEBUGGING_KEY = "galaxy:debug";
-
-const NAMESPACE_KEY = `${DEBUGGING_KEY}:namespaces`;
-const FLATTEN_LOG_MESSAGES_KEY = `${DEBUGGING_KEY}:flatten`;
-
-let localDebugging = false;
-try {
- localDebugging = localStorage.getItem(DEBUGGING_KEY) == "true";
-} catch (storageErr) {
- console.log(localize("localStorage not available for debug flag retrieval"));
-}
-
/** initalize options and sub-components */
GalaxyApp.prototype._init = function (options, bootstrapped) {
_.extend(this, Backbone.Events);
- if (localDebugging) {
- this.logger = console;
- console.debug("debugging galaxy:", "options:", options, "bootstrapped:", bootstrapped);
- }
this._processOptions(options);
this._initConfig(options.config || {});
@@ -62,24 +38,15 @@ GalaxyApp.prototype._init = function (options, bootstrapped) {
this.params = options.params || {};
this.session_csrf_token = options.session_csrf_token || null;
- this._initLogger(this.options.loggerOptions || {});
- // at this point, either logging or not and namespaces are enabled - chat it up
- this.debug("GalaxyApp.options: ", this.options);
- this.debug("GalaxyApp.config: ", this.config);
- this.debug("GalaxyApp.logger: ", this.logger);
-
this._initLocale();
- this.debug("GalaxyApp.localize: ", this.localize);
this.config = options.config || {};
- this.debug("GalaxyApp.config: ", this.config);
this._initUser(options.user || {});
- this.debug("GalaxyApp.user: ", this.user);
_setUserLocale(this.user, this.config);
_getUserLocale();
- this.debug("currentLocale: ", sessionStorage.getItem("currentLocale"));
+ console.debug("currentLocale: ", sessionStorage.getItem("currentLocale"));
this._setUpListeners();
this.trigger("ready", this);
@@ -119,9 +86,6 @@ GalaxyApp.prototype._processOptions = function _processOptions(options) {
GalaxyApp.prototype._initConfig = function _initConfig(config) {
this.config = config;
- // give precendence to localdebugging for this setting
- this.config.debug = localDebugging || this.config.debug;
-
return this;
};
@@ -129,56 +93,20 @@ GalaxyApp.prototype._initConfig = function _initConfig(config) {
GalaxyApp.prototype._patchGalaxy = function _patchGalaxy(patchWith) {
// in case req or plain script tag order has created a prev. version of the Galaxy obj...
if (this.options.patchExisting && patchWith) {
- // this.debug( 'found existing Galaxy object:', patchWith );
+ // console.debug( 'found existing Galaxy object:', patchWith );
// ...(for now) monkey patch any added attributes that the previous Galaxy may have had
//TODO: move those attributes to more formal assignment in GalaxyApp
for (const k in patchWith) {
if (Object.prototype.hasOwnProperty.call(patchWith, k)) {
- // this.debug( '\t patching in ' + k + ' to Galaxy:', this[ k ] );
+ // console.debug( '\t patching in ' + k + ' to Galaxy:', this[ k ] );
this[k] = patchWith[k];
}
}
}
};
-/** set up the metrics logger (utils/metrics-logger) and pass loggerOptions */
-GalaxyApp.prototype._initLogger = function _initLogger(loggerOptions) {
- // default to console logging at the debug level if the debug flag is set
- if (this.config.debug) {
- loggerOptions.consoleLogger = loggerOptions.consoleLogger || console;
- loggerOptions.consoleLevel = loggerOptions.consoleLevel || metricsLogger.MetricsLogger.ALL;
- // load any logging namespaces from localStorage if we can
- try {
- loggerOptions.consoleNamespaceWhitelist = localStorage.getItem(NAMESPACE_KEY).split(",");
- } catch (storageErr) {
- console.debug(storageErr);
- }
- try {
- loggerOptions.consoleFlattenMessages = localStorage.getItem(FLATTEN_LOG_MESSAGES_KEY) == "true";
- } catch (storageErr) {
- console.debug(storageErr);
- }
- console.log(loggerOptions.consoleFlattenMessages);
- }
-
- this.logger = new metricsLogger.MetricsLogger(loggerOptions);
- this.emit = {};
- ["log", "debug", "info", "warn", "error", "metric"].map((i) => {
- this.emit[i] = (data) => {
- this.logger.emit(i, arguments[0], Array.prototype.slice.call(arguments, 1));
- };
- });
-
- if (this.config.debug) {
- // add this logger to mvc's loggable mixin so that all models can use the logger
- BASE_MVC.LoggableMixin.logger = this.logger;
- }
- return this;
-};
-
/** add the localize fn to this object and the window namespace (as '_l') */
-GalaxyApp.prototype._initLocale = function _initLocale(options) {
- this.debug("_initLocale:", options);
+GalaxyApp.prototype._initLocale = function _initLocale() {
this.localize = localize;
// add to window as global shortened alias
// TODO: temporary - remove when can require for plugins
@@ -220,9 +148,8 @@ GalaxyApp.prototype._initUserLocale = function _initUserLocale(options) {
/** set up the current user as a Backbone model (mvc/user/user-model) */
GalaxyApp.prototype._initUser = function _initUser(userJSON) {
- this.debug("_initUser:", userJSON);
+ console.debug("_initUser:", userJSON);
this.user = new userModel.User(userJSON);
- this.user.logger = this.logger;
return this;
};
@@ -248,52 +175,6 @@ GalaxyApp.prototype._setUpListeners = function _setUpListeners() {
return this;
};
-/** Turn debugging/console-output on/off by passing boolean. Pass nothing to get current setting. */
-GalaxyApp.prototype.debugging = function _debugging(setting) {
- try {
- if (setting === undefined) {
- return localStorage.getItem(DEBUGGING_KEY) === "true";
- }
- if (setting) {
- localStorage.setItem(DEBUGGING_KEY, true);
- return true;
- }
-
- localStorage.removeItem(DEBUGGING_KEY);
- // also remove all namespaces
- this.debuggingNamespaces(null);
- } catch (storageErr) {
- console.log(localize("localStorage not available for debug flag retrieval"));
- }
- return false;
-};
-
-/** Add, remove, or clear namespaces from the debugging filters
- * Pass no arguments to retrieve the existing namespaces as an array.
- * Pass in null to clear all namespaces (all logging messages will show now).
- * Pass in an array of strings or single string of the namespaces to filter to.
- * Returns the new/current namespaces as an array;
- */
-GalaxyApp.prototype.debuggingNamespaces = function _debuggingNamespaces(namespaces) {
- try {
- if (namespaces === undefined) {
- const csv = localStorage.getItem(NAMESPACE_KEY);
- return typeof csv === "string" ? csv.split(",") : [];
- } else if (namespaces === null) {
- localStorage.removeItem(NAMESPACE_KEY);
- } else {
- localStorage.setItem(NAMESPACE_KEY, namespaces);
- }
- const newSettings = this.debuggingNamespaces();
- if (this.logger) {
- this.logger.options.consoleNamespaceWhitelist = newSettings;
- }
- return newSettings;
- } catch (storageErr) {
- console.log(localize("localStorage not available for debug namespace retrieval"));
- }
-};
-
/** string rep */
GalaxyApp.prototype.toString = function toString() {
const userEmail = this.user ? this.user.get("email") || "(anonymous)" : "uninitialized";
diff --git a/client/src/app/singleton.js b/client/src/app/singleton.js
index 2fcb87470b7..fb9f147c428 100644
--- a/client/src/app/singleton.js
+++ b/client/src/app/singleton.js
@@ -2,7 +2,6 @@
* TODO: Make this part of galaxy.js later, once the global refs are gone
*/
-import addLogging from "utils/add-logging";
import config from "config";
import { GalaxyApp } from "./galaxy";
import { serverPath } from "utils/serverPath";
@@ -17,9 +16,6 @@ export function setGalaxyInstance(factory) {
if (!(newInstance instanceof GalaxyApp)) {
newInstance = new GalaxyApp(newInstance);
}
- if (newInstance.debug === undefined) {
- addLogging(newInstance, "GalaxyApp");
- }
storage._galaxyInstance = newInstance;
diff --git a/client/src/app/user-model.js b/client/src/app/user-model.js
index b382f24d841..f4d6de32684 100644
--- a/client/src/app/user-model.js
+++ b/client/src/app/user-model.js
@@ -1,17 +1,13 @@
import Backbone from "backbone";
import { getAppRoot } from "onload/loadConfig";
-import baseMVC from "./base-mvc";
import _l from "utils/localization";
-var logNamespace = "user";
//==============================================================================
/** @class Model for a Galaxy user (including anonymous users).
* @name User
*/
-var User = Backbone.Model.extend(baseMVC.LoggableMixin).extend(
+var User = Backbone.Model.extend(
/** @lends User.prototype */ {
- _logNamespace: logNamespace,
-
/** API location for this resource */
urlRoot: function () {
return `${getAppRoot()}api/users`;
@@ -36,13 +32,11 @@ var User = Backbone.Model.extend(baseMVC.LoggableMixin).extend(
* @param {Object} data Initial model data.
*/
initialize: function (data) {
- this.log("User.initialize:", data);
-
this.on("loaded", function (model, resp) {
- this.log(`${this} has loaded:`, model, resp);
+ console.log(`${this} has loaded:`, model, resp);
});
this.on("change", function (model, data) {
- this.log(`${this} has changed:`, model, data.changes);
+ console.log(`${this} has changed:`, model, data.changes);
});
},
@@ -142,15 +136,6 @@ User.getCurrentUserFromApi = (options) => {
return currentUser;
};
-// (stub) collection for users (shouldn't be common unless admin UI)
-//var UserCollection = Backbone.Collection.extend(baseMVC.LoggableMixin).extend({
-// model: User,
-// urlRoot: function() {
-// return `${getAppRoot()}api/users`;
-// }
-// //logger : console,
-//});
-
//==============================================================================
export default {
User: User,
diff --git a/client/src/components/Collections/PairedListCollectionCreator.test.js b/client/src/components/Collections/PairedListCollectionCreator.test.js
index 393dd33884f..ad545196207 100644
--- a/client/src/components/Collections/PairedListCollectionCreator.test.js
+++ b/client/src/components/Collections/PairedListCollectionCreator.test.js
@@ -1,7 +1,7 @@
import { mount } from "@vue/test-utils";
import { shallowMount } from "@vue/test-utils";
import PairedListCollectionCreator from "components/Collections/PairedListCollectionCreator";
-import DATA from "../../../tests/qunit/test-data/paired-collection-creator.data.js";
+import DATA from "@tests/test-data/paired-collection-creator.data.js";
describe("PairedListCollectionCreator", () => {
let wrapper;
diff --git a/client/src/components/Collections/PairedListCollectionCreator.vue b/client/src/components/Collections/PairedListCollectionCreator.vue
index a2160206986..9282e15168a 100644
--- a/client/src/components/Collections/PairedListCollectionCreator.vue
+++ b/client/src/components/Collections/PairedListCollectionCreator.vue
@@ -669,7 +669,7 @@ export default {
},
/** sort initial list */
_sortInitialList: function () {
- //this.debug( '-- _sortInitialList' );
+ //console.debug( '-- _sortInitialList' );
this._sortDatasetList(this.workingElements);
},
@@ -813,7 +813,7 @@ export default {
}
// uncomment to see printlns while running tests
- //this.debug = function(){ console.log.apply( console, arguments ); };
+ //console.debug = function(){ console.log.apply( console, arguments ); };
// then try the remainder with something less strict
strategy = strategy || this.strategy;
@@ -909,7 +909,7 @@ export default {
};
return function _strategy(params) {
- // this.debug("autopair _strategy ---------------------------");
+ // console.debug("autopair _strategy ---------------------------");
params = params || {};
var listA = params.listA;
var listB = params.listB;
@@ -923,8 +923,8 @@ export default {
var paired = [];
//console.debug( 'params:', JSON.stringify( params, null, ' ' ) );
- // this.debug("starting list lens:", listA.length, listB.length);
- // this.debug("bestMatch (starting):", JSON.stringify(bestMatch, null, " "));
+ // console.debug("starting list lens:", listA.length, listB.length);
+ // console.debug("bestMatch (starting):", JSON.stringify(bestMatch, null, " "));
while (indexA < listA.length) {
var matchTo = listA[indexA];
@@ -932,8 +932,8 @@ export default {
for (indexB = 0; indexB < listB.length; indexB++) {
var possible = listB[indexB];
- // this.debug(`${indexA}:${matchTo.name}`);
- // this.debug(`${indexB}:${possible.name}`);
+ // console.debug(`${indexA}:${matchTo.name}`);
+ // console.debug(`${indexB}:${possible.name}`);
// no matching with self
if (listA[indexA] !== listB[indexB]) {
@@ -946,16 +946,16 @@ export default {
bestMatch: bestMatch,
})
);
- // this.debug("bestMatch:", JSON.stringify(bestMatch, null, " "));
+ // console.debug("bestMatch:", JSON.stringify(bestMatch, null, " "));
if (bestMatch.score === 1.0) {
- // this.debug("breaking early due to perfect match");
+ // console.debug("breaking early due to perfect match");
break;
}
}
}
var scoreThreshold = options.scoreThreshold.call(this);
- // this.debug("scoreThreshold:", scoreThreshold);
- // this.debug("bestMatch.score:", bestMatch.score);
+ // console.debug("scoreThreshold:", scoreThreshold);
+ // console.debug("bestMatch.score:", bestMatch.score);
if (bestMatch.score >= scoreThreshold) {
//console.debug( 'autoPairFnBuilder.strategy', listA[ indexA ].name, listB[ bestMatch.index ].name );
@@ -975,8 +975,8 @@ export default {
return paired;
}
}
- // this.debug("paired:", JSON.stringify(paired, null, " "));
- // this.debug("autopair _strategy ---------------------------");
+ // console.debug("paired:", JSON.stringify(paired, null, " "));
+ // console.debug("autopair _strategy ---------------------------");
return paired;
};
},
diff --git a/client/src/components/Datatypes/test-data/datatypes.json b/client/src/components/Datatypes/test-data/datatypes.json
deleted file mode 120000
index f32f2aee513..00000000000
--- a/client/src/components/Datatypes/test-data/datatypes.json
+++ /dev/null
@@ -1 +0,0 @@
-../../../../tests/qunit/test-data/json/datatypes.json
\ No newline at end of file
diff --git a/client/src/components/Datatypes/test-data/datatypes.mapping.json b/client/src/components/Datatypes/test-data/datatypes.mapping.json
deleted file mode 120000
index de79c06a39b..00000000000
--- a/client/src/components/Datatypes/test-data/datatypes.mapping.json
+++ /dev/null
@@ -1 +0,0 @@
-../../../../tests/qunit/test-data/json/datatypes.mapping.json
\ No newline at end of file
diff --git a/client/src/components/Datatypes/test_fixtures.ts b/client/src/components/Datatypes/test_fixtures.ts
index 0e58ccb475c..3108af7025f 100644
--- a/client/src/components/Datatypes/test_fixtures.ts
+++ b/client/src/components/Datatypes/test_fixtures.ts
@@ -1,6 +1,6 @@
// TODO: Swap these awful relative paths to an alias
-import DatatypesMappingJson from "./test-data/datatypes.mapping.json";
-import DatatypesJson from "./test-data/datatypes.json";
+import DatatypesMappingJson from "@tests/test-data/json/datatypes.mapping.json";
+import DatatypesJson from "@tests/test-data/json/datatypes.json";
import { DatatypesMapperModel } from "./model";
import type { DatatypesCombinedMap } from "./model";
diff --git a/client/src/components/Form/Elements/parameters.js b/client/src/components/Form/Elements/parameters.js
index c9fbc13a745..b2b9bfec050 100644
--- a/client/src/components/Form/Elements/parameters.js
+++ b/client/src/components/Form/Elements/parameters.js
@@ -37,12 +37,11 @@ export default Backbone.View.extend({
/** Returns an input field for a given field type */
create: function (input_def) {
- const Galaxy = getGalaxyInstance();
var fieldClass = this.types[input_def.type];
this.field = typeof this[fieldClass] === "function" ? this[fieldClass].call(this, input_def) : null;
if (!this.field) {
this.field = input_def.options ? this._fieldSelect(input_def) : this._fieldText(input_def);
- Galaxy.emit.debug("form-parameters::_addRow()", `Auto matched field type (${input_def.type}).`);
+ console.debug("form-parameters::_addRow()", `Auto matched field type (${input_def.type}).`);
}
if (input_def.value === undefined) {
input_def.value = null;
diff --git a/client/src/components/History/Export/HistoryExport.test.ts b/client/src/components/History/Export/HistoryExport.test.ts
index e2ec1de4f38..73021ce655c 100644
--- a/client/src/components/History/Export/HistoryExport.test.ts
+++ b/client/src/components/History/Export/HistoryExport.test.ts
@@ -8,7 +8,7 @@ import {
} from "@/components/Common/models/testData/exportData";
import flushPromises from "flush-promises";
import type { components } from "@/schema";
-import { getLocalVue } from "../../../../tests/jest/helpers";
+import { getLocalVue } from "@tests/jest/helpers";
import HistoryExport from "./HistoryExport.vue";
import { getExportRecords } from "./services";
diff --git a/client/src/components/Libraries/LibraryFolder/TopToolbar/library-model.js b/client/src/components/Libraries/LibraryFolder/TopToolbar/library-model.js
index e81e344c49c..3db3e4a2e6e 100644
--- a/client/src/components/Libraries/LibraryFolder/TopToolbar/library-model.js
+++ b/client/src/components/Libraries/LibraryFolder/TopToolbar/library-model.js
@@ -1,6 +1,5 @@
import Backbone from "backbone";
import { getAppRoot } from "onload/loadConfig";
-import { getGalaxyInstance } from "app";
// ============================================================================
// HELPER FUNCTIONS
@@ -140,7 +139,6 @@ var FolderContainer = Backbone.Model.extend({
},
parse: function (obj) {
- const Galaxy = getGalaxyInstance();
// empty the collection
this.get("folder").reset();
// response is not a simple array, it contains metadata
@@ -153,7 +151,7 @@ var FolderContainer = Backbone.Model.extend({
var file_item = new Ldda(obj.folder_contents[i]);
this.get("folder").add(file_item);
} else {
- Galaxy.emit.error("Unknown folder item type encountered while parsing response.");
+ console.error("Unknown folder item type encountered while parsing response.");
}
}
return obj;
diff --git a/client/src/components/User/DiskUsage/Management/Cleanup/CleanupOperationSummary.test.ts b/client/src/components/User/DiskUsage/Management/Cleanup/CleanupOperationSummary.test.ts
index 50f75803877..ea56e1bb073 100644
--- a/client/src/components/User/DiskUsage/Management/Cleanup/CleanupOperationSummary.test.ts
+++ b/client/src/components/User/DiskUsage/Management/Cleanup/CleanupOperationSummary.test.ts
@@ -1,6 +1,6 @@
import { mount } from "@vue/test-utils";
import flushPromises from "flush-promises";
-import { getLocalVue } from "../../../../../../tests/jest/helpers";
+import { getLocalVue } from "@tests/jest/helpers";
import CleanupOperationSummary from "./CleanupOperationSummary.vue";
import { CleanableSummary, type CleanupOperation, CleanupResult } from "./model";
diff --git a/client/src/mvc/ui/ui-select-content.js b/client/src/mvc/ui/ui-select-content.js
index 11de437c075..eebc06d92cc 100644
--- a/client/src/mvc/ui/ui-select-content.js
+++ b/client/src/mvc/ui/ui-select-content.js
@@ -222,7 +222,6 @@ const View = Backbone.View.extend({
/** Return the currently selected dataset values */
value: function (new_value) {
- const galaxy = getGalaxyInstance();
if (new_value) {
this._patchValue(new_value);
this.model.set("value", new_value);
@@ -240,7 +239,7 @@ const View = Backbone.View.extend({
const unpatchedValue = this._unpatchValue(details);
result.values.push(unpatchedValue);
} else {
- galaxy.emit.debug(
+ console.debug(
"ui-select-content::value()",
`Requested details not found for '${id_list[i]}'.`
);
@@ -252,7 +251,7 @@ const View = Backbone.View.extend({
}
}
} else {
- galaxy.emit.debug("ui-select-content::value()", `Invalid value/source '${new_value}'.`);
+ console.debug("ui-select-content::value()", `Invalid value/source '${new_value}'.`);
}
return null;
},
@@ -303,7 +302,7 @@ const View = Backbone.View.extend({
this.config = Configurations[config_id];
} else {
this.config = Configurations["data"];
- galaxy.emit.debug("ui-select-content::_changeType()", `Invalid configuration/type id '${config_id}'.`);
+ console.debug("ui-select-content::_changeType()", `Invalid configuration/type id '${config_id}'.`);
}
// prepare extension component of error message
diff --git a/client/src/mvc/visualization/chart/views/repeat.js b/client/src/mvc/visualization/chart/views/repeat.js
index 49965337d01..6d599a63dec 100644
--- a/client/src/mvc/visualization/chart/views/repeat.js
+++ b/client/src/mvc/visualization/chart/views/repeat.js
@@ -3,7 +3,6 @@ import _l from "utils/localization";
import _ from "underscore";
import $ from "jquery";
import Backbone from "backbone";
-import { getGalaxyInstance } from "app";
import Utils from "utils/utils";
import Portlet from "./portlet";
import Ui from "mvc/ui/ui-misc";
@@ -42,9 +41,8 @@ export var View = Backbone.View.extend({
/** Add new repeat block */
add: function (options) {
- const Galaxy = getGalaxyInstance();
if (!options.id || this.list[options.id]) {
- Galaxy.emit.debug("form-repeat::add()", "Duplicate or invalid repeat block id.");
+ console.debug("form-repeat::add()", "Duplicate or invalid repeat block id.");
return;
}
var button_delete = new Ui.Button({
@@ -75,9 +73,8 @@ export var View = Backbone.View.extend({
/** Delete repeat block */
del: function (id) {
- const Galaxy = getGalaxyInstance();
if (!this.list[id]) {
- Galaxy.emit.debug("form-repeat::del()", "Invalid repeat block id.");
+ console.debug("form-repeat::del()", "Invalid repeat block id.");
return;
}
this.$list.find(`#${id}`).remove();
diff --git a/client/src/mvc/visualization/visualization-model.js b/client/src/mvc/visualization/visualization-model.js
index 4de04f2b102..5f929d0cfc2 100644
--- a/client/src/mvc/visualization/visualization-model.js
+++ b/client/src/mvc/visualization/visualization-model.js
@@ -10,10 +10,6 @@ import { getAppRoot } from "onload/loadConfig";
*/
export var Visualization = Backbone.Model.extend(
/** @lends Visualization.prototype */ {
- ///** logger used to record this.log messages, commonly set to console */
- //// comment this out to suppress log output
- //logger : console,
-
/** default attributes for a model */
defaults: {
config: {},
@@ -29,8 +25,6 @@ export var Visualization = Backbone.Model.extend(
* @see Backbone.Model#initialize
*/
initialize: function (data) {
- //this.log( this + '.initialize', data, this.attributes );
-
// munge config sub-object here since bbone won't handle defaults with this
if (_.isObject(data.config) && _.isObject(this.defaults.config)) {
_.defaults(data.config, this.defaults.config);
@@ -84,10 +78,6 @@ export var VisualizationCollection = Backbone.Collection.extend(
/** @lends VisualizationCollection.prototype */ {
model: Visualization,
- ///** logger used to record this.log messages, commonly set to console */
- //// comment this out to suppress log output
- //logger : console,
-
url: function () {
return `${getAppRoot()}api/visualizations`;
},
diff --git a/client/src/onload/defaultAppFactory.js b/client/src/onload/defaultAppFactory.js
index c8f3ed3684e..c1ddc68a19a 100644
--- a/client/src/onload/defaultAppFactory.js
+++ b/client/src/onload/defaultAppFactory.js
@@ -11,7 +11,7 @@ export const defaultAppFactory = (config, label = "Galaxy") => {
return setGalaxyInstance((GalaxyApp) => {
const { options, bootstrapped } = config;
const app = new GalaxyApp(options, bootstrapped);
- app.debug(`${label} app`);
+ console.debug(`${label} app`);
return app;
});
};
diff --git a/client/src/utils/add-logging.js b/client/src/utils/add-logging.js
deleted file mode 100644
index 9b9f040930d..00000000000
--- a/client/src/utils/add-logging.js
+++ /dev/null
@@ -1,35 +0,0 @@
-//==============================================================================
-var LOGGING_FNS = ["log", "debug", "info", "warn", "error", "metric"];
-/** adds logging functions to an obj.prototype (or obj directly) adding a namespace for filtering
- * @param {Object} obj
- * @param {String} namespace
- */
-function addLogging(obj, namespace) {
- var addTo = obj.prototype !== undefined ? obj.prototype : obj;
- if (namespace !== undefined) {
- addTo._logNamespace = namespace;
- }
-
- // give the object each
- LOGGING_FNS.forEach((logFn) => {
- addTo[logFn] = function () {
- if (!this.logger) {
- return undefined;
- }
- if (this.logger.emit) {
- return this.logger.emit(logFn, this._logNamespace, arguments);
- }
- if (this.logger[logFn]) {
- //TODO:! there has to be a way to get the lineno/file into this
- // http://stackoverflow.com/questions/13815640/a-proper-wrapper-for-console-log-with-correct-line-number
- // http://www.paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
- return this.logger[logFn].apply(this.logger, arguments);
- }
- return undefined;
- };
- });
- return obj;
-}
-
-//==============================================================================
-export default addLogging;
diff --git a/client/src/utils/deferred.js b/client/src/utils/deferred.js
index 7dfe38996a1..ae13f556888 100644
--- a/client/src/utils/deferred.js
+++ b/client/src/utils/deferred.js
@@ -4,7 +4,6 @@
import $ from "jquery";
import Backbone from "backbone";
import Utils from "utils/utils";
-import { getGalaxyInstance } from "app";
export default Backbone.Model.extend({
initialize: function () {
@@ -19,7 +18,6 @@ export default Backbone.Model.extend({
var self = this;
var id = Utils.uid();
var has_deferred = callback.length > 0;
- const Galaxy = getGalaxyInstance();
// register process
this.active[id] = true;
@@ -29,7 +27,7 @@ export default Backbone.Model.extend({
process.promise().always(function () {
delete self.active[id];
has_deferred &&
- Galaxy.emit.debug(
+ console.debug(
"deferred::execute()",
`${this.state().charAt(0).toUpperCase() + this.state().slice(1)} ${id}`
);
@@ -38,7 +36,7 @@ export default Backbone.Model.extend({
// deferred queue
$.when(this.last).always(() => {
if (self.active[id]) {
- has_deferred && Galaxy.emit.debug("deferred::execute()", `Running ${id}`);
+ has_deferred && console.debug("deferred::execute()", `Running ${id}`);
callback(process);
!has_deferred && process.resolve();
} else {
@@ -51,8 +49,7 @@ export default Backbone.Model.extend({
/** Resets the promise queue. All currently queued but unexecuted callbacks/promises will be rejected.
*/
reset: function () {
- const Galaxy = getGalaxyInstance();
- Galaxy.emit.debug("deferred::execute()", "Reset");
+ console.debug("deferred::execute()", "Reset");
for (var i in this.active) {
this.active[i] = false;
}
diff --git a/client/src/utils/graph.js b/client/src/utils/graph.js
deleted file mode 100644
index 0f5a5675268..00000000000
--- a/client/src/utils/graph.js
+++ /dev/null
@@ -1,623 +0,0 @@
-/** deep equal of two dictionaries */
-function matches(d, d2) {
- for (var k in d2) {
- if (Object.prototype.hasOwnProperty.call(d2, k)) {
- if (!Object.prototype.hasOwnProperty.call(d, k) || d[k] !== d2[k]) {
- return false;
- }
- }
- }
- return true;
-}
-
-/** map key/values in obj
- * if propsOrFn is an object, return only those k/v that match the object
- * if propsOrFn is function, call the fn and returned the mapped values from it
- */
-function iterate(obj, propsOrFn) {
- var fn = typeof propsOrFn === "function" ? propsOrFn : undefined;
- var props = typeof propsOrFn === "object" ? propsOrFn : undefined;
- var returned = [];
- var index = 0;
- for (var key in obj) {
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
- var value = obj[key];
- if (fn) {
- returned.push(fn.call(value, value, key, index));
- } else if (props) {
- //TODO: break out to sep?
- if (typeof value === "object" && matches(value, props)) {
- returned.push(value);
- }
- } else {
- returned.push(value);
- }
- index += 1;
- }
- }
- return returned;
-}
-
-// ============================================================================
-/** A graph edge containing the name/id of both source and target and optional data
- */
-function Edge(source, target, data) {
- var self = this;
- self.source = source !== undefined ? source : null;
- self.target = target !== undefined ? target : null;
- self.data = data || null;
- //if( typeof data === 'object' ){
- // extend( self, data );
- //}
- return self;
-}
-/** String representation */
-Edge.prototype.toString = function () {
- return `${this.source}->${this.target}`;
-};
-
-/** Return a plain object representing this edge */
-Edge.prototype.toJSON = function () {
- //TODO: this is safe in most browsers (fns will be stripped) - alter tests to incorporate this in order to pass data
- //return this;
- var json = {
- source: this.source,
- target: this.target,
- };
- if (this.data) {
- json.data = this.data;
- }
- return json;
-};
-
-// ============================================================================
-/** A graph vertex with a (unique) name/id and optional data.
- * A vertex contains a list of Edges (whose sources are this vertex) and maintains the degree.
- */
-function Vertex(name, data) {
- var self = this;
- self.name = name !== undefined ? name : "(unnamed)";
- self.data = data || null;
- self.edges = {};
- self.degree = 0;
- return self;
-}
-
-/** String representation */
-Vertex.prototype.toString = function () {
- return `Vertex(${this.name})`;
-};
-
-//TODO: better name w no collision for either this.eachEdge or this.edges
-/** Iterate over each edge from this vertex */
-Vertex.prototype.eachEdge = function (propsOrFn) {
- return iterate(this.edges, propsOrFn);
-};
-
-/** Return a plain object representing this vertex */
-Vertex.prototype.toJSON = function () {
- //return this;
- return {
- name: this.name,
- data: this.data,
- };
-};
-
-// ============================================================================
-/** Base (abstract) class for Graph search algorithms.
- * Pass in the graph to search
- * and an optional dictionary containing the 3 vertex/edge processing fns listed below.
- */
-var GraphSearch = function (graph, processFns) {
- var self = this;
- self.graph = graph;
-
- self.processFns = processFns || {
- vertexEarly: function (vertex, search) {
- //console.debug( 'processing vertex:', vertex.name, vertex );
- },
- edge: function (from, edge, search) {
- //console.debug( this, 'edge:', from, edge, search );
- },
- vertexLate: function (vertex, search) {
- //console.debug( this, 'vertexLate:', vertex, search );
- },
- };
-
- self._cache = {};
- return self;
-};
-
-/** Search interface where start is the vertex (or the name/id of the vertex) to begin the search at
- * This public interface caches searches and returns the cached version if it's already been done.
- */
-GraphSearch.prototype.search = function _search(start) {
- var self = this;
- if (start in self._cache) {
- return self._cache[start];
- }
- if (!(start instanceof Vertex)) {
- start = self.graph.vertices[start];
- }
- return (self._cache[start.name] = self._search(start));
-};
-
-/** Actual search (private) function (abstract here) */
-GraphSearch.prototype._search = function __search(start, search) {
- search = search || {
- discovered: {},
- //parents : {},
- edges: [],
- };
- return search;
-};
-
-/** Searches graph from start and returns a search tree of the results */
-GraphSearch.prototype.searchTree = function _searchTree(start) {
- return this._searchTree(this.search(start));
-};
-
-/** Helper fn that returns a graph (a search tree) based on the search object passed in (does not actually search) */
-GraphSearch.prototype._searchTree = function __searchTree(search) {
- var self = this;
- return new Graph(true, {
- edges: search.edges,
- vertices: Object.keys(search.discovered).map((key) => self.graph.vertices[key].toJSON()),
- });
-};
-
-// ============================================================================
-/** Breadth first search algo.
- */
-var BreadthFirstSearch = function (graph, processFns) {
- var self = this;
- GraphSearch.call(this, graph, processFns);
- return self;
-};
-BreadthFirstSearch.prototype = new GraphSearch();
-BreadthFirstSearch.prototype.constructor = BreadthFirstSearch;
-
-/** (Private) implementation of BFS */
-BreadthFirstSearch.prototype._search = function __search(start, search) {
- search = search || {
- discovered: {},
- //parents : {},
- edges: [],
- };
-
- var self = this;
- var queue = [];
-
- function discoverAdjacent(adj, edge) {
- var source = this;
- if (self.processFns.edge) {
- self.processFns.edge.call(self, source, edge, search);
- }
- if (!search.discovered[adj.name]) {
- //console.debug( '\t\t\t', adj.name, 'is undiscovered:', search.discovered[ adj.name ] );
- search.discovered[adj.name] = true;
- //search.parents[ adj.name ] = source;
- search.edges.push({ source: source.name, target: adj.name });
- //console.debug( '\t\t\t queuing undiscovered: ', adj );
- queue.push(adj);
- }
- }
-
- //console.debug( 'BFS starting. start:', start );
- search.discovered[start.name] = true;
- queue.push(start);
- while (queue.length) {
- var vertex = queue.shift();
- //console.debug( '\t Queue is shifting. Current:', vertex, 'queue:', queue );
- if (self.processFns.vertexEarly) {
- self.processFns.vertexEarly.call(self, vertex, search);
- }
- self.graph.eachAdjacent(vertex, discoverAdjacent);
- if (self.processFns.vertexLate) {
- self.processFns.vertexLate.call(self, vertex, search);
- }
- }
- //console.debug( 'search.edges:', JSON.stringify( search.edges ) );
- return search;
-};
-
-// ============================================================================
-/** Depth first search algorithm.
- */
-var DepthFirstSearch = function (graph, processFns) {
- var self = this;
- GraphSearch.call(this, graph, processFns);
- return self;
-};
-DepthFirstSearch.prototype = new GraphSearch();
-DepthFirstSearch.prototype.constructor = DepthFirstSearch;
-
-/** (Private) implementation of DFS */
-DepthFirstSearch.prototype._search = function (start, search) {
- //console.debug( 'depthFirstSearch:', start );
- search = search || {
- discovered: {},
- //parents : {},
- edges: [],
- entryTimes: {},
- exitTimes: {},
- };
- var self = this;
- var time = 0;
-
- // discover verts adjacent to the source (this):
- // processing each edge, saving the edge to the tree, and caching the reverse path with parents
- function discoverAdjacentVertices(adjacent, edge) {
- //console.debug( '\t\t adjacent:', adjacent, 'edge:', edge );
- var sourceVertex = this;
- if (self.processFns.edge) {
- self.processFns.edge.call(self, sourceVertex, edge, search);
- }
- if (!search.discovered[adjacent.name]) {
- //search.parents[ adjacent.name ] = sourceVertex;
- search.edges.push({
- source: sourceVertex.name,
- target: adjacent.name,
- });
- recurse(adjacent);
- }
- }
-
- // use function stack for DFS stack process verts, times, and discover adjacent verts (recursing into them)
- function recurse(vertex) {
- //console.debug( '\t recursing into: ', vertex );
- search.discovered[vertex.name] = true;
- if (self.processFns.vertexEarly) {
- self.processFns.vertexEarly.call(self, vertex, search);
- }
- search.entryTimes[vertex.name] = time++;
-
- self.graph.eachAdjacent(vertex, discoverAdjacentVertices);
-
- if (self.processFns.vertexLate) {
- self.processFns.vertexLate.call(self, vertex, search);
- }
- search.exitTimes[vertex.name] = time++;
- }
- // begin recursion with the desired start
- recurse(start);
-
- return search;
-};
-
-// ============================================================================
-/** A directed/non-directed graph object.
- */
-function Graph(directed, data, options) {
- //TODO: move directed to options
- this.directed = directed || false;
- return this.init(options).read(data);
-}
-window.Graph = Graph;
-
-/** Set up options and instance variables */
-Graph.prototype.init = function (options) {
- options = options || {};
- var self = this;
-
- self.allowReflexiveEdges = options.allowReflexiveEdges || false;
-
- self.vertices = {};
- self.numEdges = 0;
- return self;
-};
-
-/** Read data from the plain object data - both in d3 form (nodes and links) or vertices and edges */
-Graph.prototype.read = function (data) {
- if (!data) {
- return this;
- }
- var self = this;
- if (Object.prototype.hasOwnProperty.call(data, "nodes")) {
- return self.readNodesAndLinks(data);
- }
- if (Object.prototype.hasOwnProperty.call(data, "vertices")) {
- return self.readVerticesAndEdges(data);
- }
- return self;
-};
-
-//TODO: the next two could be combined
-/** Create the graph using a list of nodes and a list of edges (where source and target are indeces into nodes) */
-Graph.prototype.readNodesAndLinks = function (data) {
- if (!(data && Object.prototype.hasOwnProperty.call(data, "nodes"))) {
- return this;
- }
- //console.debug( 'readNodesAndLinks:', data );
- //console.debug( 'data:\n' + JSON.stringify( data, null, ' ' ) );
- var self = this;
- data.nodes.forEach((node) => {
- self.createVertex(node.name, node.data);
- });
- //console.debug( JSON.stringify( self.vertices, null, ' ' ) );
-
- (data.links || []).forEach((edge, i) => {
- var sourceName = data.nodes[edge.source].name;
- var targetName = data.nodes[edge.target].name;
- self.createEdge(sourceName, targetName, self.directed);
- });
- //self.print();
- //console.debug( JSON.stringify( self.toNodesAndLinks(), null, ' ' ) );
- return self;
-};
-
-/** Create the graph using a list of nodes and a list of edges (where source and target are names of nodes) */
-Graph.prototype.readVerticesAndEdges = function (data) {
- if (!(data && Object.prototype.hasOwnProperty.call(data, "vertices"))) {
- return this;
- }
- //console.debug( 'readVerticesAndEdges:', data );
- //console.debug( 'data:\n' + JSON.stringify( data, null, ' ' ) );
- var self = this;
- data.vertices.forEach((node) => {
- self.createVertex(node.name, node.data);
- });
- //console.debug( JSON.stringify( self.vertices, null, ' ' ) );
-
- (data.edges || []).forEach((edge, i) => {
- self.createEdge(edge.source, edge.target, self.directed);
- });
- //self.print();
- //console.debug( JSON.stringify( self.toNodesAndLinks(), null, ' ' ) );
- return self;
-};
-
-/** Return the vertex with name, creating it if necessary */
-Graph.prototype.createVertex = function (name, data) {
- //console.debug( 'createVertex:', name, data );
- if (this.vertices[name]) {
- return this.vertices[name];
- }
- return (this.vertices[name] = new Vertex(name, data));
-};
-
-/** Create an edge in vertex named sourceName to targetName (optionally adding data to it)
- * If directed is false, create a second edge from targetName to sourceName.
- */
-Graph.prototype.createEdge = function (sourceName, targetName, directed, data) {
- //note: allows multiple 'equivalent' edges (to/from same source/target)
- //console.debug( 'createEdge:', source, target, directed );
- var isReflexive = sourceName === targetName;
- if (!this.allowReflexiveEdges && isReflexive) {
- return null;
- }
-
- var sourceVertex = this.vertices[sourceName];
- var targetVertex = this.vertices[targetName];
- //note: silently ignores edges from/to unknown vertices
- if (!(sourceVertex && targetVertex)) {
- return null;
- }
-
- //TODO: prob. move to vertex
- var self = this;
-
- var edge = new Edge(sourceName, targetName, data);
- sourceVertex.edges[targetName] = edge;
- sourceVertex.degree += 1;
- self.numEdges += 1;
-
- //TODO:! don't like having duplicate edges for non-directed graphs
- // mirror edges (reversing source and target) in non-directed graphs
- // but only if not reflexive
- if (!isReflexive && !directed) {
- // flip directed to prevent recursion loop
- self.createEdge(targetName, sourceName, true);
- }
-
- return edge;
-};
-
-/** Walk over all the edges of the graph using the vertex.eachEdge iterator */
-Graph.prototype.edges = function (propsOrFn) {
- return Array.prototype.concat.apply(
- [],
- this.eachVertex((vertex) => vertex.eachEdge(propsOrFn))
- );
-};
-
-/** Iterate over all the vertices in the graph */
-Graph.prototype.eachVertex = function (propsOrFn) {
- return iterate(this.vertices, propsOrFn);
-};
-
-/** Return a list of the vertices adjacent to vertex */
-Graph.prototype.adjacent = function (vertex) {
- var self = this;
- return iterate(vertex.edges, (edge) => self.vertices[edge.target]);
-};
-
-/** Call fn on each vertex adjacent to vertex */
-Graph.prototype.eachAdjacent = function (vertex, fn) {
- var self = this;
- return iterate(vertex.edges, (edge) => {
- var adj = self.vertices[edge.target];
- return fn.call(vertex, adj, edge);
- });
-};
-
-/** Print the graph to the console (debugging) */
-Graph.prototype.print = function () {
- var self = this;
- console.log(`Graph has ${Object.keys(self.vertices).length} vertices`);
- self.eachVertex((vertex) => {
- console.log(vertex.toString());
- vertex.eachEdge((edge) => {
- console.log(`\t ${edge}`);
- });
- });
- return self;
-};
-
-/** Return a DOT format string of this graph */
-Graph.prototype.toDOT = function () {
- var self = this;
- var strings = [];
- strings.push("graph bler {");
- self.edges((edge) => {
- strings.push(`\t${edge.from} -- ${edge.to};`);
- });
- strings.push("}");
- return strings.join("\n");
-};
-
-/** Return vertices and edges of this graph in d3 node/link format */
-Graph.prototype.toNodesAndLinks = function () {
- var self = this;
- var indeces = {};
- return {
- nodes: self.eachVertex((vertex, key, i) => {
- indeces[vertex.name] = i;
- return vertex.toJSON();
- }),
- links: self.edges((edge) => {
- var json = edge.toJSON();
- json.source = indeces[edge.source];
- json.target = indeces[edge.target];
- return json;
- }),
- };
-};
-
-/** Return vertices and edges of this graph where edges use the name/id as source and target */
-Graph.prototype.toVerticesAndEdges = function () {
- var self = this;
- return {
- vertices: self.eachVertex((vertex, key) => vertex.toJSON()),
- edges: self.edges((edge) => edge.toJSON()),
- };
-};
-
-/** Search this graph using BFS */
-Graph.prototype.breadthFirstSearch = function (start, processFns) {
- return new BreadthFirstSearch(this).search(start);
-};
-
-/** Return a searchtree of this graph using BFS */
-Graph.prototype.breadthFirstSearchTree = function (start, processFns) {
- return new BreadthFirstSearch(this).searchTree(start);
-};
-
-/** Search this graph using DFS */
-Graph.prototype.depthFirstSearch = function (start, processFns) {
- return new DepthFirstSearch(this).search(start);
-};
-
-/** Return a searchtree of this graph using DFS */
-Graph.prototype.depthFirstSearchTree = function (start, processFns) {
- return new DepthFirstSearch(this).searchTree(start);
-};
-
-//Graph.prototype.shortestPath = function( start, end ){
-//};
-//
-//Graph.prototype.articulationVertices = function(){
-//};
-//
-//Graph.prototype.isAcyclic = function(){
-//};
-//
-//Graph.prototype.isBipartite = function(){
-//};
-
-/** Return an array of weakly connected (no edges between) sub-graphs in this graph */
-Graph.prototype.weakComponents = function () {
- //TODO: alternately, instead of returning graph-like objects:
- // - could simply decorate the vertices (vertex.component = componentIndex), or clone the graph and do that
- var self = this;
-
- var searchGraph = this;
- var undiscovered;
- var components = [];
-
- function getComponent(undiscoveredVertex) {
- //TODO: better interface on dfs (search v. searchTree)
- var search = new DepthFirstSearch(searchGraph)._search(undiscoveredVertex);
-
- // remove curr discovered from undiscovered
- undiscovered = undiscovered.filter((name) => !(name in search.discovered));
-
- return {
- vertices: Object.keys(search.discovered).map((vertexName) => self.vertices[vertexName].toJSON()),
- edges: search.edges.map((edge) => {
- // restore any reversed edges
- var hasBeenReversed = self.vertices[edge.target].edges[edge.source] !== undefined;
- if (self.directed && hasBeenReversed) {
- var swap = edge.source;
- edge.source = edge.target;
- edge.target = swap;
- }
- return edge;
- }),
- };
- }
-
- if (self.directed) {
- // if directed - convert to undirected for search
- searchGraph = new Graph(false, self.toNodesAndLinks());
- }
- undiscovered = Object.keys(searchGraph.vertices);
- //console.debug( '(initial) undiscovered:', undiscovered );
- while (undiscovered.length) {
- var undiscoveredVertex = searchGraph.vertices[undiscovered.shift()];
- components.push(getComponent(undiscoveredVertex));
- //console.debug( 'undiscovered now:', undiscovered );
- }
-
- //console.debug( 'components:\n', JSON.stringify( components, null, ' ' ) );
- return components;
-};
-
-/** Return a single graph containing the weakly connected components in this graph */
-Graph.prototype.weakComponentGraph = function () {
- //note: although this can often look like the original graph - edges can be lost
- var components = this.weakComponents();
- return new Graph(this.directed, {
- vertices: components.reduce((reduction, curr) => reduction.concat(curr.vertices), []),
- edges: components.reduce((reduction, curr) => reduction.concat(curr.edges), []),
- });
-};
-
-/** Return an array of graphs of the weakly connected components in this graph */
-Graph.prototype.weakComponentGraphArray = function () {
- //note: although this can often look like the original graph - edges can be lost
- var graph = this;
- return this.weakComponents().map((component) => new Graph(graph.directed, component));
-};
-
-// ============================================================================
-/** Create a random graph with numVerts vertices and numEdges edges (for testing)
- */
-function randGraph(directed, numVerts, numEdges) {
- //console.debug( 'randGraph', directed, numVerts, numEdges );
- var data = { nodes: [], links: [] };
- function randRange(range) {
- return Math.floor(Math.random() * range);
- }
- for (var i = 0; i < numVerts; i++) {
- data.nodes.push({ name: i });
- }
- for (i = 0; i < numEdges; i++) {
- data.links.push({
- source: randRange(numVerts),
- target: randRange(numVerts),
- });
- }
- //console.debug( JSON.stringify( data, null, ' ' ) );
- return new Graph(directed, data);
-}
-
-// ============================================================================
-export default {
- Vertex: Vertex,
- Edge: Edge,
- BreadthFirstSearch: BreadthFirstSearch,
- DepthFirstSearch: DepthFirstSearch,
- Graph: Graph,
- randGraph: randGraph,
-};
diff --git a/client/src/utils/metrics-logger.js b/client/src/utils/metrics-logger.js
deleted file mode 100644
index ab9f5ea2338..00000000000
--- a/client/src/utils/metrics-logger.js
+++ /dev/null
@@ -1,504 +0,0 @@
-/*=============================================================================
-TODO:
- while anon: logs saved to 'logs-null' - this will never post
- unless we manually do so at/after login
- OR prepend when userId and localStorage has 'logs-null'
- wire up _delayPost and test
-
-=============================================================================*/
-/** @class MetricsLogger
- *
- * Object to cache, output, and post log/metric messages to the server.
- * Meant to be attached to the Galaxy object.
- *
- * Log from objects by either attaching logger directly:
- * panel.logger.metric( 'user dataset deletion', panel.user.id, hda.toJSON() )
- * or using the LoggableMixin or addLogging function:
- * MyBackboneModel.extend( LoggableMixin ).extend({ ... })
- * addLogging( MyBackboneModel, 'my-backbone-model' )
- *
- * Log from templates by calling directly from Galaxy object:
- * Galaxy.logger.metric( 'template loaded', { ownedByUser : true });
- *
- * If you attempt to log an un-serializable object (circular reference, window, etc.),
- * that entry will not be cached (or sent). If you set consoleLevel and consoleLogger
- * appropriately, a warning will be shown when this happens:
- * > panel.metric( 'something weird with window', { window : window })
- * !'Metrics logger could not stringify logArguments: ...'
- */
-import jQuery from "jquery";
-
-function MetricsLogger(options) {
- options = options || {};
- var self = this;
-
- ///** get the current user's id from bootstrapped data or options */
- self.userId = window.bootstrapped && window.bootstrapped.user ? window.bootstrapped.user.id : null;
- self.userId = self.userId || options.userId || null;
-
- /** the (optional) console to emit logs to */
- self.consoleLogger = options.consoleLogger || null;
-
- self._init(options);
- return self;
-}
-
-//----------------------------------------------------------------------------- defaults and constants
-// see: python std lib, logging
-MetricsLogger.ALL = 0;
-MetricsLogger.LOG = 0;
-MetricsLogger.DEBUG = 10;
-MetricsLogger.INFO = 20;
-MetricsLogger.WARN = 30;
-MetricsLogger.ERROR = 40;
-// metrics levels here?
-//MetricsLogger.MinorEvent = 45;
-//MetricsLogger.MajorEvent = 50;
-MetricsLogger.METRIC = 50;
-MetricsLogger.NONE = 100;
-
-/** default options - override these through the constructor */
-MetricsLogger.defaultOptions = {
- /** if an incoming message has a level >= this, it will be cached - can also be a string (e.g. 'debug') */
- logLevel: MetricsLogger.NONE,
- /** if an incoming message has a level >= this, it will be output to the console */
- consoleLevel: MetricsLogger.NONE,
- /** the default 'namespace' or label associated with an incoming message (if none is passed) */
- defaultNamespace: "Galaxy",
- /** the namespaces output to the console (all namespaces will be output if this is falsy)
- * note: applies only to the console (not the event/metrics log/cache)
- */
- consoleNamespaceWhitelist: null,
- /** Force all messages into simple strings. */
- consoleFlattenMessages: false,
- /** the prefix attached to client-side logs to distinguish them in the metrics db */
- clientPrefix: "client.",
-
- /** the maximum number of messages the cache should hold; if exceeded older messages are removed first */
- maxCacheSize: 3000,
- /** the number of messages accumulate before posting to the server; should be <= maxCacheSize */
- postSize: 1000,
- /** T/F whether to add a timestamp to incoming cached messages */
- addTime: true,
- /** string to prefix to userid for cache web storage */
- cacheKeyPrefix: "logs-",
-
- /** the relative url to post messages to */
- postUrl: "/api/metrics",
- /** delay before trying post again after two failures */
- delayPostInMs: 1000 * 60 * 10,
-
- /** an (optional) function that should return an object; used to send additional data with the metrics */
- getPingData: undefined,
- /** an (optional) function that will handle the servers response after successfully posting messages */
- onServerResponse: undefined,
-};
-
-//----------------------------------------------------------------------------- set up
-/** initialize the logger with options, set up instance vars and cache, and add onpageunload to window */
-MetricsLogger.prototype._init = function _init(options) {
- var self = this;
- self.options = {};
- for (var k in MetricsLogger.defaultOptions) {
- if (Object.prototype.hasOwnProperty.call(MetricsLogger.defaultOptions, k)) {
- self.options[k] = Object.prototype.hasOwnProperty.call(options, k)
- ? options[k]
- : MetricsLogger.defaultOptions[k];
- }
- }
- self.options.logLevel = self._parseLevel(self.options.logLevel);
- self.options.consoleLevel = self._parseLevel(self.options.consoleLevel);
- //self._emitToConsole( 'debug', 'MetricsLogger', 'MetricsLogger.options:', self.options );
-
- /** is the logger currently sending? */
- self._sending = false;
- /** the setTimeout id if the logger POST has failed more than once */
- self._waiting = null;
- /** the current number of entries to send in a POST */
- self._postSize = self.options.postSize;
-
- self._initCache();
-
- return self;
-};
-
-/** initialize the cache */
-MetricsLogger.prototype._initCache = function _initCache() {
- try {
- this.cache = new LoggingCache({
- maxSize: this.options.maxCacheSize,
- key: this.options.cacheKeyPrefix + this.userId,
- });
- } catch (err) {
- this._emitToConsole("warn", "MetricsLogger", ["Could not intitialize logging cache:", err]);
- this.options.logLevel = MetricsLogger.NONE;
- }
-};
-
-/** return the numeric log level if level in 'none, debug, log, info, warn, error' */
-MetricsLogger.prototype._parseLevel = function _parseLevel(level) {
- var type = typeof level;
- if (type === "number") {
- return level;
- }
- if (type === "string") {
- var upper = level.toUpperCase();
- if (Object.prototype.hasOwnProperty.call(MetricsLogger, upper)) {
- return MetricsLogger[upper];
- }
- }
- throw new Error(`Unknown log level: ${level}`);
-};
-
-//----------------------------------------------------------------------------- main entry point
-/** record a log/message's arguments to the cache and/or the console based on level and namespace */
-MetricsLogger.prototype.emit = function emit(level, namespace, logArguments) {
- //this._emitToConsole( 'debug', 'MetricsLogger', [ 'emit:', level, namespace, logArguments ]);
- var self = this;
- namespace = namespace || self.options.defaultNamespace;
- if (!level || !logArguments) {
- return self;
- }
- // add to cache if proper level
- //TODO: respect do not track?
- //if( !navigator.doNotTrack && level >= self.options.logLevel ){
- level = self._parseLevel(level);
- if (level >= self.options.logLevel) {
- self._addToCache(level, namespace, logArguments);
- }
- // also emit to consoleLogger if proper level for that
- if (self.consoleLogger && level >= self.options.consoleLevel) {
- self._emitToConsole(level, namespace, logArguments);
- }
- return self;
-};
-
-//----------------------------------------------------------------------------- cache
-/** add a message to the cache and if messages.length is high enough post them to the server */
-MetricsLogger.prototype._addToCache = function _addToCache(level, namespace, logArguments) {
- this._emitToConsole("debug", "MetricsLogger", [
- "_addToCache:",
- arguments,
- this.options.addTime,
- this.cache.length(),
- ]);
- //this._emitToConsole( 'debug', 'MetricsLogger', [ '\t logArguments:', logArguments ]);
- var self = this;
- // try add to the cache and if we've got _postSize number of entries, attempt to post them to the server
- try {
- var newLength = self.cache.add(self._buildEntry(level, namespace, logArguments));
- if (newLength >= self._postSize) {
- self._postCache();
- }
- // discard entry if an error occurs, but warn if level set to do so
- } catch (err) {
- self._emitToConsole("warn", "MetricsLogger", [
- "Metrics logger could not stringify logArguments:",
- namespace,
- logArguments,
- ]);
- self._emitToConsole("error", "MetricsLogger", [err]);
- }
- return self;
-};
-
-/** build a log cache entry object from the given level, namespace, and arguments (optionally adding timestamp */
-MetricsLogger.prototype._buildEntry = function _buildEntry(level, namespace, logArguments) {
- this._emitToConsole("debug", "MetricsLogger", ["_buildEntry:", arguments]);
- var entry = {
- level: level,
- namespace: this.options.clientPrefix + namespace,
- args: logArguments,
- };
- if (this.options.addTime) {
- entry.time = new Date().toISOString();
- }
- return entry;
-};
-
-/** post _postSize messages from the cache to the server, removing them if successful
- * if the post fails, wait until maxCacheSize is accumulated instead and try again then
- * in addition to the messages from the cache ('metrics'), any info from getPingData (if set) will be sent
- * onServerResponse will be called (if set) with any response from the server
- */
-MetricsLogger.prototype._postCache = function _postCache(options) {
- options = options || {};
- this._emitToConsole("info", "MetricsLogger", ["_postCache", options, this._postSize]);
-
- // short circuit if we're already sending
- if (!this.options.postUrl || this._sending) {
- return jQuery.when({});
- }
-
- var self = this;
- var postSize = options.count || self._postSize;
-
- var // do not splice - remove after *successful* post
- entries = self.cache.get(postSize);
-
- var entriesLength = entries.length;
-
- var // use the optional getPingData to add any extra info we may want to send
- postData = typeof self.options.getPingData === "function" ? self.options.getPingData() : {};
-
- //console.debug( postSize, entriesLength );
-
- // add the metrics and send
- postData.metrics = JSON.stringify(entries);
- //console.debug( postData.metrics );
- self._sending = true;
- return jQuery
- .post(self.options.postUrl, postData)
- .always(() => {
- self._sending = false;
- })
- .fail((xhr, status, message) => {
- // if we failed the previous time, set the next post target to the max num of entries
- self._postSize = self.options.maxCacheSize;
- //TODO:??
- // log this failure to explain any gap in metrics
- self.emit("error", "MetricsLogger", [
- "_postCache error:",
- xhr.readyState,
- xhr.status,
- xhr.responseJSON || xhr.responseText,
- ]);
- //TODO: still doesn't solve the problem that when cache == max, post will be tried on every emit
- //TODO: see _delayPost
- })
- .done((response) => {
- if (typeof self.options.onServerResponse === "function") {
- self.options.onServerResponse(response);
- }
- // only remove if post successful
- self.cache.remove(entriesLength);
- //console.debug( 'removed entries:', entriesLength, 'size now:', self.cache.length() );
- // if we succeeded, reset the post target to the normal num of entries
- self._postSize = self.options.postSize;
- });
- // return the xhr promise
-};
-
-/** set _waiting to true and, after delayPostInMs, set it back to false */
-MetricsLogger.prototype._delayPost = function _delayPost() {
- //TODO: this won't work between pages
- var self = this;
- self._waiting = window.setTimeout(() => {
- self._waiting = null;
- }, self.options.delayPostInMs);
-};
-
-function usefulToString(arg) {
- var asStr = String(arg);
- if (asStr == "[object Object]") {
- try {
- asStr = JSON.stringify(arg);
- } catch (e) {
- // If arg has cyclic reference, return String
- // otherwise rendering stops and we have incomplete page
- console.error(e);
- return String(arg);
- }
- }
- return asStr;
-}
-
-//----------------------------------------------------------------------------- console
-/** output message to console based on level and consoleLogger type */
-MetricsLogger.prototype._emitToConsole = function _emitToConsole(level, namespace, logArguments) {
- //console.debug( '_emitToConsole:', level, namespace, logArguments );
- var self = this;
-
- var whitelist = self.options.consoleNamespaceWhitelist;
- if (!self.consoleLogger) {
- return self;
- }
- // if a whitelist for namespaces is set, bail if this namespace is not in the list
- if (whitelist && whitelist.indexOf(namespace) === -1) {
- return self;
- }
-
- var args = Array.prototype.slice.call(logArguments, 0);
- args.unshift(namespace);
- if (self.options.consoleFlattenMessages) {
- args = [args.map(usefulToString).join(" ")];
- }
- //TODO: script location and/or source maps?
- //TODO: branch on navigator.userAgent == AIIEEE - it only has log
- if (level >= MetricsLogger.METRIC && typeof self.consoleLogger.info === "function") {
- return self.consoleLogger.info.apply(self.consoleLogger, args);
- } else if (level >= MetricsLogger.ERROR && typeof self.consoleLogger.error === "function") {
- return self.consoleLogger.error.apply(self.consoleLogger, args);
- } else if (level >= MetricsLogger.WARN && typeof self.consoleLogger.warn === "function") {
- self.consoleLogger.warn.apply(self.consoleLogger, args);
- } else if (level >= MetricsLogger.INFO && typeof self.consoleLogger.info === "function") {
- self.consoleLogger.info.apply(self.consoleLogger, args);
- } else if (level >= MetricsLogger.DEBUG && typeof self.consoleLogger.debug === "function") {
- self.consoleLogger.debug.apply(self.consoleLogger, args);
- } else if (typeof self.consoleLogger.log === "function") {
- self.consoleLogger.log.apply(self.consoleLogger, args);
- }
- return self;
-};
-
-//----------------------------------------------------------------------------- shortcuts
-// generic functions when logging from non-namespaced object (e.g. templates)
-/** log to default namespace */
-MetricsLogger.prototype.log = function log() {
- this.emit(1, this.options.defaultNamespace, Array.prototype.slice.call(arguments, 0));
-};
-
-/** debug to default namespace */
-MetricsLogger.prototype.debug = function debug() {
- this.emit(MetricsLogger.DEBUG, this.options.defaultNamespace, Array.prototype.slice.call(arguments, 0));
-};
-
-/** info to default namespace */
-MetricsLogger.prototype.info = function info() {
- this.emit(MetricsLogger.INFO, this.options.defaultNamespace, Array.prototype.slice.call(arguments, 0));
-};
-
-/** warn to default namespace */
-MetricsLogger.prototype.warn = function warn() {
- this.emit(MetricsLogger.WARN, this.options.defaultNamespace, Array.prototype.slice.call(arguments, 0));
-};
-
-/** error to default namespace */
-MetricsLogger.prototype.error = function error() {
- this.emit(MetricsLogger.ERROR, this.options.defaultNamespace, Array.prototype.slice.call(arguments, 0));
-};
-
-/** metric to default namespace */
-MetricsLogger.prototype.metric = function metric() {
- this.emit(MetricsLogger.METRIC, this.options.defaultNamespace, Array.prototype.slice.call(arguments, 0));
-};
-
-/* ============================================================================
-TODO:
- need a performance pass - the JSON un/parsing is a bit much
-
-============================================================================ */
-/** @class LoggingCache
- * Simple implementation of cache wrapping an array.
- *
- * Formats an entry before it's cached and only keeps options.maxSize number
- * of entries. Older entries are deleted first.
- */
-function LoggingCache(options) {
- var self = this;
- return self._init(options || {});
-}
-
-/** default options */
-LoggingCache.defaultOptions = {
- /** maximum number of entries to keep before discarding oldest */
- maxSize: 5000,
-};
-
-/** initialize with options */
-LoggingCache.prototype._init = function _init(options) {
- if (!this._hasStorage()) {
- //TODO: fall back to local storage
- throw new Error("LoggingCache needs localStorage");
- }
- if (!options.key) {
- throw new Error("LoggingCache needs key for localStorage");
- }
- this.key = options.key;
- this._initStorage();
-
- this.maxSize = options.maxSize || LoggingCache.defaultOptions.maxSize;
- return this;
-};
-
-/** tests for localStorage fns */
-LoggingCache.prototype._hasStorage = function _hasStorage() {
- //TODO: modernizr
- var test = "test";
- try {
- localStorage.setItem(test, test);
- localStorage.removeItem(test);
- return true;
- } catch (e) {
- return false;
- }
-};
-
-/** if no localStorage set for key, initialize to empty array */
-LoggingCache.prototype._initStorage = function _initStorage() {
- if (localStorage.getItem(this.key) === null) {
- return this.empty();
- }
- return this;
-};
-
-/** add an entry to the cache, removing the oldest beforehand if size >= maxSize */
-LoggingCache.prototype.add = function add(entry) {
- var self = this;
- var _cache = self._fetchAndParse();
- var overage = _cache.length + 1 - self.maxSize;
- if (overage > 0) {
- _cache.splice(0, overage);
- }
- _cache.push(entry);
- self._unparseAndStore(_cache);
- return _cache.length;
-};
-
-/** get the entries from localStorage and parse them */
-LoggingCache.prototype._fetchAndParse = function _fetchAndParse() {
- var self = this;
- return JSON.parse(localStorage.getItem(self.key));
-};
-
-/** stringify the entries and put them in localStorage */
-LoggingCache.prototype._unparseAndStore = function _unparseAndStore(entries) {
- var self = this;
- return localStorage.setItem(self.key, JSON.stringify(entries));
-};
-
-///** process the entry before caching */
-//LoggingCache.prototype._preprocessEntry = function _preprocessEntry( entry ){
-// return JSON.stringify( entry );
-//};
-
-/** return the length --- oh, getters where are you? */
-LoggingCache.prototype.length = function length() {
- return this._fetchAndParse().length;
-};
-
-/** get count number of entries starting with the oldest */
-LoggingCache.prototype.get = function get(count) {
- return this._fetchAndParse().slice(0, count);
-};
-
-/** remove count number of entries starting with the oldest */
-LoggingCache.prototype.remove = function remove(count) {
- var _cache = this._fetchAndParse();
- var removed = _cache.splice(0, count);
- this._unparseAndStore(_cache);
- return removed;
-};
-
-/** empty/clear the entire cache */
-LoggingCache.prototype.empty = function empty() {
- localStorage.setItem(this.key, "[]");
- return this;
-};
-
-/** stringify count number of entries (but do not remove) */
-LoggingCache.prototype.stringify = function stringify(count) {
- return JSON.stringify(this.get(count));
-};
-
-/** outputs entire cache to console */
-LoggingCache.prototype.print = function print() {
- // popup? (really, carl? a popup?) - easier to copy/paste
- console.log(JSON.stringify(this._fetchAndParse(), null, " "));
-};
-
-//=============================================================================
-export default {
- MetricsLogger: MetricsLogger,
- LoggingCache: LoggingCache,
-};
diff --git a/client/src/utils/utils.test.js b/client/src/utils/utils.test.js
new file mode 100644
index 00000000000..eb2d10c9a0b
--- /dev/null
+++ b/client/src/utils/utils.test.js
@@ -0,0 +1,17 @@
+import Utils from "./utils";
+
+describe("test utils", () => {
+ it("test isEmpty", async () => {
+ expect(Utils.isEmpty([])).toBe(true); // "Empty array");
+ expect(Utils.isEmpty(["data", undefined])).toBe(true); // , "Array contains `undefined`");
+ expect(Utils.isEmpty(["data", null])).toBe(true); //, "Array contains `null`");
+ expect(Utils.isEmpty(["data", "__null__"])).toBe(true); // , "Array contains `__null__`");
+ expect(Utils.isEmpty(["data", "__undefined__"])).toBe(true); // , "Array contains `__undefined__`");
+ expect(Utils.isEmpty(null)).toBe(true); //, "Array is null");
+ expect(Utils.isEmpty("__null__")).toBe(true); //, "Array is __null__");
+ expect(Utils.isEmpty("__undefined__")).toBe(true); //, "Array is __undefined__");
+ expect(Utils.isEmpty(["data"])).toBe(false); //, "Array contains `data`");
+ expect(Utils.isEmpty(1)).toBe(false); //, "Value is int");
+ expect(Utils.isEmpty(0)).toBe(false); //, "Value is zero");
+ });
+});
diff --git a/client/tests/jest/__mocks__/localization.js b/client/tests/jest/__mocks__/localization.js
index c19346b6775..1c834c614b8 100644
--- a/client/tests/jest/__mocks__/localization.js
+++ b/client/tests/jest/__mocks__/localization.js
@@ -1,3 +1,11 @@
-export default (l) => {
+export function _setUserLocale(user, config) {
+ sessionStorage.setItem("currentLocale", "en");
+}
+
+export function _getUserLocale(user, config) {
+ return "en";
+}
+
+export default function localize(l) {
return l;
-};
+}
diff --git a/client/tests/jest/jest.config.js b/client/tests/jest/jest.config.js
index 90d99bbb5dc..a4a84c4f3b6 100644
--- a/client/tests/jest/jest.config.js
+++ b/client/tests/jest/jest.config.js
@@ -39,6 +39,7 @@ module.exports = {
roots: ["/src/", "/tests/jest/standalone/"],
setupFilesAfterEnv: ["/tests/jest/jest.setup.js"],
testEnvironment: "jsdom",
+ testPathIgnorePatterns: ["/node_modules/", "/dist/"],
transform: {
"^.+\\.js$": "babel-jest",
"^.*\\.(vue)$": "@vue/vue2-jest",
diff --git a/client/tests/karma/karma.config.base.js b/client/tests/karma/karma.config.base.js
deleted file mode 100644
index 96e1427b8a2..00000000000
--- a/client/tests/karma/karma.config.base.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Base karma config, assumes chrome headless and webpack
- */
-
-const webpackConfigFunc = require("./webpack.config.unittest");
-
-module.exports = (config) => {
- // Karma does not execute the webpack config function by default
- const webpackConfig = webpackConfigFunc(
- {},
- {
- mode: "testing",
- }
- );
-
- return {
- basePath: "../../src",
- browsers: ["ChromeHeadlessNoSandbox"],
- client: {
- captureConsole: true,
- },
- failOnEmptyTestSuite: false,
- singleRun: true,
- webpack: webpackConfig,
- webpackMiddleware: {
- noInfo: true,
- },
- customLaunchers: {
- ChromeHeadlessNoSandbox: {
- base: "ChromeHeadless",
- flags: ["--no-sandbox"],
- },
- },
- };
-};
diff --git a/client/tests/karma/karma.config.qunit.js b/client/tests/karma/karma.config.qunit.js
deleted file mode 100644
index 2ad9bac073d..00000000000
--- a/client/tests/karma/karma.config.qunit.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Qunit Tests
- *
- * These legacy QUnit tests are interdependent and only execute as a single
- * package. A flaw in the previous node environment parameter-checking in the
- * old karma configs gave the illusion that they ran individually, but they do
- * not and probably never have. Keeping them around for now, but we should get
- * rid of them by rewriting the tests or preferrably by removing the code to
- * which they apply.
- */
-
-const baseKarmaConfig = require("./karma.config.base");
-const testFiles = ["polyfills.js", "../tests/qunit/testBundle.js"];
-const preprocessors = testFiles.reduce((result, path) => {
- result[path] = ["webpack"];
- return result;
-}, {});
-
-module.exports = function (config) {
- const baseConfig = baseKarmaConfig(config);
-
- const settings = Object.assign({}, baseConfig, {
- files: testFiles,
- preprocessors: preprocessors,
- frameworks: ["polyfill", "qunit"],
- singleRun: true,
- });
-
- config.set(settings);
-};
diff --git a/client/tests/karma/webpack.config.qunit.js b/client/tests/karma/webpack.config.qunit.js
deleted file mode 100644
index 49e559ea620..00000000000
--- a/client/tests/karma/webpack.config.qunit.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * So the legacy QUnit tests have to perform some gymastics that should not be
- * required because thse tests apparently care about assets like the CSS and images.
- * TODO: Replace these tests with like... actual unit tests.
- */
-
-const baseConfig = require("../../webpack.config");
-
-module.exports = (env, argv) => {
- // load base config
- const wpConfig = baseConfig(env, argv);
- wpConfig.mode = "production";
- wpConfig.entry = () => ({});
-
- const switchPlugin = (reMatcher, replacement) => {
- const scrubLoader = (obj) =>
- typeof obj == "string" && obj.match(reMatcher) ? Object.assign({}, replacement) : obj;
-
- return (rule) => {
- if (rule.use && rule.use.length) {
- rule.use = rule.use.map(scrubLoader);
- }
- return rule;
- };
- };
-
- // Remove MiniCssExtractPlugin loader references
- // replace mini-css-extract plugin with basic style loader
- // Honestly I'm not clear on why we process css at all for unit tests
- const scrubLoaderRules = (module) => {
- const rePluginMatch = /mini-css-extract-plugin/;
- const styleLoader = { loader: "style-loader" };
- const processor = switchPlugin(rePluginMatch, styleLoader);
- module.rules = module.rules.map(processor);
- };
-
- // Remove mini-css-extract loader references
- scrubLoaderRules(wpConfig.module);
-
- // remove MiniCSSExtract Plugin
- wpConfig.plugins = wpConfig.plugins.filter((p) => {
- return p.constructor.name != "MiniCssExtractPlugin";
- });
-
- return wpConfig;
-};
diff --git a/client/tests/karma/webpack.config.unittest.js b/client/tests/karma/webpack.config.unittest.js
deleted file mode 100644
index e08877fcb18..00000000000
--- a/client/tests/karma/webpack.config.unittest.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Unit tests should not require css or images, so replace all those things with
- * the ignore-loader for speedier testing.
- */
-
-const merge = require("webpack-merge");
-const baseConfig = require("../../webpack.config");
-
-module.exports = (env, argv) => {
- const wpConfig = baseConfig(env, argv);
- wpConfig.mode = "development";
- wpConfig.entry = () => ({});
-
- // Don't need any assets for unit testing
- const ignoreAssetLoaders = {
- rules: [
- {
- test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)(\?.*$|$)/,
- loader: "ignore-loader",
- },
- {
- test: /\.css$/,
- loader: "ignore-loader",
- },
- {
- test: /\.scss$/,
- loader: "ignore-loader",
- },
- ],
- };
-
- wpConfig.module = merge.merge(wpConfig.module, ignoreAssetLoaders);
-
- return wpConfig;
-};
diff --git a/client/tests/qunit/test-app.js b/client/tests/qunit/test-app.js
deleted file mode 100644
index bf7ebe36332..00000000000
--- a/client/tests/qunit/test-app.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/** Creates a generic/global Galaxy environment, loads shared libraries and a
- * fake server */
-
-// jQuery.fn.tooltip lives on one of these 2 libs
-import "bootstrap";
-
-import sinon from "sinon";
-import Backbone from "backbone";
-import { setGalaxyInstance } from "app";
-import { getAppRoot } from "onload";
-import galaxyOptions from "./test-data/bootstrapped";
-import serverdata from "./test-data/fakeserver";
-
-export function setupTestGalaxy(galaxyOptions_ = null) {
- galaxyOptions_ = galaxyOptions_ || galaxyOptions;
- setGalaxyInstance((GalaxyApp) => {
- const galaxy = new GalaxyApp(galaxyOptions_);
- galaxy.currHistoryPanel = {
- model: new Backbone.Model(),
- };
- galaxy.emit = {
- debug: function () {},
- error: function (v) {
- window.console.error(v);
- },
- };
- return galaxy;
- });
-}
-
-export default {
- create() {
- setupTestGalaxy(galaxyOptions);
- window.WAIT_FADE = 300;
- window.fakeserver = sinon.fakeServer.create();
- for (var route in serverdata) {
- window.fakeserver.respondWith("GET", getAppRoot() + route, [
- 200,
- { "Content-Type": "application/json" },
- serverdata[route].data,
- ]);
- }
- },
-
- destroy() {
- if (window.fakeserver) {
- window.fakeserver.restore();
- delete window.fakeserver;
- }
- },
-};
diff --git a/client/tests/qunit/test-data/fakeserver.js b/client/tests/qunit/test-data/fakeserver.js
deleted file mode 100644
index 684e643ae42..00000000000
--- a/client/tests/qunit/test-data/fakeserver.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import dataTypesMapping from "./json/datatypes.mapping.json";
-import dataTypes from "./json/datatypes.json";
-
-export default {
- "api/datatypes/mapping": {
- data: JSON.stringify(dataTypesMapping),
- },
- "api/datatypes": {
- data: JSON.stringify(dataTypes),
- },
-};
diff --git a/client/tests/qunit/test-data/job-dag-1.js b/client/tests/qunit/test-data/job-dag-1.js
deleted file mode 100644
index f2a6596eded..00000000000
--- a/client/tests/qunit/test-data/job-dag-1.js
+++ /dev/null
@@ -1,529 +0,0 @@
-// ============================================================================
-var tools = {
- upload1: {},
- "Show beginning1": {},
- "Show tail1": {},
- random_lines1: {},
- __SET_METADATA__: {},
- cat1: {},
-};
-
-// ============================================================================
-// plain 3 step job chain
-var jobs1 = [
- {
- tool_id: "upload1",
- update_time: "2014-10-03T15:12:25.904033",
- inputs: {},
- outputs: {
- output0: {
- src: "hda",
- id: "8c959c9304a2bc4b",
- },
- },
- exit_code: 0,
- state: "ok",
- create_time: "2014-10-03T15:12:22.589152",
- params: {
- // ...
- },
- model_class: "Job",
- id: "8a81cf6f989c4467",
- tool: null,
- },
- {
- tool_id: "Show beginning1",
- update_time: "2014-10-03T15:14:04.328484",
- inputs: {
- input: {
- src: "hda",
- id: "8c959c9304a2bc4b",
- },
- },
- outputs: {
- out_file1: {
- src: "hda",
- id: "132016f833b57406",
- },
- },
- exit_code: 0,
- state: "ok",
- create_time: "2014-10-03T15:14:01.060662",
- params: {
- // ...
- },
- model_class: "Job",
- id: "6505e875ddb66fd2",
- tool: null,
- },
- {
- tool_id: "Show tail1",
- update_time: "2014-10-03T15:14:21.596871",
- inputs: {
- input: {
- src: "hda",
- id: "132016f833b57406",
- },
- },
- outputs: {
- out_file1: {
- src: "hda",
- id: "846fb0a2a64137c0",
- },
- },
- exit_code: 0,
- state: "ok",
- create_time: "2014-10-03T15:14:18.425681",
- params: {
- // ...
- },
- model_class: "Job",
- id: "77f74776fd03cbc5",
- tool: null,
- },
-];
-
-var historyContents1 = [
- {
- deleted: false,
- extension: "interval",
- hid: 1,
- history_content_type: "dataset",
- history_id: "911dde3ddb677bcd",
- id: "8c959c9304a2bc4b",
- name: "1.interval",
- purged: false,
- resubmitted: false,
- state: "ok",
- type: "file",
- url: "/api/histories/911dde3ddb677bcd/contents/datasets/8c959c9304a2bc4b",
- visible: true,
- },
- {
- deleted: false,
- extension: "interval",
- hid: 2,
- history_content_type: "dataset",
- history_id: "911dde3ddb677bcd",
- id: "132016f833b57406",
- name: "Select first on data 1",
- purged: false,
- resubmitted: false,
- state: "ok",
- type: "file",
- url: "/api/histories/911dde3ddb677bcd/contents/datasets/132016f833b57406",
- visible: true,
- },
- {
- deleted: false,
- extension: "interval",
- hid: 3,
- history_content_type: "dataset",
- history_id: "911dde3ddb677bcd",
- id: "846fb0a2a64137c0",
- name: "Select last on data 2",
- purged: false,
- resubmitted: false,
- state: "ok",
- type: "file",
- url: "/api/histories/911dde3ddb677bcd/contents/datasets/846fb0a2a64137c0",
- visible: true,
- },
-];
-
-// ============================================================================
-// single job chain with a __SET_METADATA__ job
-var jobs2 = [
- {
- tool_id: "upload1",
- update_time: "2014-10-03T16:09:49.590769",
- inputs: {},
- outputs: {
- output0: {
- src: "hda",
- id: "eca0af6fb47bf90c",
- },
- },
- exit_code: 0,
- state: "ok",
- create_time: "2014-10-03T16:09:45.190023",
- params: {
- // ...
- },
- model_class: "Job",
- id: "bf60fd5f5f7f44bf",
- tool: null,
- },
- {
- tool_id: "random_lines1",
- update_time: "2014-10-03T16:10:44.743610",
- inputs: {
- input: {
- src: "hda",
- id: "eca0af6fb47bf90c",
- },
- },
- outputs: {
- out_file1: {
- src: "hda",
- id: "6fc9fbb81c497f69",
- },
- },
- exit_code: 0,
- state: "ok",
- create_time: "2014-10-03T16:10:41.446413",
- params: {
- // ...
- },
- model_class: "Job",
- id: "90240358ebde1489",
- tool: null,
- },
- {
- tool_id: "__SET_METADATA__",
- update_time: "2014-10-03T16:14:44.196697",
- inputs: {
- input1: {
- src: "hda",
- id: "eca0af6fb47bf90c",
- },
- },
- outputs: {},
- exit_code: 0,
- state: "ok",
- create_time: "2014-10-03T16:14:37.901222",
- params: {
- // ...
- },
- model_class: "Job",
- id: "86cf1d3beeec9f1c",
- tool: null,
- },
-];
-
-var historyContents2 = [
- {
- deleted: false,
- extension: "interval",
- hid: 1,
- history_content_type: "dataset",
- history_id: "ff5476bcf6c921fa",
- id: "eca0af6fb47bf90c",
- name: "1.interval",
- purged: false,
- resubmitted: false,
- state: "ok",
- type: "file",
- url: "/api/histories/ff5476bcf6c921fa/contents/datasets/eca0af6fb47bf90c",
- visible: true,
- },
- {
- deleted: false,
- extension: "interval",
- hid: 2,
- history_content_type: "dataset",
- history_id: "ff5476bcf6c921fa",
- id: "6fc9fbb81c497f69",
- name: "Select random lines on data 1",
- purged: false,
- resubmitted: false,
- state: "ok",
- type: "file",
- url: "/api/histories/ff5476bcf6c921fa/contents/datasets/6fc9fbb81c497f69",
- visible: true,
- },
-];
-
-var jobs3 = [
- {
- tool_id: "upload1",
- update_time: "2014-10-13T20:28:58.549844",
- inputs: {},
- outputs: {
- output0: {
- src: "hda",
- id: "6fb17d0cc6e8fae5",
- },
- },
- exit_code: 0,
- state: "ok",
- create_time: "2014-10-13T20:28:43.162803",
- params: {
- // ...
- },
- model_class: "Job",
- id: "8c959c9304a2bc4b",
- tool: null,
- },
- {
- tool_id: "upload1",
- update_time: "2014-10-13T20:28:58.932152",
- inputs: {},
- outputs: {
- output0: {
- src: "hda",
- id: "5114a2a207b7caff",
- },
- },
- exit_code: 0,
- state: "ok",
- create_time: "2014-10-13T20:28:47.421452",
- params: {
- // ...
- },
- model_class: "Job",
- id: "132016f833b57406",
- tool: null,
- },
- {
- tool_id: "Show beginning1",
- update_time: "2014-10-13T20:29:31.424058",
- inputs: {
- input: {
- src: "hda",
- id: "6fb17d0cc6e8fae5",
- },
- },
- outputs: {
- out_file1: {
- src: "hda",
- id: "06ec17aefa2d49dd",
- },
- },
- exit_code: 0,
- state: "ok",
- create_time: "2014-10-13T20:29:28.769495",
- params: {
- // ...
- },
- model_class: "Job",
- id: "846fb0a2a64137c0",
- tool: null,
- },
- {
- tool_id: "Show beginning1",
- update_time: "2014-10-13T20:29:55.851096",
- inputs: {
- input: {
- src: "hda",
- id: "5114a2a207b7caff",
- },
- },
- outputs: {
- out_file1: {
- src: "hda",
- id: "b8a0d6158b9961df",
- },
- },
- exit_code: 0,
- state: "ok",
- create_time: "2014-10-13T20:29:53.291703",
- params: {
- // ...
- },
- model_class: "Job",
- id: "eca0af6fb47bf90c",
- tool: null,
- },
- {
- tool_id: "Show tail1",
- update_time: "2014-10-13T20:30:16.225937",
- inputs: {
- input: {
- src: "hda",
- id: "b8a0d6158b9961df",
- },
- },
- outputs: {
- out_file1: {
- src: "hda",
- id: "24d84bcf64116fe7",
- },
- },
- exit_code: 0,
- state: "ok",
- create_time: "2014-10-13T20:30:13.789842",
- params: {
- // ...
- },
- model_class: "Job",
- id: "6fc9fbb81c497f69",
- tool: null,
- },
-];
-
-var historyContents3 = [
- {
- deleted: false,
- extension: "bed",
- hid: 1,
- history_content_type: "dataset",
- history_id: "5564089c81cf7fe8",
- id: "6fb17d0cc6e8fae5",
- name: "1.bed",
- purged: false,
- resubmitted: false,
- state: "ok",
- type: "file",
- url: "/api/histories/5564089c81cf7fe8/contents/datasets/6fb17d0cc6e8fae5",
- visible: true,
- },
- {
- deleted: false,
- extension: "interval",
- hid: 2,
- history_content_type: "dataset",
- history_id: "5564089c81cf7fe8",
- id: "5114a2a207b7caff",
- name: "1.interval",
- purged: false,
- resubmitted: false,
- state: "ok",
- type: "file",
- url: "/api/histories/5564089c81cf7fe8/contents/datasets/5114a2a207b7caff",
- visible: true,
- },
- {
- deleted: false,
- extension: "bed",
- hid: 3,
- history_content_type: "dataset",
- history_id: "5564089c81cf7fe8",
- id: "06ec17aefa2d49dd",
- name: "Select first on data 1",
- purged: false,
- resubmitted: false,
- state: "ok",
- type: "file",
- url: "/api/histories/5564089c81cf7fe8/contents/datasets/06ec17aefa2d49dd",
- visible: true,
- },
- {
- deleted: false,
- extension: "interval",
- hid: 4,
- history_content_type: "dataset",
- history_id: "5564089c81cf7fe8",
- id: "b8a0d6158b9961df",
- name: "Select first on data 2",
- purged: false,
- resubmitted: false,
- state: "ok",
- type: "file",
- url: "/api/histories/5564089c81cf7fe8/contents/datasets/b8a0d6158b9961df",
- visible: true,
- },
- {
- deleted: false,
- extension: "interval",
- hid: 5,
- history_content_type: "dataset",
- history_id: "5564089c81cf7fe8",
- id: "24d84bcf64116fe7",
- name: "Select last on data 4",
- purged: false,
- resubmitted: false,
- state: "ok",
- type: "file",
- url: "/api/histories/5564089c81cf7fe8/contents/datasets/24d84bcf64116fe7",
- visible: true,
- },
-];
-
-var jobs4 = [
- {
- tool_id: "cat1",
- update_time: "2014-10-21T17:33:36.960857",
- inputs: {
- input1: {
- src: "hda",
- id: "422eef6b1b545329",
- name: "input1",
- },
- "queries_0|input2": {
- src: "hda",
- id: "c86c1b73aa7102dd",
- name: "queries_0|input2",
- },
- },
- outputs: {
- out_file1: {
- src: "hda",
- id: "52d6bdfafedbb5e5",
- name: "out_file1",
- },
- },
- exit_code: 0,
- state: "ok",
- create_time: "2014-10-21T17:33:34.302245",
- params: {
- // ...
- },
- model_class: "Job",
- id: "92b83968e0b52980",
- },
-];
-
-var historyContents4 = [
- {
- dataset_id: 29,
- deleted: false,
- extension: "vcf",
- hid: 1,
- history_content_type: "dataset",
- history_id: "c24141d7e4e77705",
- id: "422eef6b1b545329",
- name: "1.vcf",
- purged: false,
- resubmitted: false,
- state: "ok",
- type: "file",
- url: "/api/histories/c24141d7e4e77705/contents/datasets/422eef6b1b545329",
- visible: true,
- },
- {
- dataset_id: 56,
- deleted: false,
- extension: "maf",
- hid: 2,
- history_content_type: "dataset",
- history_id: "c24141d7e4e77705",
- id: "c86c1b73aa7102dd",
- name: "3.maf",
- purged: false,
- resubmitted: false,
- state: "ok",
- type: "file",
- url: "/api/histories/c24141d7e4e77705/contents/datasets/c86c1b73aa7102dd",
- visible: true,
- },
- {
- dataset_id: 131,
- deleted: false,
- extension: "maf",
- hid: 3,
- history_content_type: "dataset",
- history_id: "c24141d7e4e77705",
- id: "52d6bdfafedbb5e5",
- name: "Concatenate datasets on data 1 and data 2",
- purged: false,
- resubmitted: false,
- state: "ok",
- type: "file",
- url: "/api/histories/c24141d7e4e77705/contents/datasets/52d6bdfafedbb5e5",
- visible: true,
- },
-];
-
-// ============================================================================
-export default {
- tools: tools,
- jobs1: jobs1,
- historyContents1: historyContents1,
- jobs2: jobs2,
- historyContents2: historyContents2,
- jobs3: jobs3,
- historyContents3: historyContents3,
- jobs4: jobs4,
- historyContents4: historyContents4,
-};
diff --git a/client/tests/qunit/testBundle.js b/client/tests/qunit/testBundle.js
deleted file mode 100644
index 2286b30def8..00000000000
--- a/client/tests/qunit/testBundle.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// Load all qunit tests into a single bundle.
-//var testsContext = require.context(".", true, /_tests$/);
-//testsContext.keys().forEach(testsContext);
-
-import "./tests/galaxy_app_base_tests";
-import "./tests/jquery_plugin_tests";
-import "./tests/metrics_logger_tests";
-import "./tests/graph_tests";
-import "./tests/modal_tests";
-import "./tests/utils_tests";
-import "./tests/ui_tests";
diff --git a/client/tests/qunit/tests/galaxy_app_base_tests.js b/client/tests/qunit/tests/galaxy_app_base_tests.js
deleted file mode 100644
index 0d18449f594..00000000000
--- a/client/tests/qunit/tests/galaxy_app_base_tests.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/* global QUnit */
-import testApp from "../test-app";
-import { getGalaxyInstance, setGalaxyInstance } from "app";
-
-QUnit.module("Galaxy client app tests", {
- beforeEach: function () {
- testApp.create();
- },
- afterEach: function () {
- testApp.destroy();
- },
-});
-
-QUnit.test("App base construction/initializiation defaults", function (assert) {
- var app = getGalaxyInstance();
- assert.ok(app.hasOwnProperty("options") && typeof app.options === "object");
- assert.ok(app.hasOwnProperty("logger") && typeof app.logger === "object");
- assert.ok(app.hasOwnProperty("localize") && typeof app.localize === "function");
- assert.ok(app.hasOwnProperty("config") && typeof app.config === "object");
- assert.ok(app.hasOwnProperty("user") && typeof app.config === "object");
- assert.equal(app.localize, window._l);
-});
-
-QUnit.test("App base default options", function (assert) {
- var app = getGalaxyInstance();
- assert.ok(app.hasOwnProperty("options") && typeof app.options === "object");
- assert.equal(app.options.root, "/");
- assert.equal(app.options.patchExisting, true);
-});
-
-QUnit.test("App base extends from Backbone.Events", function (assert) {
- var app = getGalaxyInstance();
- ["on", "off", "trigger", "listenTo", "stopListening"].forEach(function (fn) {
- assert.ok(app.hasOwnProperty(fn) && typeof app[fn] === "function");
- });
-});
-
-QUnit.test("App base has logging methods from utils/add-logging.js", function (assert) {
- var app = getGalaxyInstance();
- ["debug", "info", "warn", "error", "metric"].forEach(function (fn) {
- assert.ok(typeof app[fn] === "function");
- });
- assert.ok(app._logNamespace === "GalaxyApp");
-});
-
-// We no longer want this behavior
-QUnit.test("App base will patch in attributes from existing Galaxy objects", function (assert) {
- var existingApp = getGalaxyInstance();
- existingApp.foo = 123;
-
- var newApp = setGalaxyInstance((GalaxyApp) => {
- return new GalaxyApp();
- });
-
- assert.ok(newApp.foo === 123);
-});
-
-QUnit.test("App base logger", function (assert) {
- var app = getGalaxyInstance();
- assert.ok(app.hasOwnProperty("logger") && typeof app.config === "object");
-});
-
-QUnit.test("App base config", function (assert) {
- var app = getGalaxyInstance();
- assert.ok(app.hasOwnProperty("config") && typeof app.config === "object");
- assert.equal(app.config.allow_user_deletion, false);
- assert.equal(app.config.allow_user_creation, true);
- assert.equal(app.config.wiki_url, "https://galaxyproject.org/");
- assert.equal(app.config.ftp_upload_site, null);
-});
-
-QUnit.test("App base user", function (assert) {
- var app = getGalaxyInstance();
- assert.ok(app.hasOwnProperty("user") && typeof app.user === "object");
- assert.ok(app.user.isAdmin() === false);
-});
diff --git a/client/tests/qunit/tests/graph_tests.js b/client/tests/qunit/tests/graph_tests.js
deleted file mode 100644
index 19e945d9a6b..00000000000
--- a/client/tests/qunit/tests/graph_tests.js
+++ /dev/null
@@ -1,563 +0,0 @@
-/* global QUnit */
-import testApp from "../test-app";
-import GRAPH from "utils/graph";
-
-QUnit.module("utils/graph.js library tests", {
- beforeEach: function () {
- testApp.create();
- },
- afterEach: function () {
- testApp.destroy();
- },
-});
-
-///*
-function testEmptyObject(assert, o) {
- assert.ok(typeof o === "object");
- assert.ok(Object.keys(o).length === 0);
-}
-
-// ------------------------------------------------------------------------ vertices
-QUnit.test("Empty vertex construction", function (assert) {
- var vert = new GRAPH.Vertex();
- assert.ok(vert instanceof GRAPH.Vertex);
- assert.ok(vert.name === "(unnamed)");
- assert.ok(vert.data === null);
- testEmptyObject(assert, vert.edges);
- assert.ok(vert.degree === 0);
- assert.ok(vert + "" === "Vertex((unnamed))");
- assert.deepEqual(vert.toJSON(), { name: "(unnamed)", data: null });
-});
-
-QUnit.test("Vertex construction", function (assert) {
- var vert = new GRAPH.Vertex("blah", { blorp: 1, bleep: 2 });
- assert.ok(vert instanceof GRAPH.Vertex);
- assert.ok(vert.name === "blah");
- assert.deepEqual(vert.data, { blorp: 1, bleep: 2 });
- testEmptyObject(assert, vert.edges);
- assert.ok(vert.degree === 0);
- assert.ok(vert + "" === "Vertex(blah)");
- assert.deepEqual(vert.toJSON(), { name: "blah", data: { blorp: 1, bleep: 2 } });
-});
-
-// ------------------------------------------------------------------------ edges
-QUnit.test("Empty edge construction", function (assert) {
- var edge = new GRAPH.Edge();
- assert.ok(edge instanceof GRAPH.Edge);
- assert.ok(edge.source === null);
- assert.ok(edge.target === null);
- assert.ok(edge.data === null);
- assert.ok(edge + "" === "null->null");
- assert.deepEqual(edge.toJSON(), { source: null, target: null });
-});
-
-QUnit.test("Edge construction", function (assert) {
- var edge = new GRAPH.Edge("A", "B", { one: 1, two: 2 });
- assert.ok(edge instanceof GRAPH.Edge);
- assert.ok(edge.source === "A");
- assert.ok(edge.target === "B");
- assert.deepEqual(edge.data, { one: 1, two: 2 });
- assert.ok(edge + "" === "A->B");
- assert.deepEqual(edge.toJSON(), { source: "A", target: "B", data: { one: 1, two: 2 } });
-});
-
-// ------------------------------------------------------------------------ graphs
-function testEmptyGraph(assert, graph) {
- assert.ok(graph instanceof GRAPH.Graph);
- testEmptyObject(assert, graph.vertices);
- assert.ok(graph.numEdges === 0);
-}
-
-QUnit.test("Empty graph construction", function (assert) {
- var graph = new GRAPH.Graph();
-
- assert.ok(graph.directed === false);
- assert.ok(graph.allowReflexiveEdges === false);
-
- testEmptyGraph(assert, graph);
-});
-
-QUnit.test("Bad data graph construction", function (assert) {
- var graph = new GRAPH.Graph(false, {});
- testEmptyGraph(assert, graph);
-
- graph = new GRAPH.Graph(false, null);
- testEmptyGraph(assert, graph);
-});
-
-QUnit.test("Test directed and options", function (assert) {
- var graph = new GRAPH.Graph(true, {}, { allowReflexiveEdges: true });
-
- assert.ok(graph.directed);
- assert.ok(graph.allowReflexiveEdges);
-
- testEmptyGraph(assert, graph);
-});
-
-function testSampleDirectedGraph(assert, graph) {
- assert.ok(!graph.directed);
-
- assert.ok(Object.keys(graph.vertices).length === 3);
- assert.ok(graph.vertices.A instanceof GRAPH.Vertex);
- assert.ok(graph.vertices.B instanceof GRAPH.Vertex);
- assert.ok(graph.vertices.C instanceof GRAPH.Vertex);
-
- assert.deepEqual(Object.keys(graph.vertices.A.edges), ["B", "C"]);
- assert.deepEqual(Object.keys(graph.vertices.B.edges), ["A", "C"]);
- assert.deepEqual(Object.keys(graph.vertices.C.edges), ["A", "B"]);
-
- assert.ok(graph.vertices.A.degree === 2);
- assert.ok(graph.vertices.B.degree === 2);
- assert.ok(graph.vertices.C.degree === 2);
-
- assert.deepEqual(graph.vertices.A.edges.B.toJSON(), { source: "A", target: "B" });
- assert.deepEqual(graph.vertices.A.edges.C.toJSON(), { source: "A", target: "C" });
- assert.deepEqual(graph.vertices.B.edges.A.toJSON(), { source: "B", target: "A" });
- assert.deepEqual(graph.vertices.B.edges.C.toJSON(), { source: "B", target: "C" });
- assert.deepEqual(graph.vertices.C.edges.A.toJSON(), { source: "C", target: "A" });
- assert.deepEqual(graph.vertices.C.edges.B.toJSON(), { source: "C", target: "B" });
-
- assert.ok(graph.numEdges === 6);
-}
-
-function testSampleNonDirectedGraph(assert, graph) {
- assert.ok(graph.directed);
-
- assert.ok(Object.keys(graph.vertices).length === 3);
- assert.ok(graph.vertices.A instanceof GRAPH.Vertex);
- assert.ok(graph.vertices.B instanceof GRAPH.Vertex);
- assert.ok(graph.vertices.C instanceof GRAPH.Vertex);
-
- assert.deepEqual(Object.keys(graph.vertices.A.edges), ["B", "C"]);
- assert.deepEqual(Object.keys(graph.vertices.B.edges), ["C"]);
- assert.deepEqual(Object.keys(graph.vertices.C.edges), []);
-
- assert.ok(graph.vertices.A.degree === 2);
- assert.ok(graph.vertices.B.degree === 1);
- assert.ok(graph.vertices.C.degree === 0);
-
- assert.deepEqual(graph.vertices.A.edges.B.toJSON(), { source: "A", target: "B" });
- assert.deepEqual(graph.vertices.A.edges.C.toJSON(), { source: "A", target: "C" });
- assert.deepEqual(graph.vertices.B.edges.C.toJSON(), { source: "B", target: "C" });
-
- assert.ok(graph.numEdges === 3);
-}
-
-var nodeLinkData = {
- nodes: [
- { name: "A", data: 100 },
- { name: "B", data: 200 },
- { name: "C", data: 300 },
- ],
- links: [
- { source: 0, target: 1 },
- { source: 0, target: 2 },
- { source: 1, target: 2 },
- ],
-};
-
-QUnit.test("Test nodes and links data input on *non-directed* graph", function (assert) {
- var graph = new GRAPH.Graph(false, nodeLinkData);
- testSampleDirectedGraph(assert, graph);
-});
-
-QUnit.test("Test nodes and links data input on *directed* graph", function (assert) {
- var graph = new GRAPH.Graph(true, nodeLinkData);
- testSampleNonDirectedGraph(assert, graph);
-});
-
-var vertexEdgeData = {
- vertices: [
- { name: "A", data: 100 },
- { name: "B", data: 200 },
- { name: "C", data: 300 },
- ],
- edges: [
- { source: "A", target: "B" },
- { source: "A", target: "C" },
- { source: "B", target: "C" },
- ],
-};
-
-QUnit.test("Test vertex and edge data input on *non-directed* graph", function (assert) {
- var graph = new GRAPH.Graph(false, vertexEdgeData);
- testSampleDirectedGraph(assert, graph);
-});
-
-QUnit.test("Test vertex and edge data input on *directed* graph", function (assert) {
- var graph = new GRAPH.Graph(true, vertexEdgeData);
- testSampleNonDirectedGraph(assert, graph);
-});
-
-QUnit.test("Test vertex eachEdge", function (assert) {
- var graph = new GRAPH.Graph(false, nodeLinkData);
- assert.ok(typeof graph.vertices.A.eachEdge === "function");
- assert.deepEqual(
- graph.vertices.A.eachEdge(function (e) {
- return e.target;
- }),
- ["B", "C"]
- );
- assert.ok(graph.vertices.A.eachEdge({ target: "B" }).length === 1);
-});
-
-QUnit.test("Test graph eachVertex", function (assert) {
- var graph = new GRAPH.Graph(true, nodeLinkData);
- assert.ok(typeof graph.eachVertex === "function");
- assert.deepEqual(
- graph.eachVertex(function (v) {
- return { n: v.name, d: v.degree };
- }),
- [
- { n: "A", d: 2 },
- { n: "B", d: 1 },
- { n: "C", d: 0 },
- ]
- );
- assert.ok(graph.eachVertex({ degree: 2 })[0] === graph.vertices.A);
-});
-
-QUnit.test("Test createVertex", function (assert) {
- var graph = new GRAPH.Graph();
- var vert1 = graph.createVertex("A", { blah: 1 });
- assert.ok(vert1 instanceof GRAPH.Vertex);
- assert.ok(vert1 === graph.vertices.A);
- assert.ok(graph.createVertex("A", { blah: 1 }) === vert1);
-});
-
-QUnit.test("Test createEdge", function (assert) {
- var graph, A, B, edge;
-
- graph = new GRAPH.Graph();
- A = graph.createVertex("A");
- B = graph.createVertex("B");
- edge = graph.createEdge("A", "B");
- assert.ok(edge instanceof GRAPH.Edge);
- assert.ok(A.degree === 1);
- assert.ok(B.degree === 1);
- assert.ok(A.edges.B);
- assert.ok(B.edges.A);
- assert.ok(graph.numEdges === 2);
-
- // bad target
- graph = new GRAPH.Graph();
- A = graph.createVertex("A");
- B = graph.createVertex("B");
- edge = graph.createEdge("A", "C");
- assert.ok(edge === null);
- assert.ok(A.degree === 0);
- assert.ok(B.degree === 0);
- assert.ok(!A.edges.B);
- assert.ok(!B.edges.A);
- assert.ok(graph.numEdges === 0);
-
- // bad source
- graph = new GRAPH.Graph();
- A = graph.createVertex("A");
- B = graph.createVertex("B");
- edge = graph.createEdge("C", "A");
- assert.ok(graph.numEdges === 0);
-
- // reflexive
- graph = new GRAPH.Graph();
- A = graph.createVertex("A");
- B = graph.createVertex("B");
- edge = graph.createEdge("A", "A");
- assert.ok(graph.numEdges === 0);
-
- // reflexive (allowed)
- graph = new GRAPH.Graph(false, {}, { allowReflexiveEdges: true });
- A = graph.createVertex("A");
- edge = graph.createEdge("A", "A");
- // reflexive edges shouldn't mirror
- assert.ok(graph.numEdges === 1);
- assert.ok(A.edges.A);
-});
-
-QUnit.test("Test graph.edges", function (assert) {
- var graph = new GRAPH.Graph(false, nodeLinkData);
- assert.ok(graph.edges().length === 6);
- assert.deepEqual(
- graph.edges(function (e) {
- return e.source;
- }),
- ["A", "A", "B", "B", "C", "C"]
- );
- assert.deepEqual(graph.edges({ source: "A" }), [graph.vertices.A.edges.B, graph.vertices.A.edges.C]);
-
- graph = new GRAPH.Graph(true, nodeLinkData);
- assert.ok(graph.edges().length === 3);
- assert.deepEqual(
- graph.edges(function (e) {
- return e.source;
- }),
- ["A", "A", "B"]
- );
- assert.deepEqual(graph.edges({ source: "A" }), [graph.vertices.A.edges.B, graph.vertices.A.edges.C]);
-});
-
-QUnit.test("Test graph.adjacent", function (assert) {
- var graph = new GRAPH.Graph(true, nodeLinkData);
- assert.deepEqual(graph.adjacent(graph.vertices.A), [graph.vertices.B, graph.vertices.C]);
- assert.deepEqual(graph.adjacent(graph.vertices.B), [graph.vertices.C]);
- assert.deepEqual(graph.adjacent(graph.vertices.C), []);
-});
-
-QUnit.test("Test graph.eachAdjacent", function (assert) {
- var graph = new GRAPH.Graph(true, nodeLinkData);
- assert.deepEqual(
- graph.eachAdjacent(graph.vertices.A, function (v, e) {
- return v;
- }),
- [graph.vertices.B, graph.vertices.C]
- );
-});
-
-// ------------------------------------------------------------------------ breadth first search
-QUnit.test("Empty BreadthFirstSearch", function (assert) {
- var search = new GRAPH.BreadthFirstSearch();
- assert.ok(search instanceof GRAPH.BreadthFirstSearch);
- assert.ok(search.graph === undefined);
- assert.ok(typeof search.processFns === "object");
- assert.ok(typeof search.processFns.vertexEarly === "function");
- assert.ok(typeof search.processFns.edge === "function");
- assert.ok(typeof search.processFns.vertexLate === "function");
- assert.ok(typeof search._cache === "object");
-});
-
-QUnit.test("BreadthFirstSearch on undirected graph", function (assert) {
- var graph = new GRAPH.Graph(false, nodeLinkData),
- bfs = new GRAPH.BreadthFirstSearch(graph);
- assert.ok(bfs instanceof GRAPH.BreadthFirstSearch);
- assert.ok(bfs.graph === graph);
-
- var search = bfs.search("A"),
- tree = bfs.searchTree("A");
- assert.deepEqual(search, {
- discovered: { A: true, B: true, C: true },
- edges: [
- { source: "A", target: "B" },
- { source: "A", target: "C" },
- ],
- });
- assert.ok(tree instanceof GRAPH.Graph);
- assert.deepEqual(tree.vertices.A.toJSON(), graph.vertices.A.toJSON());
- assert.deepEqual(
- tree.eachVertex(function (v) {
- return v.degree;
- }),
- [2, 0, 0]
- );
-
- assert.deepEqual(bfs.search("B").edges, [
- { source: "B", target: "A" },
- { source: "B", target: "C" },
- ]);
- assert.deepEqual(bfs.search("C").edges, [
- { source: "C", target: "A" },
- { source: "C", target: "B" },
- ]);
- assert.ok(typeof bfs._cache.A === "object");
- assert.deepEqual(Object.keys(bfs._cache), ["A", "B", "C"]);
-});
-
-QUnit.test("BreadthFirstSearch on directed graph", function (assert) {
- var graph = new GRAPH.Graph(true, nodeLinkData),
- bfs = new GRAPH.BreadthFirstSearch(graph);
- assert.ok(bfs instanceof GRAPH.BreadthFirstSearch);
- assert.ok(bfs.graph === graph);
-
- var search = bfs.search("A"),
- tree = bfs.searchTree("A");
- assert.deepEqual(search, {
- discovered: { A: true, B: true, C: true },
- edges: [
- { source: "A", target: "B" },
- { source: "A", target: "C" },
- ],
- });
- assert.ok(tree instanceof GRAPH.Graph);
- assert.deepEqual(tree.vertices.A.toJSON(), graph.vertices.A.toJSON());
- assert.deepEqual(
- tree.eachVertex(function (v) {
- return v.degree;
- }),
- [2, 0, 0]
- );
-
- assert.deepEqual(bfs.search("B").edges, [{ source: "B", target: "C" }]);
- assert.deepEqual(bfs.search("C").edges, []);
- assert.ok(typeof bfs._cache.A === "object");
- assert.deepEqual(Object.keys(bfs._cache), ["A", "B", "C"]);
-});
-
-// ------------------------------------------------------------------------ depth first search
-var DFSData = {
- vertices: [{ name: "A" }, { name: "B" }, { name: "C" }, { name: "D" }, { name: "E" }, { name: "F" }],
- edges: [
- { source: "A", target: "B" },
- { source: "B", target: "C" },
- // confound it
- { source: "A", target: "C" },
- { source: "C", target: "D" },
- { source: "A", target: "E" },
- { source: "E", target: "F" },
- // confound it
- { source: "F", target: "A" },
- ],
-};
-
-QUnit.test("Empty DepthFirstSearch", function (assert) {
- var search = new GRAPH.DepthFirstSearch();
- assert.ok(search instanceof GRAPH.DepthFirstSearch);
- assert.ok(search.graph === undefined);
- assert.ok(typeof search.processFns === "object");
- assert.ok(typeof search.processFns.vertexEarly === "function");
- assert.ok(typeof search.processFns.edge === "function");
- assert.ok(typeof search.processFns.vertexLate === "function");
- assert.ok(typeof search._cache === "object");
-});
-
-QUnit.test("DepthFirstSearch on undirected graph", function (assert) {
- var graph = new GRAPH.Graph(false, DFSData),
- dfs = new GRAPH.DepthFirstSearch(graph);
- assert.ok(dfs instanceof GRAPH.DepthFirstSearch);
- assert.ok(dfs.graph === graph);
-
- var search = dfs.search("A"),
- tree = dfs.searchTree("A");
- assert.deepEqual(search, {
- discovered: { A: true, B: true, C: true, D: true, E: true, F: true },
- edges: [
- { source: "A", target: "B" },
- { source: "B", target: "C" },
- { source: "C", target: "D" },
- { source: "A", target: "E" },
- { source: "E", target: "F" },
- ],
- entryTimes: { A: 0, B: 1, C: 2, D: 3, E: 7, F: 8 },
- exitTimes: { A: 11, B: 6, C: 5, D: 4, E: 10, F: 9 },
- });
- assert.ok(tree instanceof GRAPH.Graph);
- assert.deepEqual(tree.vertices.A.toJSON(), graph.vertices.A.toJSON());
- assert.deepEqual(
- tree.eachVertex(function (v) {
- return v.degree;
- }),
- [2, 1, 1, 0, 1, 0]
- );
-
- assert.deepEqual(dfs.search("B").edges, [
- { source: "B", target: "A" },
- { source: "A", target: "C" },
- { source: "C", target: "D" },
- { source: "A", target: "E" },
- { source: "E", target: "F" },
- ]);
-
- assert.ok(typeof dfs._cache.A === "object");
- assert.deepEqual(Object.keys(dfs._cache), ["A", "B"]);
-});
-
-QUnit.test("DepthFirstSearch on directed graph", function (assert) {
- var graph = new GRAPH.Graph(true, DFSData),
- dfs = new GRAPH.DepthFirstSearch(graph);
- assert.ok(dfs instanceof GRAPH.DepthFirstSearch);
- assert.ok(dfs.graph === graph);
-
- var search = dfs.search("A"),
- tree = dfs.searchTree("A");
- assert.deepEqual(search, {
- discovered: { A: true, B: true, C: true, D: true, E: true, F: true },
- edges: [
- { source: "A", target: "B" },
- { source: "B", target: "C" },
- { source: "C", target: "D" },
- { source: "A", target: "E" },
- { source: "E", target: "F" },
- ],
- entryTimes: { A: 0, B: 1, C: 2, D: 3, E: 7, F: 8 },
- exitTimes: { A: 11, B: 6, C: 5, D: 4, E: 10, F: 9 },
- });
- assert.ok(tree instanceof GRAPH.Graph);
- assert.deepEqual(tree.vertices.A.toJSON(), graph.vertices.A.toJSON());
- assert.deepEqual(
- tree.eachVertex(function (v) {
- return v.degree;
- }),
- [2, 1, 1, 0, 1, 0]
- );
-
- assert.deepEqual(dfs.search("B").edges, [
- { source: "B", target: "C" },
- { source: "C", target: "D" },
- ]);
-
- assert.ok(typeof dfs._cache.A === "object");
- assert.deepEqual(Object.keys(dfs._cache), ["A", "B"]);
-});
-
-// ------------------------------------------------------------------------ components
-//*/
-QUnit.test("weakComponents on undirected graph", function (assert) {
- var graph = new GRAPH.Graph(false, {
- vertices: [{ name: "A" }, { name: "B" }, { name: "C" }, { name: "D" }, { name: "E" }],
- edges: [
- { source: "A", target: "B" },
- { source: "C", target: "D" },
- ],
- });
- assert.equal(graph.numEdges, 4);
- var components = graph.weakComponents();
- assert.equal(components.length, 3);
-});
-
-QUnit.test("weakComponents on directed graph", function (assert) {
- var graph, components;
- graph = new GRAPH.Graph(true, {
- vertices: [{ name: "A" }, { name: "B" }, { name: "C" }, { name: "D" }, { name: "E" }],
- edges: [
- { source: "A", target: "B" },
- { source: "D", target: "C" },
- ],
- });
- assert.equal(graph.numEdges, 2);
-
- components = graph.weakComponents();
- assert.equal(components.length, 3);
-
- graph = new GRAPH.Graph(true, {
- vertices: [
- { name: "A", data: 100 },
- { name: "B", data: 200 },
- { name: "C", data: 30 },
- { name: "D", data: 40 },
- { name: "E", data: 500 },
- { name: "F", data: 600 },
- { name: "G", data: 7 },
- ],
- edges: [
- { source: "A", target: "B" },
- { source: "D", target: "C" },
- { source: "E", target: "A" },
- { source: "F", target: "E" },
- ],
- });
- components = graph.weakComponents();
- assert.equal(components.length, 3);
- // data retained
- assert.equal(components[0].vertices[0].data, 100);
-
- assert.equal(components[0].vertices.length, 4);
- assert.deepEqual(components[0].edges, [
- { source: "A", target: "B" },
- { source: "E", target: "A" },
- { source: "F", target: "E" },
- ]);
-
- assert.equal(components[1].vertices.length, 2);
- assert.deepEqual(components[1].edges, [{ source: "D", target: "C" }]);
-
- assert.deepEqual(components[2].vertices, [{ name: "G", data: 7 }]);
- assert.deepEqual(components[2].edges.length, 0);
-});
diff --git a/client/tests/qunit/tests/jquery_plugin_tests.js b/client/tests/qunit/tests/jquery_plugin_tests.js
deleted file mode 100644
index 2d2cc1cc83e..00000000000
--- a/client/tests/qunit/tests/jquery_plugin_tests.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/* global QUnit */
-import $ from "jquery";
-import testApp from "../test-app";
-
-QUnit.module("Galaxy jquery plugin test", {
- beforeEach: function () {
- testApp.create();
- },
- afterEach: function () {
- testApp.destroy();
- },
-});
-
-QUnit.test("Check jquery for tooltip and select2", function (assert) {
- assert.ok($.fn.tooltip);
- assert.ok($.fn.select2);
-});
diff --git a/client/tests/qunit/tests/metrics_logger_tests.js b/client/tests/qunit/tests/metrics_logger_tests.js
deleted file mode 100644
index ce069fcf3c7..00000000000
--- a/client/tests/qunit/tests/metrics_logger_tests.js
+++ /dev/null
@@ -1,379 +0,0 @@
-// This file isn't really testing anything useful yet, it is just testing
-// (or demonstrating) qunit+backbone interactions.
-
-/* global QUnit */
-import jQuery from "jquery";
-import sinon from "sinon";
-import metrics from "utils/metrics-logger";
-import testApp from "../test-app";
-
-var MockConsole = function () {
- var self = this;
- self.lastMessage = null;
- ["log", "debug", "info", "warn", "error"].forEach(function (fnName) {
- self[fnName] = function () {
- var args = Array.prototype.slice.call(arguments, 0);
- self.lastMessage = { level: fnName, args: args };
- };
- });
- return self;
-};
-
-(window.bootstrapped = {}).user = {
- id: "test",
-};
-
-QUnit.module("Metrics logger tests", {
- beforeEach: function () {
- testApp.create();
- },
- afterEach: function () {
- testApp.destroy();
- },
-});
-
-// ======================================================================== MetricsLogger
-QUnit.test("logger construction/initializiation defaults", function (assert) {
- var logger = new metrics.MetricsLogger({});
- assert.equal(logger.consoleLogger, null);
- assert.equal(logger.options.logLevel, metrics.MetricsLogger.NONE);
- assert.equal(logger.options.consoleLevel, metrics.MetricsLogger.NONE);
- assert.equal(logger.options.defaultNamespace, "Galaxy");
- assert.equal(logger.options.clientPrefix, "client.");
- assert.equal(logger.options.postSize, 1000);
- assert.equal(logger.options.maxCacheSize, 3000);
- assert.equal(logger.options.addTime, true);
- assert.equal(logger.options.postUrl, "/api/metrics");
- assert.equal(logger.options.getPingData, undefined);
- assert.equal(logger.options.onServerResponse, undefined);
-
- assert.equal(logger._postSize, 1000);
- assert.equal(logger.cache.constructor, metrics.LoggingCache);
-});
-
-QUnit.test("_parseLevel", function (assert) {
- var logger = new metrics.MetricsLogger({});
- assert.equal(logger._parseLevel("all"), metrics.MetricsLogger.ALL);
- assert.equal(logger._parseLevel("debug"), metrics.MetricsLogger.DEBUG);
- assert.equal(logger._parseLevel("info"), metrics.MetricsLogger.INFO);
- assert.equal(logger._parseLevel("warn"), metrics.MetricsLogger.WARN);
- assert.equal(logger._parseLevel("error"), metrics.MetricsLogger.ERROR);
- assert.equal(logger._parseLevel("metric"), metrics.MetricsLogger.METRIC);
- assert.equal(logger._parseLevel("none"), metrics.MetricsLogger.NONE);
- assert.equal(logger._parseLevel(15), 15);
-
- assert.throws(
- function () {
- logger._parseLevel(undefined);
- },
- /Unknown log level/,
- "Unknown log level throws error"
- );
- assert.throws(
- function () {
- logger._parseLevel("nope");
- },
- /Unknown log level/,
- "Unknown log level throws error"
- );
-});
-
-// ------------------------------------------------------------------------ Emit to cache
-QUnit.test("emit to cache at level", function (assert) {
- var logger = new metrics.MetricsLogger({
- logLevel: "metric",
- });
- logger.cache.empty();
-
- assert.equal(logger.options.logLevel, metrics.MetricsLogger.METRIC);
- logger.emit("metric", "test", [1, 2, { three: 3 }]);
- assert.equal(logger.cache.length(), 1);
-
- var cached = logger.cache.get(1)[0];
- //console.debug( 'cached:', JSON.stringify( cached ) );
- assert.equal(cached.level, metrics.MetricsLogger.METRIC);
- assert.equal(cached.namespace, "client.test");
- assert.equal(cached.args.length, 3);
- assert.equal(cached.args[2].three, 3);
- assert.ok(typeof cached.time === "string");
- assert.ok(cached.time === new Date(cached.time).toISOString());
-});
-
-QUnit.test("emit to cache below does not cache", function (assert) {
- var logger = new metrics.MetricsLogger({
- logLevel: "metric",
- });
- logger.cache.empty();
-
- logger.emit("error", "test", [1, 2, { three: 3 }]);
- assert.equal(logger.cache.length(), 0);
-});
-
-QUnit.test("emit to cache (silently) drops non-parsable", function (assert) {
- var logger = new metrics.MetricsLogger({
- logLevel: "metric",
- });
- logger.cache.empty();
-
- logger.emit("metric", "test", [{ window: window }]);
- assert.equal(logger.cache.length(), 0);
-});
-
-function metricsFromRequestBody(request) {
- // assumes 'metrics' is only entry in requestBody
- return JSON.parse(decodeURIComponent(request.requestBody.replace("metrics=", "")));
-}
-
-QUnit.test("_postCache success", function (assert) {
- var callback = sinon.spy(),
- logger = new metrics.MetricsLogger({
- logLevel: "metric",
- onServerResponse: function (response) {
- callback();
- },
- });
- logger.cache.empty();
-
- var server = sinon.fakeServer.create(),
- metricsOnServer;
- server.respondWith("POST", "/api/metrics", function (request) {
- metricsOnServer = metricsFromRequestBody(request);
- //console.debug( 'requestBody:', request.requestBody );
- //console.debug( 'metricsOnServer:', JSON.stringify( metricsOnServer, null, ' ' ) );
- request.respond(
- 200,
- { "Content-Type": "application/json" },
- JSON.stringify({
- fakeResponse: "yes",
- })
- );
- });
-
- logger.emit("metric", "test", [1, 2, { three: 3 }]);
- logger._postCache();
- server.respond();
-
- assert.ok(callback.calledOnce, "onServerResponse was called");
- assert.equal(logger.cache.length(), 0, "should have emptied cache (on success)");
- assert.equal(logger._postSize, 1000, "_postSize still at default");
-
- // metrics were in proper form on server
- assert.equal(metricsOnServer.length, 1);
- var metric = metricsOnServer[0];
- assert.equal(metric.level, metrics.MetricsLogger.METRIC);
- assert.equal(metric.namespace, "client.test");
- assert.equal(metric.args.length, 3);
- assert.equal(metric.args[2].three, 3);
- assert.ok(typeof metric.time === "string");
- assert.ok(metric.time === new Date(metric.time).toISOString());
-
- server.restore();
-});
-
-QUnit.test("_postCache failure", function (assert) {
- var callback = sinon.spy(),
- logger = new metrics.MetricsLogger({
- logLevel: "metric",
- onServerResponse: function (response) {
- callback();
- },
- });
- logger.cache.empty();
-
- var server = sinon.fakeServer.create();
- server.respondWith("POST", "/api/metrics", function (request) {
- request.respond(
- 500,
- { "Content-Type": "application/json" },
- JSON.stringify({
- err_msg: "NoooOPE!",
- })
- );
- });
-
- logger.emit("metric", "test", [1, 2, { three: 3 }]);
- logger._postCache();
- server.respond();
- //TODO: is the following what we want?
- assert.ok(!callback.calledOnce, "onServerResponse was NOT called");
- assert.equal(logger.cache.length(), 1, "should NOT have emptied cache");
- assert.equal(logger._postSize, logger.options.maxCacheSize, "_postSize changed to max");
-
- server.restore();
-});
-
-// ------------------------------------------------------------------------ Emit to console
-QUnit.test("emit to console at level", function (assert) {
- var mockConsole = new MockConsole(),
- logger = new metrics.MetricsLogger({
- consoleLevel: "debug",
- consoleLogger: mockConsole,
- });
- assert.equal(logger.options.consoleLevel, metrics.MetricsLogger.DEBUG);
- assert.equal(logger.consoleLogger.constructor, MockConsole);
-
- logger.emit("debug", "test", [1, 2, { three: 3 }]);
- assert.equal(logger.cache.length(), 1);
- //console.debug( JSON.stringify( mockConsole.lastMessage ) );
- assert.equal(mockConsole.lastMessage.level, "debug");
- assert.equal(mockConsole.lastMessage.args.length, 4);
- assert.equal(mockConsole.lastMessage.args[0], "test");
- assert.equal(mockConsole.lastMessage.args[3].three, 3);
-});
-
-QUnit.test("emit to console below does not output", function (assert) {
- var mockConsole = new MockConsole(),
- logger = new metrics.MetricsLogger({
- consoleLevel: "error",
- consoleLogger: mockConsole,
- });
- logger.emit("debug", "test", [1, 2, { three: 3 }]);
- assert.equal(mockConsole.lastMessage, null);
-});
-
-// ------------------------------------------------------------------------ Shortcuts
-QUnit.test("logger shortcuts emit to default namespace properly", function (assert) {
- var logger = new metrics.MetricsLogger({
- logLevel: "all",
- });
- logger.cache.empty();
-
- assert.equal(logger.options.logLevel, metrics.MetricsLogger.ALL);
- logger.log(0);
- logger.debug(1);
- logger.info(2);
- logger.warn(3);
- logger.error(4);
- logger.metric(5);
-
- assert.equal(logger.cache.length(), 6);
- var cached = logger.cache.remove(6),
- entry;
-
- cached.forEach(function (entry) {
- assert.ok(entry.namespace === logger.options.clientPrefix + logger.options.defaultNamespace);
- assert.ok(jQuery.type(entry.args) === "array");
- assert.ok(typeof entry.time === "string");
- });
-
- // log is different
- entry = cached[0];
- assert.ok(entry.level === 1);
- assert.ok(entry.args[0] === 0);
-
- ["debug", "info", "warn", "error", "metric"].forEach(function (level, i) {
- entry = cached[i + 1];
- assert.ok(entry.level === logger._parseLevel(level));
- assert.ok(entry.args[0] === i + 1);
- });
-});
-
-// ======================================================================== LoggingCache
-QUnit.test("cache construction/initializiation defaults", function (assert) {
- // use empty to prevent tests stepping on one another due to persistence
- var cache = new metrics.LoggingCache({ key: "logs-test" }).empty();
- assert.equal(cache.maxSize, 5000);
- assert.equal(window.localStorage.getItem("logs-test"), "[]");
-});
-
-QUnit.test("cache construction/initializiation failure", function (assert) {
- ////TODO: doesn't work - readonly
- //window.localStorage = null;
- //console.debug( 'localStorage:', window.localStorage );
- var oldFn = metrics.LoggingCache.prototype._hasStorage;
- metrics.LoggingCache.prototype._hasStorage = function () {
- return false;
- };
- assert.throws(
- function () {
- return new metrics.LoggingCache({ key: "logs-test" });
- },
- /LoggingCache needs localStorage/,
- "lack of localStorage throws error"
- );
- metrics.LoggingCache.prototype._hasStorage = oldFn;
-
- assert.throws(
- function () {
- return new metrics.LoggingCache();
- },
- /LoggingCache needs key for localStorage/,
- "lack of key throws error"
- );
-});
-
-QUnit.test("cache construction/initializiation setting max cache size", function (assert) {
- var cache = new metrics.LoggingCache({
- key: "logs-test",
- maxSize: 5,
- }).empty();
- assert.equal(cache.maxSize, 5);
-});
-
-QUnit.test("cache plays well with no data", function (assert) {
- var cache = new metrics.LoggingCache({ key: "logs-test" }).empty();
-
- assert.equal(cache.length(), 0);
- var get = cache.get(10);
- assert.ok(jQuery.type(get) === "array" && get.length === 0);
- var remove = cache.remove(10);
- assert.ok(jQuery.type(remove) === "array" && remove.length === 0);
- assert.equal(cache.length(), 0);
-});
-
-QUnit.test("cache add properly adds and removes data", function (assert) {
- var cache = new metrics.LoggingCache({
- key: "logs-test",
- maxSize: 5,
- }).empty();
-
- var entry1 = [{ one: 1 }, "two"];
- cache.add(entry1);
-
- assert.equal(cache.length(), 1);
- assert.equal(JSON.stringify(cache.get(1)[0]), JSON.stringify(entry1));
-
- var entry2 = { blah: { one: 1 }, bler: ["three", { two: 2 }] };
- cache.add(entry2);
- assert.equal(cache.length(), 2);
- assert.equal(cache.stringify(2), "[" + JSON.stringify(entry1) + "," + JSON.stringify(entry2) + "]");
-
- // FIFO
- var returned = cache.remove(1);
- assert.equal(cache.length(), 1);
- assert.ok(jQuery.type(returned) === "array" && returned.length === 1);
- var returned0 = returned[0];
- assert.ok(jQuery.type(returned0) === "array" && JSON.stringify(returned0) === JSON.stringify(entry1));
-});
-
-QUnit.test("cache past max loses oldest", function (assert) {
- var cache = new metrics.LoggingCache({
- key: "logs-test",
- maxSize: 5,
- }).empty();
-
- for (var i = 0; i < 10; i += 1) {
- cache.add({ index: i });
- }
- assert.equal(cache.length(), 5);
- var get = cache.get(5);
- assert.ok(get[0].index === 5);
- assert.ok(get[1].index === 6);
- assert.ok(get[2].index === 7);
- assert.ok(get[3].index === 8);
- assert.ok(get[4].index === 9);
-});
-
-QUnit.test("cache is properly persistent", function (assert) {
- var cache1 = new metrics.LoggingCache({ key: "logs-test" }).empty(),
- entry = [{ one: 1 }, "two"];
- cache1.add(entry);
- assert.equal(cache1.length(), 1);
-
- var cache2 = new metrics.LoggingCache({ key: "logs-test" });
- assert.equal(cache2.length(), 1, "old key gets previously stored");
- assert.equal(JSON.stringify(cache2.get(1)[0]), JSON.stringify(entry));
-
- var cache3 = new metrics.LoggingCache({ key: "logs-bler" });
- assert.equal(cache3.length(), 0, "new key causes new storage");
-});
diff --git a/client/tests/qunit/tests/modal_tests.js b/client/tests/qunit/tests/modal_tests.js
deleted file mode 100644
index b7d3ed7ed90..00000000000
--- a/client/tests/qunit/tests/modal_tests.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/* global QUnit */
-import $ from "jquery";
-import testApp from "../test-app";
-import GalaxyModal from "mvc/ui/ui-modal";
-
-QUnit.module("Modal dialog test", {
- beforeEach: function () {
- $.fx.off = true;
- testApp.create();
- var self = this;
- this.app = new GalaxyModal.View({
- title: "Test title",
- body: "Test body",
- buttons: {
- Ok: function () {},
- Cancel: function () {
- self.app.hide();
- },
- },
- });
- },
- afterEach: function () {
- $.fx.off = false;
- testApp.destroy();
- this.app.$el.remove();
- },
-});
-
-QUnit.test("test dialog attributes", function (assert) {
- assert.ok(this.app.$header.find(".title").html() == "Test title", "Modal header has correct title.");
- assert.ok(this.app.$body.html() == "Test body", "Modal header has correct body.");
-});
-
-QUnit.test("test dialog visibility", function (assert) {
- this.app.hide();
- assert.ok(this.app.$el.css("display") == "none", "Modal hidden manually");
- this.app.show();
- assert.ok(this.app.$el.css("display") == "block", "Modal shown manually");
- this.app.getButton("Ok").trigger("click");
- assert.ok(this.app.$el.css("display") == "block", "Modal still visible after clicking Ok");
- this.app.getButton("Cancel").trigger("click");
- assert.ok(this.app.$el.css("display") == "none", "Modal hidden after clicking Cancel");
- this.app.show();
- assert.ok(this.app.$el.css("display") == "block", "Modal manually shown again");
- assert.ok(!this.app.$header.hasClass("no-separator"), "Title separator tagged as visible.");
- this.app.show({ title_separator: false });
- assert.ok(this.app.$header.hasClass("no-separator"), "Title separator tagged as hidden.");
- assert.ok(this.app.$backdrop.hasClass("in"), "Backdrop tagged as shown.");
- this.app.show({ backdrop: false });
- assert.ok(!this.app.$backdrop.hasClass("in"), "Backdrop tagged as hidden.");
-});
-
-QUnit.test("test dialog closing events", function (assert) {
- this.app.show();
- this.app.$backdrop.trigger("click");
- assert.ok(this.app.$el.css("display") == "block", "Modal shown after backdrop click");
- this.app.hide();
- this.app.show({ closing_events: true });
- assert.ok(this.app.$el.css("display") == "block", "Modal shown with closing events");
- this.app.$backdrop.trigger("click");
- assert.ok(this.app.$el.css("display") == "none", "Modal hidden after backdrop click");
-});
-
-QUnit.test("test dialog rendering", function (assert) {
- var before = this.app.$el.html();
- this.app.render();
- assert.ok(before == this.app.$el.html(), "Re-rendering successful");
- this.app.options.title = "New Title";
- this.app.render();
- assert.ok(this.app.$header.find(".title").html() == "New Title", "Modal header has correct new title.");
-});
-
-QUnit.test("test button states", function (assert) {
- assert.ok(this.app.getButton("Ok").html() === "Ok", "Ok has correct label");
- assert.ok(!this.app.getButton("Ok").prop("disabled"), "Ok is active");
- assert.ok(!this.app.getButton("Cancel").prop("disabled"), "Cancel is active");
- this.app.disableButton("Ok");
- assert.ok(this.app.getButton("Ok").prop("disabled"), "Ok is disabled");
- assert.ok(!this.app.getButton("Cancel").prop("disabled"), "Cancel is still active");
- this.app.disableButton("Cancel");
- assert.ok(this.app.getButton("Cancel").prop("disabled"), "Cancel is also disabled");
- assert.ok(this.app.getButton("Ok").prop("disabled"), "Ok is still disabled");
- this.app.enableButton("Ok");
- assert.ok(this.app.getButton("Cancel").prop("disabled"), "Cancel is still disabled");
- assert.ok(!this.app.getButton("Ok").prop("disabled"), "Ok is active again");
-});
diff --git a/client/tests/qunit/tests/ui_tests.js b/client/tests/qunit/tests/ui_tests.js
deleted file mode 100644
index 92905554f21..00000000000
--- a/client/tests/qunit/tests/ui_tests.js
+++ /dev/null
@@ -1,896 +0,0 @@
-/* global QUnit */
-import $ from "jquery";
-import testApp from "../test-app";
-import sinon from "sinon";
-import Ui from "mvc/ui/ui-misc";
-import SelectContent from "mvc/ui/ui-select-content";
-import Drilldown from "mvc/ui/ui-drilldown";
-import Tabs from "mvc/ui/ui-tabs";
-
-QUnit.module("Ui test", {
- beforeEach: function () {
- testApp.create();
- this.clock = sinon.useFakeTimers();
- },
- afterEach: function () {
- testApp.destroy();
- this.clock.restore();
- },
-});
-
-QUnit.test("tabs", function (assert) {
- assert.ok($.fn);
- var self = this;
- var tabs = new Tabs.View({});
- var collection = tabs.collection;
- collection.add({ id: "id_a", title: "title_a", icon: "icon_a", $el: "el_a" });
- var _test = function () {
- self.clock.tick(window.WAIT_FADE);
- collection.each(function (model, index) {
- var $tab_element = tabs.$("#tab-" + model.id + " .nav-link");
- var $tab_content = tabs.$("#" + model.id);
- var is_current = model.id == tabs.model.get("current");
- assert.ok($tab_content.hasClass("active") == is_current, "Active state of content.");
- assert.ok($tab_element.hasClass("active") == is_current, "Active state of element.");
- });
- };
- $("body").prepend(tabs.$el);
- _test();
- collection.add({ id: "id_b", title: "title_b", icon: "icon_b", $el: "el_b" });
- _test();
- tabs.collection.get("id_b").set("hidden", true);
- _test();
- collection.add({ id: "id_c", title: "title_c", icon: "icon_c", $el: "el_c" });
- tabs.model.set("current", "id_c");
- _test();
- tabs.collection.get("id_b").set("hidden", false);
- _test();
- tabs.model.set("current", "id_b");
- _test();
- tabs.model.set("visible", false);
- tabs.collection.reset();
- self.clock.tick(window.WAIT_FADE);
- assert.ok(tabs.$el.css("display", "none"), "Everything hidden.");
- tabs.model.set("visible", true);
- self.clock.tick(window.WAIT_FADE);
- assert.ok(tabs.$el.css("display", "block"), "Everything shown.");
- collection.add({ id: "id_c", title: "title_c", icon: "icon_c", $el: "el_c" });
- tabs.model.set("current", "id_c");
- _test();
-});
-
-QUnit.test("button-default", function (assert) {
- var button = new Ui.Button({ title: "title" });
- var model = button.model;
- $("body").prepend(button.$el);
- assert.ok(button.$title.html() == "title", "Has correct title");
- model.set("title", "_title");
- assert.ok(button.$title.html() == "_title", "Has correct new title");
- assert.ok(!button.$el.attr("disabled"), "Button active");
- model.set("disabled", true);
- assert.ok(button.$el.attr("disabled"), "Button disabled");
- model.set("disabled", false);
- assert.ok(!button.$el.attr("disabled"), "Button active, again");
- model.set("wait", true);
- assert.ok(button.$title.html() == model.get("wait_text"), "Shows correct wait text");
- model.set("wait_text", "wait_text");
- assert.ok(button.$title.html() == "wait_text", "Shows correct new wait text");
- model.set("wait", false);
- assert.ok(button.$title.html() == model.get("title"), "Shows correct regular title");
-});
-
-QUnit.test("button-default", function (assert) {
- var button = new Ui.Button({ title: "title" });
- var model = button.model;
- $("body").prepend(button.$el);
- assert.ok(button.$title.html() == "title", "Has correct title");
- model.set("title", "_title");
- assert.ok(button.$title.html() == "_title", "Has correct new title");
- assert.ok(!button.$el.attr("disabled"), "Button active");
- model.set("disabled", true);
- assert.ok(button.$el.attr("disabled"), "Button disabled");
- model.set("disabled", false);
- assert.ok(!button.$el.attr("disabled"), "Button active, again");
- model.set("wait", true);
- assert.ok(button.$title.html() == model.get("wait_text"), "Shows correct wait text");
- model.set("wait_text", "wait_text");
- assert.ok(button.$title.html() == "wait_text", "Shows correct new wait text");
- model.set("wait", false);
- assert.ok(button.$title.html() == model.get("title"), "Shows correct regular title");
-});
-
-QUnit.test("button-check", function (assert) {
- var button = new Ui.ButtonCheck({ title: "title" });
- var model = button.model;
- $("body").prepend(button.$el);
- assert.ok(button.$title.html() == "title", "Has correct title");
- model.set("title", "_title");
- assert.ok(button.$title.html() == "_title", "Has correct new title");
- assert.ok(button.$icon.hasClass(button.model.get("icons")[0]), "Has correct " + model.get("value") + " value");
- button.value(1);
- assert.ok(button.$icon.hasClass(button.model.get("icons")[1]), "Has correct " + model.get("value") + " value");
- button.value(2);
- assert.ok(button.$icon.hasClass(button.model.get("icons")[2]), "Has correct " + model.get("value") + " value");
- button.value(0, 100);
- assert.ok(
- button.$icon.hasClass(button.model.get("icons")[0]),
- "Has correct " + model.get("value") + " value after fraction"
- );
- button.value(10, 100);
- assert.ok(
- button.$icon.hasClass(button.model.get("icons")[1]),
- "Has correct " + model.get("value") + " value after fraction"
- );
- button.value(100, 100);
- assert.ok(
- button.$icon.hasClass(button.model.get("icons")[2]),
- "Has correct " + model.get("value") + " value after fraction"
- );
- button.$el.trigger("click");
- assert.ok(
- button.$icon.hasClass(button.model.get("icons")[0]),
- "Has correct " + model.get("value") + " value after click"
- );
- button.$el.trigger("click");
- assert.ok(
- button.$icon.hasClass(button.model.get("icons")[2]),
- "Has correct " + model.get("value") + " value after click"
- );
- button.$el.trigger("click");
- assert.ok(
- button.$icon.hasClass(button.model.get("icons")[0]),
- "Has correct " + model.get("value") + " value after click"
- );
-});
-
-QUnit.test("options", function (assert) {
- function _test(obj, options) {
- assert.ok(JSON.stringify(obj.value()) == JSON.stringify(options.value), "Selected value is " + options.value);
- assert.ok(
- obj.$menu.css("display") == (options.menu_visible ? "block" : "none"),
- "Menu visibility: " + options.menu_visible
- );
- assert.ok(
- obj.$message.css("display") == (options.message_visible ? "block" : "none"),
- "Message visibility: " + options.message_visible
- );
- assert.ok(
- obj.$options.css("display") == (options.options_visible ? "inline-block" : "none"),
- "Options visibility: " + options.options_visible
- );
- options.message_cls &&
- assert.ok(obj.$message.hasClass(options.message_cls), "Message has class: " + options.message_cls);
- assert.ok(obj.length() === options.length, "Number of options: " + options.length);
- options.message_text &&
- assert.ok(obj.$message.html() === options.message_text, "Message text is: " + options.message_text);
- options.first && assert.ok(obj.first() === options.first, "First value is: " + options.first);
- options.all_icon &&
- assert.ok(
- obj.all_button.$(".icon").hasClass(options.all_icon),
- "All button in correct state: " + options.all_icon
- );
- assert.ok(
- obj.$menu.find(".ui-button-check").length === (options.all_icon ? 1 : 0),
- "All button available: " + Boolean(options.all_active)
- );
- }
-
- var radio = new Ui.Radio.View({});
- $("body").prepend(radio.$el);
- radio.model.set("visible", false);
- assert.ok(radio.value() === null, "Initial value is `null`.");
- assert.ok(radio.$el.css("display") === "none", "Options hidden.");
- radio.model.set("visible", true);
- assert.ok(radio.$el.css("display") === "block", "Options shown.");
- radio.model.set("value", "Unavailable.");
- assert.ok(radio.value() === null, "Unavailable value ignored.");
- _test(radio, {
- menu_visible: false,
- message_visible: true,
- message_text: "No options available.",
- message_cls: "alert-danger",
- options_visible: false,
- value: null,
- length: 0,
- });
- radio.model.set("wait", true);
- _test(radio, {
- menu_visible: false,
- message_visible: true,
- message_text: "Please wait...",
- message_cls: "alert-info",
- options_visible: false,
- value: null,
- length: 0,
- });
- radio.model.set("wait", false);
- _test(radio, {
- menu_visible: false,
- message_visible: true,
- message_text: "No options available.",
- message_cls: "alert-danger",
- options_visible: false,
- value: null,
- length: 0,
- });
- radio.model.set("data", [
- { value: "valuea", label: "labela" },
- { value: "valueb", label: "labelb" },
- ]);
- _test(radio, {
- menu_visible: true,
- message_visible: false,
- options_visible: true,
- value: "valuea",
- first: "valuea",
- length: 2,
- });
- radio.model.set("value", "valueb");
- _test(radio, {
- menu_visible: true,
- message_visible: false,
- options_visible: true,
- value: "valueb",
- first: "valuea",
- length: 2,
- });
- radio.model.set("data", null);
- _test(radio, {
- menu_visible: false,
- message_visible: true,
- message_text: "No options available.",
- message_cls: "alert-danger",
- options_visible: false,
- value: null,
- first: null,
- length: 0,
- });
- radio.model.set("data", [
- { value: "valuea", label: "labela" },
- { value: "valueb", label: "labelb" },
- { value: "valuec", label: "labelc" },
- ]);
- _test(radio, {
- menu_visible: true,
- message_visible: false,
- options_visible: true,
- value: "valueb",
- first: "valuea",
- length: 3,
- });
- radio.$("input").last().click();
- _test(radio, {
- menu_visible: true,
- message_visible: false,
- options_visible: true,
- value: "valuec",
- first: "valuea",
- length: 3,
- });
-
- var check = new Ui.Checkbox.View({});
- $("body").prepend(check.$el);
- _test(check, {
- menu_visible: false,
- message_visible: true,
- message_text: "No options available.",
- message_cls: "alert-danger",
- options_visible: false,
- value: null,
- length: 0,
- all_icon: "fa-square-o",
- });
- check.model.set("data", [
- { value: "valuea", label: "labela" },
- { value: "valueb", label: "labelb" },
- { value: "valuec", label: "labelc" },
- ]);
- _test(check, {
- menu_visible: true,
- message_visible: false,
- options_visible: true,
- value: null,
- length: 3,
- all_icon: "fa-square-o",
- });
- check.model.set("value", ["valuea", "valuec"]);
- _test(check, {
- menu_visible: true,
- message_visible: false,
- options_visible: true,
- value: ["valuea", "valuec"],
- length: 3,
- all_icon: "fa-minus-square-o",
- });
- check.model.set("value", ["valuea", "valueb", "valuec"]);
- _test(check, {
- menu_visible: true,
- message_visible: false,
- options_visible: true,
- value: ["valuea", "valueb", "valuec"],
- length: 3,
- all_icon: "fa-check-square-o",
- });
- check.model.set("data", []);
- _test(check, {
- menu_visible: false,
- message_visible: true,
- options_visible: false,
- value: null,
- length: 0,
- all_icon: "fa-square-o",
- });
- check.model.set("data", [
- { value: "valuea", label: "labela" },
- { value: "valueb", label: "labelb" },
- ]);
- _test(check, {
- menu_visible: true,
- message_visible: false,
- options_visible: true,
- value: ["valuea", "valueb"],
- first: "valuea",
- length: 2,
- all_icon: "fa-check-square-o",
- });
- check.all_button.$el.click();
- _test(check, {
- menu_visible: true,
- message_visible: false,
- options_visible: true,
- value: null,
- first: "valuea",
- length: 2,
- all_icon: "fa-square-o",
- });
- check.all_button.$el.click();
- _test(check, {
- menu_visible: true,
- message_visible: false,
- options_visible: true,
- value: ["valuea", "valueb"],
- first: "valuea",
- length: 2,
- all_icon: "fa-check-square-o",
- });
- check.$("input").last().click();
- _test(check, {
- menu_visible: true,
- message_visible: false,
- options_visible: true,
- value: ["valuea"],
- first: "valuea",
- length: 2,
- all_icon: "fa-minus-square-o",
- });
- check.$("input").last().click();
- _test(check, {
- menu_visible: true,
- message_visible: false,
- options_visible: true,
- value: ["valuea", "valueb"],
- first: "valuea",
- length: 2,
- all_icon: "fa-check-square-o",
- });
-
- var radiobutton = new Ui.RadioButton.View({});
- $("body").prepend(radiobutton.$el);
- radiobutton.model.set("data", [
- { value: "valuea", label: "labela" },
- { value: "valueb", label: "labelb" },
- ]);
- _test(radiobutton, {
- menu_visible: true,
- message_visible: false,
- options_visible: true,
- value: "valuea",
- first: "valuea",
- length: 2,
- });
- radiobutton.$("input").last().click();
- _test(radiobutton, {
- menu_visible: true,
- message_visible: false,
- options_visible: true,
- value: "valueb",
- first: "valuea",
- length: 2,
- });
-
- var drilldown = new Drilldown.View({});
- $("body").prepend(drilldown.$el);
- drilldown.model.set("data", [
- {
- value: "valuea",
- name: "labela",
- options: [
- { value: "valueb", name: "labelb" },
- { value: "valuec", name: "labelc" },
- {
- value: "valued",
- name: "labeld",
- options: [
- { value: "valuee", name: "labele" },
- { value: "valuef", name: "labelf" },
- ],
- },
- ],
- },
- {
- value: "valueg",
- name: "labelg",
- options: [
- { value: "valueh", name: "labelh" },
- { value: "valuei", name: "labeli" },
- {
- value: "valuej",
- name: "labelj",
- options: [
- { value: "valuek", name: "labelk" },
- { value: "valuel", name: "labell" },
- { value: "valuem", name: "labelm" },
- ],
- },
- ],
- },
- { value: "valuen", name: "labeln" },
- ]);
- _test(drilldown, {
- menu_visible: true,
- message_visible: false,
- options_visible: true,
- value: null,
- first: "valuea",
- length: 14,
- all_icon: "fa-square-o",
- });
- drilldown.model.set("value", ["valuek", "valuen"]);
- _test(drilldown, {
- menu_visible: true,
- message_visible: false,
- options_visible: true,
- value: ["valuek", "valuen"],
- first: "valuea",
- length: 14,
- all_icon: "fa-minus-square-o",
- });
- var drillradio = new Drilldown.View({ display: "radio" });
- $("body").prepend(drillradio.$el);
- _test(drillradio, {
- menu_visible: false,
- message_visible: true,
- options_visible: false,
- value: null,
- length: 0,
- });
- drillradio.model.set("data", drilldown.model.get("data"));
- _test(drillradio, {
- menu_visible: true,
- message_visible: false,
- options_visible: true,
- value: "valuea",
- first: "valuea",
- length: 14,
- });
-});
-
-QUnit.test("select-default", function (assert) {
- function _test(options) {
- assert.ok(
- JSON.stringify(select.value()) == JSON.stringify(options.value),
- "Selected value is " + options.value
- );
- assert.ok(select.text() == options.label, "Selected label is " + options.label);
- assert.ok(select.$el.display === options.visible ? "block" : "none", options.visible ? "Visible" : "Hidden");
- assert.ok(select.data.length === options.count && select.length(), "Found " + options.count + " option");
- options.exists && assert.ok(select.exists(options.exists), "Found value: " + options.exists);
- assert.ok(
- select.$select.prop("multiple") === Boolean(options.multiple),
- "Multiple state set to: " + options.multiple
- );
- assert.ok(Boolean(select.all_button) === Boolean(options.multiple), "Visiblity of select all button correct.");
- options.multiple &&
- assert.ok(
- select.all_button.$(".icon").hasClass(options.all_icon),
- "All button in correct state: " + options.all_icon
- );
- }
- var select = new Ui.Select.View({});
- $("body").prepend(select.$el);
- assert.ok(select.first() === "__null__", "First select is '__null__'");
- assert.ok(select.$dropdown.hasClass("fa-caret-down"), "Caret down shown.");
- select.model.set("data", [{ value: "value", label: "label" }]);
- _test({
- value: "value",
- label: "label",
- visible: true,
- count: 1,
- });
- select.model.set("data", [
- { value: "valuea", label: "labela" },
- { value: "valueb", label: "labelb" },
- ]);
- _test({
- value: "valuea",
- label: "labela",
- visible: true,
- count: 2,
- exists: "valueb",
- });
- select.value("valueb");
- _test({
- value: "valueb",
- label: "labelb",
- visible: true,
- count: 2,
- });
- select.model.set("data", [{ value: "value", label: "label" }]);
- _test({
- value: "value",
- label: "label",
- visible: true,
- count: 1,
- });
- select.model.set({ visible: false, value: "unavailable" });
- _test({
- value: "value",
- label: "label",
- visible: false,
- count: 1,
- });
- select.model.set({
- visible: true,
- value: "valueb",
- data: [
- { value: "valuea", label: "labela" },
- { value: "valueb", label: "labelb" },
- ],
- });
- _test({
- value: "valueb",
- label: "labelb",
- visible: true,
- count: 2,
- exists: "valuea",
- });
- select.model.set({ multiple: true });
- _test({
- value: ["valueb"],
- label: "labelb",
- visible: true,
- count: 2,
- exists: "valuea",
- multiple: true,
- all_icon: "fa-minus-square-o",
- });
- select.model.set("value", ["valueb", "valuea"]);
- _test({
- value: ["valuea", "valueb"],
- label: "labela",
- visible: true,
- count: 2,
- exists: "valueb",
- multiple: true,
- all_icon: "fa-check-square-o",
- });
- select.model.set("value", []);
- _test({
- value: null,
- label: "",
- visible: true,
- count: 2,
- exists: "valuea",
- multiple: true,
- all_icon: "fa-square-o",
- });
- select.model.set({ multiple: false });
- _test({
- value: "valuea",
- label: "labela",
- visible: true,
- count: 2,
- exists: "valuea",
- });
- select.model.set({ visible: false });
- _test({
- value: "valuea",
- label: "labela",
- visible: false,
- count: 2,
- exists: "valuea",
- });
- select.model.set({
- multiple: true,
- visible: true,
- value: ["valueb", "valuec"],
- data: [
- { value: "valuea", label: "labela" },
- { value: "valueb", label: "labelb" },
- { value: "valuec", label: "labelc" },
- ],
- });
- _test({
- value: ["valueb", "valuec"],
- label: "labelb",
- visible: true,
- count: 3,
- exists: "valuea",
- multiple: true,
- all_icon: "fa-minus-square-o",
- });
-});
-
-QUnit.test("input", function (assert) {
- var input = new Ui.Input();
- $("body").prepend(input.$el);
- assert.ok(input.tagName === "input", "Created input.");
- assert.ok(input.value() === undefined, "Input empty.");
- input.model.set("value", "_value");
- assert.ok(input.$el.val() === "_value", "Input with value.");
- assert.ok(!input.$el.hasClass("_cls"), "Has no custom class.");
- input.model.set("cls", "_cls");
- assert.ok(input.$el.hasClass("_cls"), "Has custom class.");
- assert.ok(!input.$el.attr("placeholder"), "Has no placeholder");
- input.model.set("placeholder", "_placeholder");
- assert.ok(input.$el.attr("placeholder") === "_placeholder", "Has correct placeholder");
- input.model.set("disabled", true);
- assert.ok(input.$el.attr("disabled"), "Disabled");
- input.model.set("disabled", false);
- assert.ok(!input.$el.attr("disabled"), "Enabled");
- input.model.set("visible", false);
- assert.ok(input.$el.css("display") === "none", "Hidden");
- input.model.set("visible", true);
- assert.ok(input.$el.css("display") === "inline-block", "Shown");
-});
-
-QUnit.test("textarea", function (assert) {
- var input = new Ui.Input({ area: true });
- $("body").prepend(input.$el);
- assert.ok(input.tagName === "textarea", "Created textarea.");
- assert.ok(input.value() === undefined, "Unavailable value.");
- input.model.set("value", "_value");
- assert.ok(input.value() === "_value", "Correct new value.");
- assert.ok(!input.$el.hasClass("_cls"), "Has no custom class.");
- input.model.set("cls", "_cls");
- assert.ok(input.$el.hasClass("_cls"), "Has custom class.");
-});
-
-QUnit.test("nullableText", function (assert) {
- // Start with null value, optional button should be off
- var input = new Ui.NullableText({ area: false, value: null });
- $("body").prepend(input.$el);
- assert.ok(input.text_input.tagName === "input", "input tag");
- assert.ok(input.value() === null, "null value");
- assert.ok(input.optional_button.model.get("value") === "false");
- // toggle button, will set value to `""`
- input.optional_button.model.set("value", "true");
- assert.ok(input.value() === "", "Correct new value.");
- // set value
- input.text_input.model.set("value", "_value");
- assert.ok(input.value() === "_value", "Correct new value.");
- assert.ok(input.optional_button.model.get("value") === "true");
- // toggle button to false, will reset value to null
- input.optional_button.model.set("value", "false");
- assert.ok(input.value() === null, "Correct new value.");
- assert.ok(input.optional_button.model.get("value") === "false");
- // New input, start with value, optional button should be on
- var definedInput = new Ui.NullableText({ area: false, value: "123" });
- assert.ok(definedInput.value() === "123");
- assert.ok(definedInput.optional_button.model.get("value") === "true");
-});
-
-QUnit.test("message", function (assert) {
- var message = new Ui.Message({
- persistent: true,
- message: "_message",
- status: "danger",
- });
- $("body").prepend(message.$el);
- assert.ok(message.$el.hasClass("alert-danger"), "Alert danger.");
- message.model.set("status", "info");
- assert.ok(!message.$el.hasClass("alert-danger"), "Alert danger (disabled).");
- assert.ok(message.$el.hasClass("alert-info"), "Alert info.");
- assert.ok(message.$el.html() === "_message", "Correct message.");
- message.model.set("message", "_new_message");
- assert.ok(message.$el.html() === "_new_message", "Correct new message.");
-});
-
-QUnit.test("select-content", function (assert) {
- var select = new SelectContent.View({});
- $("body").prepend(select.$el);
- var _testSelect = function (tag, options) {
- var field = select.fields[tag == "first" ? 0 : select.fields.length - 1];
- var $select = select.$(".ui-select:" + tag);
- var $button = select.$(".ui-radiobutton").find("label:" + tag);
- assert.ok(field.length() == options[tag + "length"], tag + " one has " + options[tag + "length"] + " options");
- assert.ok(field.data[0].value == options[tag + "value"], tag + " option has correct value");
- assert.ok(field.data[0].label == options[tag + "label"], tag + " option has correct label");
- assert.ok($select.hasClass("ui-select-multiple") == options[tag + "multiple"], "Check multiple option");
- $button.trigger("mouseover");
- var tooltip = $(".tooltip-inner:last").text();
- $button.trigger("mouseleave");
- assert.ok(tooltip.indexOf("dataset") != -1 || tooltip.indexOf("collection") != -1, "Basic tooltip check");
- };
- var _test = function (options) {
- assert.ok(select.button_type.$(".ui-option:first").hasClass("active"), "First one is toggled");
- assert.ok(
- select.$(".ui-select").length == options.selectfields,
- "Found " + options.selectfields + " select fields"
- );
- assert.ok(
- select.button_type.$(".ui-option").length == options.selectfields,
- "Found " + options.selectfields + " radio button options"
- );
- assert.ok(
- select.$(".ui-select-multiple").length == options.totalmultiple,
- "Contains " + options.totalmultiple + " multiselect fields"
- );
- assert.ok(
- select.$el.find(".ui-options:first .ui-option").length === options.selectfields,
- "Radio button count, expected " + options.selectfields
- );
- assert.ok(select.$(".ui-select:first").css("display") == "block", "Check select visibility");
- assert.ok(
- select.$(".ui-select:last").css("display") == (options.selectfields == 1 ? "block" : "none"),
- "Last select visibility"
- );
- assert.ok(
- (select.button_dialog.$el.css("display") != "none") === options.showdialog,
- "Data dialog button visible"
- );
- _testSelect("first", options);
- _testSelect("last", options);
- };
-
- assert.ok(select.button_type.value() == 0, "Initial mode selected by default.");
- select.model.set("data", {
- hda: [
- { id: "id0", name: "name0", hid: "hid0" },
- { id: "id1", name: "name1", hid: "hid1" },
- ],
- hdca: [
- { id: "id2", name: "name2", hid: "hid2" },
- { id: "id3", name: "name3", hid: "hid3" },
- { id: "id4", name: "name4", hid: "hid4" },
- ],
- });
-
- var initial = {
- selectfields: 3,
- firstlength: 2,
- firstvalue: "id0",
- firstlabel: "hid0: name0",
- firstmultiple: false,
- totalmultiple: 1,
- lastvalue: "id2",
- lastlabel: "hid2: name2",
- lastlength: 3,
- lastmultiple: false,
- showdialog: true,
- };
- _test(initial);
-
- select.model.set("multiple", true);
- select.model.set("type", "data");
- _test({
- selectfields: 2,
- firstlength: 2,
- firstvalue: "id0",
- firstlabel: "hid0: name0",
- firstmultiple: true,
- totalmultiple: 2,
- lastvalue: "id2",
- lastlabel: "hid2: name2",
- lastlength: 3,
- lastmultiple: true,
- showdialog: true,
- });
-
- select.model.set("multiple", false);
- select.model.set("type", "data_collection");
- _test({
- selectfields: 1,
- firstlength: 3,
- firstvalue: "id2",
- firstlabel: "hid2: name2",
- firstmultiple: false,
- totalmultiple: 0,
- lastvalue: "id2",
- lastlabel: "hid2: name2",
- lastlength: 3,
- lastmultiple: false,
- showdialog: false,
- });
-
- select.model.set("type", "module_data_collection");
- _test({
- selectfields: 2,
- firstlength: 3,
- firstvalue: "id2",
- firstlabel: "hid2: name2",
- firstmultiple: false,
- totalmultiple: 1,
- lastvalue: "id2",
- lastlabel: "hid2: name2",
- lastlength: 3,
- lastmultiple: true,
- showdialog: false,
- });
-
- select.model.set("type", "module_data");
- _test({
- selectfields: 2,
- firstlength: 2,
- firstvalue: "id0",
- firstlabel: "hid0: name0",
- firstmultiple: false,
- totalmultiple: 1,
- lastvalue: "id0",
- lastlabel: "hid0: name0",
- lastlength: 2,
- lastmultiple: true,
- showdialog: true,
- });
-
- select.model.set("type", "data");
- _test(initial);
-
- select.model.set("wait", true);
- assert.ok(select.$(".icon-dropdown").hasClass("fa-spinner"), "Shows spinner");
- select.model.set("wait", false);
- assert.ok(select.$(".icon-dropdown").hasClass("fa-caret-down"), "Shows caret");
- select.model.set("optional", true);
- assert.ok(select.fields[0].data[0].value == "__null__", "First option is optional value");
- select.model.set("optional", false);
- assert.ok(select.fields[0].data[0].value != "__null__", "First option is not optional value");
-
- select.model.set("value", { values: [{ id: "id1", src: "hda" }] });
- assert.ok(
- JSON.stringify(select.value()) == '{"values":[{"id":"id1","name":"name1","hid":"hid1"}],"batch":false}',
- "Checking single value"
- );
-
- assert.ok(select.config[select.model.get("current")].src == "hda", "Matched dataset field");
- assert.ok(!select.config[select.model.get("current")].multiple, "Matched single select field");
- select.model.set("value", {
- values: [
- { id: "id0", src: "hda" },
- { id: "id1", src: "hda" },
- ],
- });
- assert.ok(select.config[select.model.get("current")].multiple, "Matched multiple field");
- assert.ok(
- JSON.stringify(select.value()) ==
- '{"values":[{"id":"id0","name":"name0","hid":"hid0"},{"id":"id1","name":"name1","hid":"hid1"}],"batch":true}',
- "Checking multiple values"
- );
- select.model.set("value", { values: [{ id: "id2", src: "hdca" }] });
- assert.ok(select.config[select.model.get("current")].src == "hdca", "Matched collection field");
- assert.ok(
- JSON.stringify(select.value()) == '{"values":[{"id":"id2","name":"name2","hid":"hid2"}],"batch":true}',
- "Checking collection value"
- );
-
- select = new SelectContent.View({});
- $("body").prepend(select.$el);
- var _testEmptySelect = function (tag, txt_extension, txt_label) {
- var field = select.fields[tag == "first" ? 0 : select.fields.length - 1];
- select.$(".ui-select:" + tag);
- assert.ok(field.data[0].value == "__null__", tag + " option has correct empty value.");
- assert.ok(
- field.data[0].label == "No " + txt_extension + txt_label + " available.",
- tag + " option has correct empty label."
- );
- };
-
- var labels = select.model.get("src_labels");
- _testEmptySelect("first", "", labels.hda);
- _testEmptySelect("last", "", labels.hdca);
- select.model.set("extensions", ["txt", "bam"]);
- _testEmptySelect("first", "txt or bam ", labels.hda);
- _testEmptySelect("last", "txt or bam ", labels.hdca);
- select.model.set("extensions", ["txt"]);
- _testEmptySelect("first", "txt ", labels.hda);
- _testEmptySelect("last", "txt ", labels.hdca);
-});
diff --git a/client/tests/qunit/tests/utils_tests.js b/client/tests/qunit/tests/utils_tests.js
deleted file mode 100644
index da57e48b6c6..00000000000
--- a/client/tests/qunit/tests/utils_tests.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/* global QUnit */
-import testApp from "../test-app";
-import Utils from "utils/utils";
-
-QUnit.module("Utils test", {
- beforeEach: function () {
- testApp.create();
- },
- afterEach: function () {
- testApp.destroy();
- },
-});
-
-QUnit.test("isEmpty", function (assert) {
- assert.ok(Utils.isEmpty([]), "Empty array");
- assert.ok(Utils.isEmpty(["data", undefined]), "Array contains `undefined`");
- assert.ok(Utils.isEmpty(["data", null]), "Array contains `null`");
- assert.ok(Utils.isEmpty(["data", "__null__"]), "Array contains `__null__`");
- assert.ok(Utils.isEmpty(["data", "__undefined__"]), "Array contains `__undefined__`");
- assert.ok(Utils.isEmpty(null), "Array is null");
- assert.ok(Utils.isEmpty("__null__"), "Array is __null__");
- assert.ok(Utils.isEmpty("__undefined__"), "Array is __undefined__");
- assert.ok(!Utils.isEmpty(["data"]), "Array contains `data`");
- assert.ok(!Utils.isEmpty(1), "Value is int");
- assert.ok(!Utils.isEmpty(0), "Value is zero");
-});
diff --git a/client/tests/qunit/test-data/bootstrapped.js b/client/tests/test-data/bootstrapped.js
similarity index 100%
rename from client/tests/qunit/test-data/bootstrapped.js
rename to client/tests/test-data/bootstrapped.js
diff --git a/client/tests/qunit/test-data/json/datatypes.json b/client/tests/test-data/json/datatypes.json
similarity index 100%
rename from client/tests/qunit/test-data/json/datatypes.json
rename to client/tests/test-data/json/datatypes.json
diff --git a/client/tests/qunit/test-data/json/datatypes.mapping.json b/client/tests/test-data/json/datatypes.mapping.json
similarity index 100%
rename from client/tests/qunit/test-data/json/datatypes.mapping.json
rename to client/tests/test-data/json/datatypes.mapping.json
diff --git a/client/tests/qunit/test-data/paired-collection-creator.data.js b/client/tests/test-data/paired-collection-creator.data.js
similarity index 100%
rename from client/tests/qunit/test-data/paired-collection-creator.data.js
rename to client/tests/test-data/paired-collection-creator.data.js
diff --git a/client/webpack.config.js b/client/webpack.config.js
index f9493e6ec7c..b749fbe4a7d 100644
--- a/client/webpack.config.js
+++ b/client/webpack.config.js
@@ -7,6 +7,7 @@ const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const DuplicatePackageCheckerPlugin = require("@cerner/duplicate-package-checker-webpack-plugin");
const { DumpMetaPlugin } = require("dumpmeta-webpack-plugin");
const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");
+const TerserPlugin = require("terser-webpack-plugin");
const scriptsBase = path.join(__dirname, "src");
const testsBase = path.join(__dirname, "tests");
@@ -32,6 +33,27 @@ module.exports = (env = {}, argv = {}) => {
// environment name based on -d, -p, webpack flag
const targetEnv = process.env.NODE_ENV == "production" || argv.mode == "production" ? "production" : "development";
+ let minimizations = {};
+ if (targetEnv == "production") {
+ minimizations = {
+ minimize: true,
+ minimizer: [
+ new TerserPlugin({
+ terserOptions: {
+ compress: {
+ drop_console: true,
+ },
+ },
+ }),
+ new CssMinimizerPlugin(),
+ ],
+ };
+ } else {
+ minimizations = {
+ minimize: false,
+ };
+ }
+
const buildconfig = {
mode: targetEnv,
entry: {
@@ -84,8 +106,7 @@ module.exports = (env = {}, argv = {}) => {
},
},
},
- minimize: true,
- minimizer: [`...`, new CssMinimizerPlugin()],
+ ...minimizations,
},
module: {
rules: [
@@ -272,8 +293,8 @@ module.exports = (env = {}, argv = {}) => {
},
};
- if (process.env.GXY_BUILD_SOURCEMAPS || buildconfig.mode == "development") {
- buildconfig.devtool = "eval-cheap-source-map";
+ if (process.env.GXY_BUILD_SOURCEMAPS) {
+ buildconfig.devtool = "source-map";
}
return buildconfig;
diff --git a/client/yarn.lock b/client/yarn.lock
index b510fcdc084..024f7c381b6 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -1405,11 +1405,6 @@
"@citation-js/name" "^0.4.2"
wikidata-sdk "^8.0.0"
-"@colors/colors@1.5.0":
- version "1.5.0"
- resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz"
- integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==
-
"@discoveryjs/json-ext@^0.5.0":
version "0.5.7"
resolved "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz"
@@ -2023,11 +2018,6 @@
resolved "https://registry.npmjs.org/@types/circular-json/-/circular-json-0.4.0.tgz"
integrity sha512-7+kYB7x5a7nFWW1YPBh3KxhwKfiaI4PbZ1RvzBU91LZy7lWJO822CI+pqzSre/DZ7KsCuMKdHnLHHFu8AyXbQg==
-"@types/component-emitter@^1.2.10":
- version "1.2.11"
- resolved "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz"
- integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==
-
"@types/connect-history-api-fallback@^1.3.5":
version "1.3.5"
resolved "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz"
@@ -2043,16 +2033,6 @@
dependencies:
"@types/node" "*"
-"@types/cookie@^0.4.1":
- version "0.4.1"
- resolved "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz"
- integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==
-
-"@types/cors@^2.8.12":
- version "2.8.12"
- resolved "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz"
- integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==
-
"@types/d3-array@*":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.0.3.tgz#87d990bf504d14ad6b16766979d04e943c046dac"
@@ -2378,7 +2358,7 @@
resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c"
integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==
-"@types/node@*", "@types/node@>=10.0.0":
+"@types/node@*":
version "18.6.5"
resolved "https://registry.npmjs.org/@types/node/-/node-18.6.5.tgz"
integrity sha512-Xjt5ZGUa5WusGZJ4WJPbOT8QOqp6nDynVFRKcUt32bOgvXEoc6o085WNkYTMO7ifAj2isEfQQ2cseE+wT6jsRw==
@@ -3356,11 +3336,6 @@ base64-js@^1.3.1:
resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
-base64id@2.0.0, base64id@~2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz"
- integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==
-
base@^0.11.1:
version "0.11.2"
resolved "https://registry.npmjs.org/base/-/base-0.11.2.tgz"
@@ -3408,7 +3383,7 @@ bluebird@^3.1.1:
resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz"
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
-body-parser@1.20.0, body-parser@^1.19.0:
+body-parser@1.20.0:
version "1.20.0"
resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz"
integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==
@@ -3645,15 +3620,10 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0"
-caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001304, caniuse-lite@^1.0.30001370:
- version "1.0.30001375"
- resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001375.tgz"
- integrity sha512-kWIMkNzLYxSvnjy0hL8w1NOaWNr2rn39RTAVyIwcw8juu60bZDWiF1/loOYANzjtJmy6qPgNmn38ro5Pygagdw==
-
-caniuse-lite@^1.0.30001400:
- version "1.0.30001439"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz#ab7371faeb4adff4b74dad1718a6fd122e45d9cb"
- integrity sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==
+caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001304, caniuse-lite@^1.0.30001370, caniuse-lite@^1.0.30001400:
+ version "1.0.30001450"
+ resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001450.tgz"
+ integrity sha512-qMBmvmQmFXaSxexkjjfMvD5rnDL0+m+dUMZKoDYsGG8iZN29RuYh9eRoMvKsT6uMAWlyUUGDEQGJJYjzCIO9ew==
caniuse-lite@^1.0.30001426:
version "1.0.30001451"
@@ -3709,7 +3679,7 @@ char-regex@^1.0.2:
resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz"
integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==
-chokidar@3.5.3, "chokidar@>=3.0.0 <4.0.0", chokidar@^2.0.0, chokidar@^3.5.1, chokidar@^3.5.3:
+chokidar@3.5.3, "chokidar@>=3.0.0 <4.0.0", chokidar@^2.0.0, chokidar@^3.5.3:
version "3.5.3"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
@@ -3797,15 +3767,6 @@ cliui@^3.2.0:
strip-ansi "^3.0.1"
wrap-ansi "^2.0.0"
-cliui@^7.0.2:
- version "7.0.4"
- resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz"
- integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
- dependencies:
- string-width "^4.2.0"
- strip-ansi "^6.0.0"
- wrap-ansi "^7.0.0"
-
cliui@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa"
@@ -3946,7 +3907,7 @@ combined-stream@^1.0.8:
dependencies:
delayed-stream "~1.0.0"
-commander@7, commander@7.2.0, commander@^7.2.0:
+commander@7, commander@^7.2.0:
version "7.2.0"
resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz"
integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
@@ -3966,7 +3927,7 @@ commander@^9.4.1:
resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30"
integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==
-component-emitter@^1.2.1, component-emitter@~1.3.0:
+component-emitter@^1.2.1:
version "1.3.0"
resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz"
integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
@@ -4028,16 +3989,6 @@ connect-history-api-fallback@^2.0.0:
resolved "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz"
integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==
-connect@^3.7.0:
- version "3.7.0"
- resolved "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz"
- integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==
- dependencies:
- debug "2.6.9"
- finalhandler "1.1.2"
- parseurl "~1.3.3"
- utils-merge "1.0.1"
-
consola@^2.15.0:
version "2.15.3"
resolved "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz"
@@ -4084,11 +4035,6 @@ cookie@0.5.0:
resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
-cookie@~0.4.1:
- version "0.4.2"
- resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz"
- integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
-
copy-descriptor@^0.1.0:
version "0.1.1"
resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz"
@@ -4129,14 +4075,6 @@ core-util-is@~1.0.0:
resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz"
integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
-cors@~2.8.5:
- version "2.8.5"
- resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz"
- integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==
- dependencies:
- object-assign "^4"
- vary "^1"
-
cosmiconfig@^7.0.0:
version "7.0.1"
resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz"
@@ -4357,11 +4295,6 @@ custom-error-instance@2.1.1:
resolved "https://registry.npmjs.org/custom-error-instance/-/custom-error-instance-2.1.1.tgz"
integrity sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg==
-custom-event@~1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz"
- integrity sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==
-
"d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3, d3-array@^3.2.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.1.tgz#39331ea706f5709417d31bbb6ec152e0328b39b3"
@@ -4638,11 +4571,6 @@ date-fns@^2.28.0:
resolved "https://registry.npmjs.org/date-fns/-/date-fns-2.29.1.tgz"
integrity sha512-dlLD5rKaKxpFdnjrs+5azHDFOPEu4ANy/LTh04A1DTzMM7qoajmKCBc8pkKRFT41CNzw+4gQh79X5C+Jq27HAw==
-date-format@^4.0.13:
- version "4.0.13"
- resolved "https://registry.npmjs.org/date-format/-/date-format-4.0.13.tgz"
- integrity sha512-bnYCwf8Emc3pTD8pXnre+wfnjGtfi5ncMDKy7+cWZXbmRAsdWkOQHrfC1yz/KiwP5thDp2kCHWYWKBX4HP1hoQ==
-
de-indent@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz"
@@ -4655,7 +4583,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
dependencies:
ms "2.0.0"
-debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2:
+debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:
version "4.3.4"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@@ -4841,11 +4769,6 @@ detect-node@^2.0.4:
resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz"
integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==
-di@^0.0.1:
- version "0.0.1"
- resolved "https://registry.npmjs.org/di/-/di-0.0.1.tgz"
- integrity sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==
-
diff-sequences@^27.5.1:
version "27.5.1"
resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz"
@@ -4902,16 +4825,6 @@ dom-event-types@^1.0.0:
resolved "https://registry.npmjs.org/dom-event-types/-/dom-event-types-1.1.0.tgz"
integrity sha512-jNCX+uNJ3v38BKvPbpki6j5ItVlnSqVV6vDWGS6rExzCMjsc39frLjm1n91o6YaKK6AZl0wLloItW6C6mr61BQ==
-dom-serialize@^2.2.1:
- version "2.2.1"
- resolved "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz"
- integrity sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==
- dependencies:
- custom-event "~1.0.0"
- ent "~2.2.0"
- extend "^3.0.0"
- void-elements "^2.0.0"
-
dom-serializer@^1.0.1:
version "1.4.1"
resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz"
@@ -5054,27 +4967,6 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0:
dependencies:
once "^1.4.0"
-engine.io-parser@~5.0.3:
- version "5.0.4"
- resolved "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz"
- integrity sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==
-
-engine.io@~6.2.0:
- version "6.2.0"
- resolved "https://registry.npmjs.org/engine.io/-/engine.io-6.2.0.tgz"
- integrity sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg==
- dependencies:
- "@types/cookie" "^0.4.1"
- "@types/cors" "^2.8.12"
- "@types/node" ">=10.0.0"
- accepts "~1.3.4"
- base64id "2.0.0"
- cookie "~0.4.1"
- cors "~2.8.5"
- debug "~4.3.1"
- engine.io-parser "~5.0.3"
- ws "~8.2.3"
-
enhanced-resolve@^5.0.0, enhanced-resolve@^5.10.0:
version "5.10.0"
resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz"
@@ -5091,11 +4983,6 @@ enhanced-resolve@^5.7.0:
graceful-fs "^4.2.4"
tapable "^2.2.0"
-ent@~2.2.0:
- version "2.2.0"
- resolved "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz"
- integrity sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==
-
entities@^2.0.0:
version "2.2.0"
resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz"
@@ -5704,19 +5591,6 @@ fill-range@^7.0.1:
dependencies:
to-regex-range "^5.0.1"
-finalhandler@1.1.2:
- version "1.1.2"
- resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz"
- integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==
- dependencies:
- debug "2.6.9"
- encodeurl "~1.0.2"
- escape-html "~1.0.3"
- on-finished "~2.3.0"
- parseurl "~1.3.3"
- statuses "~1.5.0"
- unpipe "~1.0.0"
-
finalhandler@1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz"
@@ -5808,7 +5682,7 @@ flatted@^2.0.0:
resolved "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz"
integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==
-flatted@^3.1.0, flatted@^3.2.6:
+flatted@^3.1.0:
version "3.2.6"
resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz"
integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==
@@ -5881,15 +5755,6 @@ fresh@0.5.2:
resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz"
integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
-fs-extra@^8.1.0:
- version "8.1.0"
- resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz"
- integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
- dependencies:
- graceful-fs "^4.2.0"
- jsonfile "^4.0.0"
- universalify "^0.1.0"
-
fs-mkdirp-stream@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz"
@@ -6045,7 +5910,7 @@ glob-watcher@^5.0.3:
normalize-path "^3.0.0"
object.defaults "^1.1.0"
-glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.7, glob@^7.2.0, glob@~7.2.0:
+glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.2.0, glob@~7.2.0:
version "7.2.3"
resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz"
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
@@ -6100,11 +5965,6 @@ globals@^13.15.0:
dependencies:
type-fest "^0.20.2"
-globalyzer@0.1.0:
- version "0.1.0"
- resolved "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz"
- integrity sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==
-
globby@^11.0.1, globby@^11.1.0:
version "11.1.0"
resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz"
@@ -6128,11 +5988,6 @@ globby@^13.1.1:
merge2 "^1.4.1"
slash "^4.0.0"
-globrex@^0.1.2:
- version "0.1.2"
- resolved "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz"
- integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==
-
glogg@^1.0.0:
version "1.0.2"
resolved "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz"
@@ -6147,7 +6002,7 @@ gopd@^1.0.1:
dependencies:
get-intrinsic "^1.1.3"
-graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
+graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
version "4.2.10"
resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz"
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
@@ -6987,11 +6842,6 @@ isarray@^2.0.5:
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
-isbinaryfile@^4.0.8:
- version "4.0.10"
- resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz"
- integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==
-
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"
@@ -7639,13 +7489,6 @@ json5@^2.2.2:
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
-jsonfile@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz"
- integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==
- optionalDependencies:
- graceful-fs "^4.1.6"
-
jspdf@^2.5.1:
version "2.5.1"
resolved "https://registry.npmjs.org/jspdf/-/jspdf-2.5.1.tgz"
@@ -7676,62 +7519,6 @@ just-extend@^4.0.2:
resolved "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz"
integrity sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==
-karma-chrome-launcher@^3.1.0:
- version "3.1.1"
- resolved "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz"
- integrity sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ==
- dependencies:
- which "^1.2.1"
-
-karma-polyfill@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/karma-polyfill/-/karma-polyfill-1.1.0.tgz"
- integrity sha512-TGWOIeTa4VBU2Af6jp4IYbROlTH6EXqpQZt15r0TRv7AYMt03BIagj5eljZgC64Uqg11QDh09j9megr6Vmzm6g==
-
-karma-qunit@^4.1.2:
- version "4.1.2"
- resolved "https://registry.npmjs.org/karma-qunit/-/karma-qunit-4.1.2.tgz"
- integrity sha512-taTPqBeHCOlkeKTSzQgIKzAUb79vw3rfbCph+xwwh63tyGjNtljwx91VArhIM9DzIIR3gB9G214wQg+oXI9ycw==
-
-karma-webpack@^5.0.0:
- version "5.0.0"
- resolved "https://registry.npmjs.org/karma-webpack/-/karma-webpack-5.0.0.tgz"
- integrity sha512-+54i/cd3/piZuP3dr54+NcFeKOPnys5QeM1IY+0SPASwrtHsliXUiCL50iW+K9WWA7RvamC4macvvQ86l3KtaA==
- dependencies:
- glob "^7.1.3"
- minimatch "^3.0.4"
- webpack-merge "^4.1.5"
-
-karma@^6.3.16:
- version "6.4.0"
- resolved "https://registry.npmjs.org/karma/-/karma-6.4.0.tgz"
- integrity sha512-s8m7z0IF5g/bS5ONT7wsOavhW4i4aFkzD4u4wgzAQWT4HGUeWI3i21cK2Yz6jndMAeHETp5XuNsRoyGJZXVd4w==
- dependencies:
- "@colors/colors" "1.5.0"
- body-parser "^1.19.0"
- braces "^3.0.2"
- chokidar "^3.5.1"
- connect "^3.7.0"
- di "^0.0.1"
- dom-serialize "^2.2.1"
- glob "^7.1.7"
- graceful-fs "^4.2.6"
- http-proxy "^1.18.1"
- isbinaryfile "^4.0.8"
- lodash "^4.17.21"
- log4js "^6.4.1"
- mime "^2.5.2"
- minimatch "^3.0.4"
- mkdirp "^0.5.5"
- qjobs "^1.2.0"
- range-parser "^1.2.1"
- rimraf "^3.0.2"
- socket.io "^4.4.1"
- source-map "^0.6.1"
- tmp "^0.2.1"
- ua-parser-js "^0.7.30"
- yargs "^16.1.1"
-
kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
version "3.2.2"
resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz"
@@ -8009,17 +7796,6 @@ lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21:
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
-log4js@^6.4.1:
- version "6.6.1"
- resolved "https://registry.npmjs.org/log4js/-/log4js-6.6.1.tgz"
- integrity sha512-J8VYFH2UQq/xucdNu71io4Fo+purYYudyErgBbswWKO0MC6QVOERRomt5su/z6d3RJSmLyTGmXl3Q/XjKCf+/A==
- dependencies:
- date-format "^4.0.13"
- debug "^4.3.4"
- flatted "^3.2.6"
- rfdc "^1.3.0"
- streamroller "^3.1.2"
-
lower-case@^2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz"
@@ -8239,11 +8015,6 @@ mime@1.6.0:
resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz"
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
-mime@^2.5.2:
- version "2.6.0"
- resolved "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz"
- integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==
-
mimic-fn@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz"
@@ -8302,13 +8073,6 @@ mixin-deep@^1.2.0:
for-in "^1.0.2"
is-extendable "^1.0.1"
-mkdirp@^0.5.5:
- version "0.5.6"
- resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz"
- integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==
- dependencies:
- minimist "^1.2.6"
-
moment@2.20.1:
version "2.20.1"
resolved "https://registry.npmjs.org/moment/-/moment-2.20.1.tgz"
@@ -8445,11 +8209,6 @@ node-releases@^2.0.6:
resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz"
integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==
-node-watch@0.7.3:
- version "0.7.3"
- resolved "https://registry.npmjs.org/node-watch/-/node-watch-0.7.3.tgz"
- integrity sha512-3l4E8uMPY1HdMMryPRUAl+oIHtXtyiTlIiESNSVSNxcPfzAFzeTbXFQkZfAwBbo0B1qMSG8nUABx+Gd+YrbKrQ==
-
nopt@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz"
@@ -8537,11 +8296,6 @@ nwsapi@^2.2.2:
resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0"
integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==
-object-assign@^4:
- version "4.1.1"
- resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"
- integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
-
object-copy@^0.1.0:
version "0.1.0"
resolved "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz"
@@ -8646,13 +8400,6 @@ on-finished@2.4.1:
dependencies:
ee-first "1.1.1"
-on-finished@~2.3.0:
- version "2.3.0"
- resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz"
- integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==
- dependencies:
- ee-first "1.1.1"
-
on-headers@~1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz"
@@ -9452,11 +9199,6 @@ pyre-to-regexp@^0.0.5:
resolved "https://registry.npmjs.org/pyre-to-regexp/-/pyre-to-regexp-0.0.5.tgz"
integrity sha512-AYoI8bSYhCbElpcj/Z7FyP0rrpuuw96GAYCqdrX3fDH+vRXh8lXWeRRZtyJgRO4LgBlb5fK2o2odkaoSGQ6gIQ==
-qjobs@^1.2.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz"
- integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==
-
qs@6.10.3:
version "6.10.3"
resolved "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz"
@@ -9484,15 +9226,6 @@ quick-lru@^5.1.1:
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
-qunit@^2.17.2:
- version "2.19.1"
- resolved "https://registry.npmjs.org/qunit/-/qunit-2.19.1.tgz"
- integrity sha512-gSGuw0vErE/rNjnlBW/JmE7NNubBlGrDPQvsug32ejYhcVFuZec9yoU0+C30+UgeCGwq6Ap89K65dMGo+kDGZQ==
- dependencies:
- commander "7.2.0"
- node-watch "0.7.3"
- tiny-glob "0.2.9"
-
raf@^3.4.1:
version "3.4.1"
resolved "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz"
@@ -9883,17 +9616,12 @@ reusify@^1.0.4:
resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz"
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
-rfdc@^1.3.0:
- version "1.3.0"
- resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz"
- integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==
-
rgbcolor@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz"
integrity sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==
-rimraf@^3.0.0, rimraf@^3.0.2:
+rimraf@^3.0.2:
version "3.0.2"
resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz"
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
@@ -10278,32 +10006,6 @@ snapdragon@^0.8.1:
source-map-resolve "^0.5.0"
use "^3.1.0"
-socket.io-adapter@~2.4.0:
- version "2.4.0"
- resolved "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz"
- integrity sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==
-
-socket.io-parser@~4.0.4:
- version "4.0.5"
- resolved "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.5.tgz"
- integrity sha512-sNjbT9dX63nqUFIOv95tTVm6elyIU4RvB1m8dOeZt+IgWwcWklFDOdmGcfo3zSiRsnR/3pJkjY5lfoGqEe4Eig==
- dependencies:
- "@types/component-emitter" "^1.2.10"
- component-emitter "~1.3.0"
- debug "~4.3.1"
-
-socket.io@^4.4.1:
- version "4.5.1"
- resolved "https://registry.npmjs.org/socket.io/-/socket.io-4.5.1.tgz"
- integrity sha512-0y9pnIso5a9i+lJmsCdtmTTgJFFSvNQKDnPQRz28mGNnxbmqYg2QPtJTLFxhymFZhAIn50eHAKzJeiNaKr+yUQ==
- dependencies:
- accepts "~1.3.4"
- base64id "~2.0.0"
- debug "~4.3.2"
- engine.io "~6.2.0"
- socket.io-adapter "~2.4.0"
- socket.io-parser "~4.0.4"
-
sockjs@^0.3.24:
version "0.3.24"
resolved "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz"
@@ -10489,7 +10191,7 @@ statuses@2.0.1:
resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz"
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
-"statuses@>= 1.4.0 < 2", statuses@~1.5.0:
+"statuses@>= 1.4.0 < 2":
version "1.5.0"
resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz"
integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==
@@ -10517,15 +10219,6 @@ stream-shift@^1.0.0:
resolved "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz"
integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==
-streamroller@^3.1.2:
- version "3.1.2"
- resolved "https://registry.npmjs.org/streamroller/-/streamroller-3.1.2.tgz"
- integrity sha512-wZswqzbgGGsXYIrBYhOE0yP+nQ6XRk7xDcYwuQAGTYXdyAUmvgVFE0YU1g5pvQT0m7GBaQfYcSnlHbapuK0H0A==
- dependencies:
- date-format "^4.0.13"
- debug "^4.3.4"
- fs-extra "^8.1.0"
-
streamsearch@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764"
@@ -10817,21 +10510,6 @@ timers-browserify@^2.0.12:
dependencies:
setimmediate "^1.0.4"
-tiny-glob@0.2.9:
- version "0.2.9"
- resolved "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz"
- integrity sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==
- dependencies:
- globalyzer "0.1.0"
- globrex "^0.1.2"
-
-tmp@^0.2.1:
- version "0.2.1"
- resolved "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz"
- integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==
- dependencies:
- rimraf "^3.0.0"
-
tmpl@1.0.5:
version "1.0.5"
resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz"
@@ -11077,11 +10755,6 @@ typescript@^4.9.5:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
-ua-parser-js@^0.7.30:
- version "0.7.33"
- resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.33.tgz#1d04acb4ccef9293df6f70f2c3d22f3030d8b532"
- integrity sha512-s8ax/CeZdK9R/56Sui0WM6y9OFREJarMRHqLB2EwkovemBxNQ+Bqu8GAsUnVcXKgphb++ghr/B2BZx4mahujPw==
-
uc.micro@^1.0.1, uc.micro@^1.0.5:
version "1.0.6"
resolved "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz"
@@ -11181,11 +10854,6 @@ unique-stream@^2.0.2:
json-stable-stringify-without-jsonify "^1.0.1"
through2-filter "^3.0.0"
-universalify@^0.1.0:
- version "0.1.2"
- resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz"
- integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
-
universalify@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0"
@@ -11308,7 +10976,7 @@ value-or-function@^3.0.0:
resolved "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz"
integrity sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==
-vary@^1, vary@~1.1.2:
+vary@~1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz"
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
@@ -11361,11 +11029,6 @@ vinyl@^2.0.0:
remove-trailing-separator "^1.0.1"
replace-ext "^1.0.0"
-void-elements@^2.0.0:
- version "2.0.1"
- resolved "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz"
- integrity sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==
-
vue-demi@*:
version "0.13.11"
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.13.11.tgz#7d90369bdae8974d87b1973564ad390182410d99"
@@ -11611,13 +11274,6 @@ webpack-dev-server@^4.11.1:
webpack-dev-middleware "^5.3.1"
ws "^8.4.2"
-webpack-merge@^4.1.5:
- version "4.2.2"
- resolved "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz"
- integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==
- dependencies:
- lodash "^4.17.15"
-
webpack-merge@^5.7.3, webpack-merge@^5.8.0:
version "5.8.0"
resolved "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz"
@@ -11783,7 +11439,7 @@ which-typed-array@^1.1.8:
has-tostringtag "^1.0.0"
is-typed-array "^1.1.10"
-which@^1.2.1, which@^1.2.14:
+which@^1.2.14:
version "1.3.1"
resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz"
integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
@@ -11864,11 +11520,6 @@ ws@^8.4.2:
resolved "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz"
integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==
-ws@~8.2.3:
- version "8.2.3"
- resolved "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz"
- integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==
-
xml-beautifier@^0.5.0:
version "0.5.0"
resolved "https://registry.npmjs.org/xml-beautifier/-/xml-beautifier-0.5.0.tgz"
@@ -11942,7 +11593,7 @@ yaml@^2.0.0:
resolved "https://registry.npmjs.org/yaml/-/yaml-2.1.1.tgz"
integrity sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw==
-yargs-parser@^20.2.2, yargs-parser@^20.2.9:
+yargs-parser@^20.2.9:
version "20.2.9"
resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz"
integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
@@ -11960,19 +11611,6 @@ yargs-parser@^5.0.1:
camelcase "^3.0.0"
object.assign "^4.1.0"
-yargs@^16.1.1:
- version "16.2.0"
- resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz"
- integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
- dependencies:
- cliui "^7.0.2"
- escalade "^3.1.1"
- get-caller-file "^2.0.5"
- require-directory "^2.1.1"
- string-width "^4.2.0"
- y18n "^5.0.5"
- yargs-parser "^20.2.2"
-
yargs@^17.3.1:
version "17.6.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.2.tgz#2e23f2944e976339a1ee00f18c77fedee8332541"