AngularJS unittest with Jasmine and Karma for gate check
Change-Id: I156ec1665d98f247f01a1b0a5adaf26ab1eb09ce Co-Authored-By: Saju Madhavan <sajuptpm@gmail.com> Implements: blueprint angularjs-unittest-with-jasmine-and-karma
This commit is contained in:
parent
470ae7d22d
commit
f1ff41eb84
162
karma.conf.js
Normal file
162
karma.conf.js
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var fs = require('fs');
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
|
module.exports = function (config) {
|
||||||
|
// This tox venv is setup in the post-install npm step
|
||||||
|
var xstaticPath = path.resolve('./.tox/npm');
|
||||||
|
|
||||||
|
if (!xstaticPath) {
|
||||||
|
console.error('xStatic libraries not found, please run `tox -e npm`');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
xstaticPath += '/lib/';
|
||||||
|
xstaticPath += fs.readdirSync(xstaticPath).find(function(directory) {
|
||||||
|
return directory.indexOf('python') === 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
var toxPath = xstaticPath + '/site-packages/';
|
||||||
|
xstaticPath = toxPath + 'xstatic/pkg/';
|
||||||
|
|
||||||
|
config.set({
|
||||||
|
preprocessors: {
|
||||||
|
// Used to collect templates for preprocessing.
|
||||||
|
// NOTE: the templates must also be listed in the files section below.
|
||||||
|
'./static/**/*.html': ['ng-html2js']
|
||||||
|
},
|
||||||
|
|
||||||
|
// Sets up module to process templates.
|
||||||
|
ngHtml2JsPreprocessor: {
|
||||||
|
prependPrefix: '/',
|
||||||
|
moduleName: 'templates'
|
||||||
|
},
|
||||||
|
|
||||||
|
basePath: './',
|
||||||
|
|
||||||
|
// Contains both source and test files.
|
||||||
|
files: [
|
||||||
|
/*
|
||||||
|
* shim, partly stolen from /i18n/js/horizon/
|
||||||
|
* Contains expected items not provided elsewhere (dynamically by
|
||||||
|
* Django or via jasmine template.
|
||||||
|
*/
|
||||||
|
'./test-shim.js',
|
||||||
|
|
||||||
|
// from jasmine.html
|
||||||
|
xstaticPath + 'jquery/data/jquery.js',
|
||||||
|
xstaticPath + 'angular/data/angular.js',
|
||||||
|
xstaticPath + 'angular/data/angular-route.js',
|
||||||
|
xstaticPath + 'angular/data/angular-mocks.js',
|
||||||
|
xstaticPath + 'angular/data/angular-cookies.js',
|
||||||
|
xstaticPath + 'angular_bootstrap/data/angular-bootstrap.js',
|
||||||
|
xstaticPath + 'angular_gettext/data/angular-gettext.js',
|
||||||
|
xstaticPath + 'angular_fileupload/data/ng-file-upload-all.js',
|
||||||
|
xstaticPath + 'angular/data/angular-sanitize.js',
|
||||||
|
xstaticPath + 'd3/data/d3.js',
|
||||||
|
xstaticPath + 'rickshaw/data/rickshaw.js',
|
||||||
|
xstaticPath + 'angular_smart_table/data/smart-table.js',
|
||||||
|
xstaticPath + 'angular_lrdragndrop/data/lrdragndrop.js',
|
||||||
|
xstaticPath + 'spin/data/spin.js',
|
||||||
|
xstaticPath + 'spin/data/spin.jquery.js',
|
||||||
|
xstaticPath + 'tv4/data/tv4.js',
|
||||||
|
xstaticPath + 'objectpath/data/ObjectPath.js',
|
||||||
|
xstaticPath + 'angular_schema_form/data/schema-form.js',
|
||||||
|
|
||||||
|
// TODO: These should be mocked.
|
||||||
|
toxPath + '/horizon/static/horizon/js/horizon.js',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include framework source code from horizon that we need.
|
||||||
|
* Otherwise, karma will not be able to find them when testing.
|
||||||
|
* These files should be mocked in the foreseeable future.
|
||||||
|
*/
|
||||||
|
toxPath + 'horizon/static/framework/**/*.module.js',
|
||||||
|
toxPath + 'horizon/static/framework/**/!(*.spec|*.mock).js',
|
||||||
|
toxPath + 'openstack_dashboard/static/**/*.module.js',
|
||||||
|
toxPath + 'openstack_dashboard/static/**/!(*.spec|*.mock).js',
|
||||||
|
toxPath + 'openstack_dashboard/dashboards/**/static/**/*.module.js',
|
||||||
|
toxPath + 'openstack_dashboard/dashboards/**/static/**/!(*.spec|*.mock).js',
|
||||||
|
|
||||||
|
'./vitrage_dashboard/dashboard/static/vendor/lodash/**/lodash.js',
|
||||||
|
'./vitrage_dashboard/dashboard/static/vendor/graphlib/**/graphlib.core.js',
|
||||||
|
'./vitrage_dashboard/dashboard/static/vendor/dagre/**/dagre.core.js',
|
||||||
|
'./vitrage_dashboard/dashboard/static/vendor/d3/**/d3.js',
|
||||||
|
'./vitrage_dashboard/dashboard/static/vendor/dagre-d3/**/dagre-d3.core.js',
|
||||||
|
//'./vitrage_dashboard/dashboard/static/**/*.module.js',
|
||||||
|
//'./vitrage_dashboard/dashboard/static/**/*.module.js',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* First, list all the files that defines application's angular modules.
|
||||||
|
* Those files have extension of `.module.js`. The order among them is
|
||||||
|
* not significant.
|
||||||
|
*/
|
||||||
|
'./vitrage_dashboard/dashboard/static/**/*.module.js',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Followed by other JavaScript files that defines angular providers
|
||||||
|
* on the modules defined in files listed above. And they are not mock
|
||||||
|
* files or spec files defined below. The order among them is not
|
||||||
|
* significant.
|
||||||
|
*/
|
||||||
|
'./vitrage_dashboard/dashboard/static/**/!(*.spec|*.mock).js',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Then, list files for mocks with `mock.js` extension. The order
|
||||||
|
* among them should not be significant.
|
||||||
|
*/
|
||||||
|
toxPath + 'openstack_dashboard/static/**/*.mock.js',
|
||||||
|
//'./static/**/*.mock.js',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finally, list files for spec with `spec.js` extension. The order
|
||||||
|
* among them should not be significant.
|
||||||
|
*/
|
||||||
|
'./vitrage_dashboard/dashboard/static/app/core/openstack-service-api/vitrage.service.spec.js',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Angular external templates
|
||||||
|
*/
|
||||||
|
'./vitrage_dashboard/dashboard/static/**/*.html',
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
autoWatch: true,
|
||||||
|
|
||||||
|
frameworks: ['jasmine'],
|
||||||
|
|
||||||
|
browsers: ['Chrome'],
|
||||||
|
|
||||||
|
phantomjsLauncher: {
|
||||||
|
// Have phantomjs exit if a ResourceError is encountered
|
||||||
|
// (useful if karma exits without killing phantom)
|
||||||
|
exitOnResourceError: true
|
||||||
|
},
|
||||||
|
|
||||||
|
reporters: ['progress'],
|
||||||
|
//reporters: ['spec'],
|
||||||
|
|
||||||
|
plugins: [
|
||||||
|
'karma-chrome-launcher',
|
||||||
|
'karma-jasmine',
|
||||||
|
'karma-ng-html2js-preprocessor',
|
||||||
|
'karma-spec-reporter',
|
||||||
|
]
|
||||||
|
|
||||||
|
});
|
||||||
|
};
|
26
package.json
Normal file
26
package.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"name": "vitrage-dashboard",
|
||||||
|
"description": "Vitrage Dashboard",
|
||||||
|
"repository": "none",
|
||||||
|
"license": "Apache 2.0",
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "1.10.3",
|
||||||
|
"eslint-config-openstack": "1.2.4",
|
||||||
|
"jasmine-core": "2.4.1",
|
||||||
|
"karma": "1.1.2",
|
||||||
|
"karma-chrome-launcher": "1.0.1",
|
||||||
|
"karma-cli": "^1.0.1",
|
||||||
|
"karma-jasmine": "1.0.2",
|
||||||
|
"karma-ng-html2js-preprocessor": "1.0.0",
|
||||||
|
"karma-spec-reporter": "0.0.32"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"postinstall": "if [ ! -d .venv ]; then tox -e npm --notest; fi",
|
||||||
|
"lint": "eslint --no-color vitrage_dashboard/static",
|
||||||
|
"lintq": "eslint --quiet vitrage_dashboard/static",
|
||||||
|
"test": "karma start karma.conf.js --single-run"
|
||||||
|
},
|
||||||
|
"dependencies": {}
|
||||||
|
}
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
pbr!=2.1.0,>=2.0.0 # Apache-2.0
|
pbr!=2.1.0,>=2.0.0 # Apache-2.0
|
||||||
# Horizon Core Requirements
|
# Horizon Core Requirements
|
||||||
Django<1.11,>=1.8 # BSD
|
|
||||||
django-compressor>=2.0 # MIT
|
django-compressor>=2.0 # MIT
|
||||||
iso8601>=0.1.11 # MIT
|
iso8601>=0.1.11 # MIT
|
||||||
|
|
||||||
|
horizon>=14.0.0.0b1 # Apache-2.0
|
||||||
|
110
test-shim.js
Normal file
110
test-shim.js
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/**
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License. You may obtain
|
||||||
|
* a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shim for Javascript unit tests; supplying expected global features.
|
||||||
|
* This should be removed from the codebase once i18n services are provided.
|
||||||
|
* Taken from default i18n file provided by Django.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var horizonPlugInModules = [];
|
||||||
|
|
||||||
|
|
||||||
|
(function (globals) {
|
||||||
|
|
||||||
|
var django = globals.django || (globals.django = {});
|
||||||
|
|
||||||
|
|
||||||
|
django.pluralidx = function (count) { return (count == 1) ? 0 : 1; };
|
||||||
|
|
||||||
|
/* gettext identity library */
|
||||||
|
|
||||||
|
django.gettext = function (msgid) { return msgid; };
|
||||||
|
django.ngettext = function (singular, plural, count) { return (count == 1) ? singular : plural; };
|
||||||
|
django.gettext_noop = function (msgid) { return msgid; };
|
||||||
|
django.pgettext = function (context, msgid) { return msgid; };
|
||||||
|
django.npgettext = function (context, singular, plural, count) { return (count == 1) ? singular : plural; };
|
||||||
|
|
||||||
|
|
||||||
|
django.interpolate = function (fmt, obj, named) {
|
||||||
|
if (named) {
|
||||||
|
return fmt.replace(/%\(\w+\)s/g, function(match){return String(obj[match.slice(2,-2)])});
|
||||||
|
} else {
|
||||||
|
return fmt.replace(/%s/g, function(match){return String(obj.shift())});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* formatting library */
|
||||||
|
|
||||||
|
django.formats = {
|
||||||
|
"DATETIME_FORMAT": "N j, Y, P",
|
||||||
|
"DATETIME_INPUT_FORMATS": [
|
||||||
|
"%Y-%m-%d %H:%M:%S",
|
||||||
|
"%Y-%m-%d %H:%M:%S.%f",
|
||||||
|
"%Y-%m-%d %H:%M",
|
||||||
|
"%Y-%m-%d",
|
||||||
|
"%m/%d/%Y %H:%M:%S",
|
||||||
|
"%m/%d/%Y %H:%M:%S.%f",
|
||||||
|
"%m/%d/%Y %H:%M",
|
||||||
|
"%m/%d/%Y",
|
||||||
|
"%m/%d/%y %H:%M:%S",
|
||||||
|
"%m/%d/%y %H:%M:%S.%f",
|
||||||
|
"%m/%d/%y %H:%M",
|
||||||
|
"%m/%d/%y"
|
||||||
|
],
|
||||||
|
"DATE_FORMAT": "N j, Y",
|
||||||
|
"DATE_INPUT_FORMATS": [
|
||||||
|
"%Y-%m-%d",
|
||||||
|
"%m/%d/%Y",
|
||||||
|
"%m/%d/%y"
|
||||||
|
],
|
||||||
|
"DECIMAL_SEPARATOR": ".",
|
||||||
|
"FIRST_DAY_OF_WEEK": "0",
|
||||||
|
"MONTH_DAY_FORMAT": "F j",
|
||||||
|
"NUMBER_GROUPING": "3",
|
||||||
|
"SHORT_DATETIME_FORMAT": "m/d/Y P",
|
||||||
|
"SHORT_DATE_FORMAT": "m/d/Y",
|
||||||
|
"THOUSAND_SEPARATOR": ",",
|
||||||
|
"TIME_FORMAT": "P",
|
||||||
|
"TIME_INPUT_FORMATS": [
|
||||||
|
"%H:%M:%S",
|
||||||
|
"%H:%M:%S.%f",
|
||||||
|
"%H:%M"
|
||||||
|
],
|
||||||
|
"YEAR_MONTH_FORMAT": "F Y"
|
||||||
|
};
|
||||||
|
|
||||||
|
django.get_format = function (format_type) {
|
||||||
|
var value = django.formats[format_type];
|
||||||
|
if (typeof(value) == 'undefined') {
|
||||||
|
return format_type;
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* add to global namespace */
|
||||||
|
globals.pluralidx = django.pluralidx;
|
||||||
|
globals.gettext = django.gettext;
|
||||||
|
globals.ngettext = django.ngettext;
|
||||||
|
globals.gettext_noop = django.gettext_noop;
|
||||||
|
globals.pgettext = django.pgettext;
|
||||||
|
globals.npgettext = django.npgettext;
|
||||||
|
globals.interpolate = django.interpolate;
|
||||||
|
globals.get_format = django.get_format;
|
||||||
|
globals.STATIC_URL = '/static/';
|
||||||
|
globals.WEBROOT = '/';
|
||||||
|
|
||||||
|
}(this));
|
14
tox.ini
14
tox.ini
@ -1,6 +1,6 @@
|
|||||||
[tox]
|
[tox]
|
||||||
minversion = 1.6
|
minversion = 1.6
|
||||||
envlist = py35,py27,pep8
|
envlist = py35,py27,pep8,npm
|
||||||
skipsdist = True
|
skipsdist = True
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
@ -17,6 +17,18 @@ basepython = python3
|
|||||||
commands = flake8
|
commands = flake8
|
||||||
python setup.py check --restructuredtext --strict
|
python setup.py check --restructuredtext --strict
|
||||||
|
|
||||||
|
[testenv:npm]
|
||||||
|
basepython = python3
|
||||||
|
passenv =
|
||||||
|
HOME
|
||||||
|
DISPLAY
|
||||||
|
commands =
|
||||||
|
nodeenv -p
|
||||||
|
npm install
|
||||||
|
npm run {posargs:test}
|
||||||
|
deps =
|
||||||
|
-r{toxinidir}/requirements.txt
|
||||||
|
-r{toxinidir}/test-requirements.txt
|
||||||
[testenv:venv]
|
[testenv:venv]
|
||||||
basepython = python3
|
basepython = python3
|
||||||
commands = {posargs}
|
commands = {posargs}
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
}
|
}
|
||||||
console.info('CONFIG in core - ', config)
|
console.info('CONFIG in core - ', config)
|
||||||
return apiService.get('/api/vitrage/topology/', config)
|
return apiService.get('/api/vitrage/topology/', config)
|
||||||
.catch(function () {
|
.error(function () {
|
||||||
toastService.add('error', gettext('Unable to fetch the Vitrage Topology service.'));
|
toastService.add('error', gettext('Unable to fetch the Vitrage Topology service.'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,8 @@
|
|||||||
"func": "getTopology",
|
"func": "getTopology",
|
||||||
"method": "get",
|
"method": "get",
|
||||||
"path": "/api/vitrage/topology/",
|
"path": "/api/vitrage/topology/",
|
||||||
"error": "Unable to get the Vitrage service topology."
|
"data": {},
|
||||||
|
"error": "Unable to fetch the Vitrage Topology service."
|
||||||
}
|
}
|
||||||
|
|
||||||
];
|
];
|
||||||
|
Loading…
Reference in New Issue
Block a user