From 299cc43c9848792eb3e23572188967fce2316b8f Mon Sep 17 00:00:00 2001 From: Kenji Ishii Date: Fri, 2 Dec 2016 11:04:52 +0900 Subject: [PATCH] Add mechanism to execute JavaScript test Same as other UI plugins, it can run tests by the following command. npm run test Change-Id: I5bf05b9b8b073b805844496a73670fd62c791160 --- .eslintrc | 54 +++++++++++++++ package.json | 28 ++++++++ test-shim.js | 96 +++++++++++++++++++++++++++ zun_ui/karma.conf.js | 154 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 332 insertions(+) create mode 100644 .eslintrc create mode 100644 package.json create mode 100644 test-shim.js create mode 100644 zun_ui/karma.conf.js diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..653c865 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,54 @@ +# Set up globals +globals: + angular: false + +extends: openstack + +# Most environment options are not explicitly enabled or disabled, only +# included here for completeness' sake. They are commented out, because the +# global updates.py script would otherwise override them during a global +# requirements synchronization. +# +# Individual projects should choose which platforms they deploy to. + +env: + # browser global variables. + browser: true + + # 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. +rules: + ############################################################################# + # Disabled Rules from eslint-config-openstack + ############################################################################# + valid-jsdoc: [1, { + requireParamDescription: false + }] + brace-style: 1 + no-extra-parens: 1 + consistent-return: 1 + callback-return: 1 + guard-for-in: 1 + block-scoped-var: 1 + semi-spacing: 1 + no-redeclare: 1 + no-new: 1 + + ############################################################################# + # Angular Plugin Customization + ############################################################################# + + angular/controller-as-vm: + - 1 + - "ctrl" + + # Remove after migrating to angular 1.4 or later. + angular/no-cookiestore: + - 1 diff --git a/package.json b/package.json new file mode 100644 index 0000000..a3bfbae --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "version": "0.0.0", + "private": true, + "name": "zun-ui", + "description": "OpenStack Zun-UI", + "repository": "none", + "license": "Apache 2.0", + "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" + }, + "scripts": { + "postinstall": "if [ ! -d .venv ]; then tox -epy27 --notest; fi", + "test": "karma start zun_ui/karma.conf.js --single-run", + "lint": "eslint --no-color zun_ui/static", + "lintq": "eslint --quiet zun_ui/static" + }, + "dependencies": {} +} diff --git a/test-shim.js b/test-shim.js new file mode 100644 index 0000000..5b364ba --- /dev/null +++ b/test-shim.js @@ -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)); diff --git a/zun_ui/karma.conf.js b/zun_ui/karma.conf.js new file mode 100644 index 0000000..7f2b8ec --- /dev/null +++ b/zun_ui/karma.conf.js @@ -0,0 +1,154 @@ +/* + * 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_fileupload/data/ng-file-upload-all.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', + + // 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', + //'./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'], + + phantomjsLauncher: { + // Have phantomjs exit if a ResourceError is encountered + // (useful if karma exits without killing phantom) + exitOnResourceError: true + }, + + reporters: ['progress', 'coverage', 'threshold'], + + plugins: [ + 'karma-chrome-launcher', + 'karma-jasmine', + 'karma-ng-html2js-preprocessor', + 'karma-coverage', + 'karma-threshold-reporter' + ], + + coverageReporter: { + type: 'html', + dir: '../cover/zun_ui' + }, + + // Coverage threshold values. + thresholdReporter: { + statements: 45, + branches: 0, + functions: 15, + lines: 45 + } + }); +};