Setup JavaScript test environment
This patch setups JavaScript test environment. - eslint test at local: `tox -e=eslint` - karma test at local: `npm run test`
This commit is contained in:
parent
c325be7d36
commit
48004f0fc0
@ -18,6 +18,9 @@ env:
|
||||
# Adds all of the Jasmine testing global variables for version 1.3 and 2.0.
|
||||
jasmine: true
|
||||
|
||||
# Enable eslint-plugin-angular
|
||||
plugins:
|
||||
- angular
|
||||
|
||||
# Below we adjust rules specific to horizon's usage of openstack's linting
|
||||
# rules, and its own plugin inclusions.
|
||||
@ -28,11 +31,20 @@ rules:
|
||||
valid-jsdoc: [1, {
|
||||
requireParamDescription: false
|
||||
}]
|
||||
no-undefined: 1
|
||||
brace-style: 1
|
||||
no-extra-parens: 1
|
||||
callback-return: 1
|
||||
block-scoped-var: 1
|
||||
callback-return: 1
|
||||
consistent-return: 1
|
||||
guard-for-in: 1
|
||||
no-extra-parens: 1
|
||||
no-new: 1
|
||||
no-redeclare: 1
|
||||
no-undefined: 1
|
||||
no-unneeded-ternary: 1
|
||||
no-use-before-define: 1
|
||||
quote-props: 0
|
||||
semi-spacing: 1
|
||||
space-in-parens: 1
|
||||
|
||||
#############################################################################
|
||||
# Angular Plugin Customization
|
||||
|
32
{{cookiecutter.repo_name}}/package.json
Normal file
32
{{cookiecutter.repo_name}}/package.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "{{ cookiecutter.repo_name }}",
|
||||
"description": "{{ cookiecutter.call_by_name }} JavaScript tests",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://git.openstack.org/openstack/{{ cookiecutter.repo_name }}"
|
||||
},
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"license": "Apache 2.0",
|
||||
"author": "Openstack <openstack-dev@lists.openstack.org>",
|
||||
"devDependencies": {
|
||||
"eslint": "^1.10.3",
|
||||
"eslint-config-openstack": "^1.2.4",
|
||||
"eslint-plugin-angular": "1.0.1",
|
||||
"jasmine-core": "2.4.1",
|
||||
"karma": "1.1.2",
|
||||
"karma-chrome-launcher": "1.0.1",
|
||||
"karma-cli": "1.0.1",
|
||||
"karma-coverage": "1.1.1",
|
||||
"karma-jasmine": "1.0.2",
|
||||
"karma-ng-html2js-preprocessor": "1.0.0",
|
||||
"karma-threshold-reporter": "0.1.15"
|
||||
},
|
||||
"dependencies": {},
|
||||
"scripts": {
|
||||
"postinstall": "if [ ! -d .tox ] || [ ! -d .tox/py27 ]; then tox -epy27 --notest; fi",
|
||||
"lint": "eslint --no-color {{ cookiecutter.module_folder }}/static",
|
||||
"lintq": "eslint --quiet {{ cookiecutter.module_folder }}/static",
|
||||
"test": "karma start {{ cookiecutter.module_folder }}/karma.conf.js --single-run"
|
||||
}
|
||||
}
|
96
{{cookiecutter.repo_name}}/test-shim.js
Normal file
96
{{cookiecutter.repo_name}}/test-shim.js
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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));
|
@ -31,6 +31,26 @@ commands =
|
||||
pip install django>=1.8,<1.9
|
||||
python manage.py test {posargs} --settings={{cookiecutter.module_folder}}.test.settings
|
||||
|
||||
[testenv:eslint]
|
||||
whitelist_externals = npm
|
||||
commands =
|
||||
npm install
|
||||
npm run postinstall
|
||||
npm run lint
|
||||
|
||||
[testenv:karma]
|
||||
# NOTE(shu-mutou): Until PhantomJS setup get reliable, we use
|
||||
# Chromium for JS test. And npm can't launch Chromium via tox.
|
||||
#whitelist_externals = npm
|
||||
#commands =
|
||||
# npm install
|
||||
# npm run postinstall
|
||||
# npm run test
|
||||
whitelist_externals = echo
|
||||
commands =
|
||||
echo "npm can't launch Chromium via tox."
|
||||
echo "nexecute `npm run test`"
|
||||
|
||||
[testenv:docs]
|
||||
setenv = DJANGO_SETTINGS_MODULE={{cookiecutter.module_folder}}.test.settings
|
||||
commands = python setup.py build_sphinx
|
||||
|
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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 toxPath = '../.tox/py27/lib/python2.7/site-packages/';
|
||||
|
||||
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'],
|
||||
// Used to indicate files requiring coverage reports.
|
||||
'./static/**/!(*.spec).js': ['coverage'],
|
||||
},
|
||||
|
||||
// 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
|
||||
toxPath + 'xstatic/pkg/jquery/data/jquery.js',
|
||||
toxPath + 'xstatic/pkg/angular/data/angular.js',
|
||||
toxPath + 'xstatic/pkg/angular/data/angular-route.js',
|
||||
toxPath + 'xstatic/pkg/angular/data/angular-mocks.js',
|
||||
toxPath + 'xstatic/pkg/angular/data/angular-cookies.js',
|
||||
toxPath + 'xstatic/pkg/angular_bootstrap/data/angular-bootstrap.js',
|
||||
toxPath + 'xstatic/pkg/angular_gettext/data/angular-gettext.js',
|
||||
toxPath + 'xstatic/pkg/angular/data/angular-sanitize.js',
|
||||
toxPath + 'xstatic/pkg/d3/data/d3.js',
|
||||
toxPath + 'xstatic/pkg/rickshaw/data/rickshaw.js',
|
||||
toxPath + 'xstatic/pkg/angular_smart_table/data/smart-table.js',
|
||||
toxPath + 'xstatic/pkg/angular_lrdragndrop/data/lrdragndrop.js',
|
||||
toxPath + 'xstatic/pkg/spin/data/spin.js',
|
||||
toxPath + 'xstatic/pkg/spin/data/spin.jquery.js',
|
||||
toxPath + 'xstatic/pkg/tv4/data/tv4.js',
|
||||
toxPath + 'xstatic/pkg/objectpath/data/ObjectPath.js',
|
||||
toxPath + 'xstatic/pkg/angular_schema_form/data/schema-form.js',
|
||||
toxPath + 'xstatic/pkg/angular_fileupload/data/ng-file-upload.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',
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
'./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.
|
||||
*/
|
||||
'./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',
|
||||
|
||||
/**
|
||||
* Finally, list files for spec with `spec.js` extension. The order
|
||||
* among them should not be significant.
|
||||
*/
|
||||
'./static/**/*.spec.js',
|
||||
|
||||
/**
|
||||
* Angular external templates
|
||||
*/
|
||||
'./static/**/*.html'
|
||||
],
|
||||
|
||||
autoWatch: true,
|
||||
|
||||
frameworks: ['jasmine'],
|
||||
|
||||
browsers: ['Chrome'],
|
||||
|
||||
browserNoActivityTimeout: 60000,
|
||||
|
||||
reporters: ['progress', 'coverage', 'threshold'],
|
||||
|
||||
plugins: [
|
||||
'karma-chrome-launcher',
|
||||
'karma-jasmine',
|
||||
'karma-ng-html2js-preprocessor',
|
||||
'karma-coverage',
|
||||
'karma-threshold-reporter'
|
||||
],
|
||||
|
||||
// Places coverage report in HTML format in the subdirectory below.
|
||||
coverageReporter: {
|
||||
type: 'html',
|
||||
dir: '../cover/karma/'
|
||||
},
|
||||
|
||||
// Coverage threshold values.
|
||||
thresholdReporter: {
|
||||
statements: 10, // target 100
|
||||
branches: 0, // target 100
|
||||
functions: 10, // target 100
|
||||
lines: 10 // target 100
|
||||
}
|
||||
});
|
||||
};
|
Loading…
Reference in New Issue
Block a user