Added JavaScript Style Linting

This patch adds eslint, a permissively licensed (as opposed to
jshint or jslint) javascript style linter. It also enables the use
of 'npm run lint', which may be used in OpenStack's gate to
cause build failures when improperly formed javascript is
committed.

Existing javascript was updated to pass linting rules. Note
that most of these changes were formatting and file length
concerns. The noted stylistic change that we should probably
discuss is the use of singlequote vs. doublequote. Single is
the pep8 standard used in python, and thus enforcing that
seems to make the most sense.

Change-Id: I52768fe6e7ee1f76f0d67f44273fdc48b159489a
This commit is contained in:
Michael Krotscheck 2015-05-26 12:00:40 -07:00 committed by David Lenwell
parent 0d51cad50f
commit 6fffbca938
13 changed files with 563 additions and 421 deletions

View File

@ -0,0 +1 @@
app/assets/lib

58
refstack-ui/.eslintrc Normal file
View File

@ -0,0 +1,58 @@
{
// For a detailed list of all options, please see here:
// http://eslint.org/docs/configuring/
"ecmaFeatures": {
"arrowFunctions": false,
"binaryLiterals": false,
"blockBindings": false,
"defaultParams": false,
"forOf": false,
"generators": false,
"objectLiteralComputedProperties": false,
"objectLiteralDuplicateProperties": false,
"objectLiteralShorthandProperties": false,
"octalLiterals": false,
"regexUFlag": false,
"superInFunctions": false,
"templateStrings": false,
"unicodeCodePointEscapes": false,
"globalReturn": false,
"jsx": false
},
"env": {
"browser": true,
"node": false,
"amd": false,
"mocha": false,
"jasmine": true,
"phantomjs": false,
"jquery": false,
"prototypejs": false,
"shelljs": false
},
"globals": {
"require": false,
"exports": false,
"angular": false, // AngularJS
"module": false,
"inject": false,
"element": false,
"by": false,
"browser": false
},
"rules": {
"quotes": [2, "single"],
"eol-last": 2,
"no-trailing-spaces": 2,
"camelcase": 0,
"no-extra-boolean-cast": 0,
// Stylistic
"indent": [2, 4],
"max-len": [2, 80],
"no-undefined": 2
}
}

View File

@ -1,15 +1,16 @@
'use strict';
/* App Module */
var refstackApp = angular.module('refstackApp', [
'ui.router', 'ui.bootstrap', 'cgBusy']);
'ui.router', 'ui.bootstrap', 'cgBusy']);
/*
* Handle application routing.
*/
refstackApp.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
refstackApp.config([
'$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
'use strict';
$urlRouterProvider.otherwise('/');
$stateProvider.
state('home', {
@ -34,7 +35,7 @@ refstackApp.config(['$stateProvider', '$urlRouterProvider',
url: '/results/:testID',
templateUrl: '/components/results-report/resultsReport.html',
controller: 'resultsReportController'
})
});
}
]);
@ -42,7 +43,10 @@ refstackApp.config(['$stateProvider', '$urlRouterProvider',
* Load Config and start up the angular application.
*/
angular.element(document).ready(function () {
'use strict';
var $http = angular.injector(['ng']).get('$http');
function startApp(config) {
// Add config options as constants.
for (var key in config) {
@ -51,9 +55,9 @@ angular.element(document).ready(function () {
angular.bootstrap(document, ['refstackApp']);
}
$http.get('config.json').success(function(data) {
$http.get('config.json').success(function (data) {
startApp(data);
}).error(function(error) {
}).error(function () {
startApp({});
});
});

View File

@ -1,3 +1 @@
'use strict';
/* Miscellaneous Refstack JavaScript */

View File

@ -1,72 +1,81 @@
'use strict';
/* Refstack Capabilities Controller */
var refstackApp = angular.module('refstackApp');
refstackApp.controller('capabilitiesController', ['$scope', '$http', 'refstackApiUrl', function($scope, $http, refstackApiUrl) {
$scope.hideAchievements = true;
$scope.hideTests = true;
$scope.target = 'platform';
$scope.status = {
required: 'required',
advisory: '',
deprecated: '',
removed: ''
};
refstackApp.controller('capabilitiesController',
['$scope', '$http', 'refstackApiUrl',
function ($scope, $http, refstackApiUrl) {
'use strict';
$scope.getVersionList = function() {
var content_url = refstackApiUrl + '/capabilities';
$scope.versionsRequest = $http.get(content_url).success(function(data) {
$scope.versionList = data.sort().reverse();
$scope.version = $scope.versionList[0];
$scope.update();
}).error(function(error) {
$scope.showError = true;
$scope.error = 'Error retrieving version list: ' + JSON.stringify(error);
});
};
$scope.hideAchievements = true;
$scope.hideTests = true;
$scope.target = 'platform';
$scope.status = {
required: 'required',
advisory: '',
deprecated: '',
removed: ''
};
$scope.update = function() {
var content_url = refstackApiUrl + '/capabilities/' + $scope.version;
$scope.capsRequest = $http.get(content_url).success(function(data) {
$scope.capabilities = data;
}).error(function(error) {
$scope.showError = true;
$scope.capabilities = null;
$scope.error = 'Error retrieving capabilities: ' + JSON.stringify(error);
});
};
$scope.getVersionList = function () {
var content_url = refstackApiUrl + '/capabilities';
$scope.versionsRequest =
$http.get(content_url).success(function (data) {
$scope.versionList = data.sort().reverse();
$scope.version = $scope.versionList[0];
$scope.update();
}).error(function (error) {
$scope.showError = true;
$scope.error = 'Error retrieving version list: ' +
JSON.stringify(error);
});
};
$scope.getVersionList();
$scope.update = function () {
var content_url = refstackApiUrl + '/capabilities/' +
$scope.version;
$scope.capsRequest =
$http.get(content_url).success(function (data) {
$scope.capabilities = data;
}).error(function (error) {
$scope.showError = true;
$scope.capabilities = null;
$scope.error = 'Error retrieving capabilities: ' +
JSON.stringify(error);
});
};
$scope.filterProgram = function(capability){
var components = $scope.capabilities.components;
if ($scope.target === 'platform') {
var platform_components = $scope.capabilities.platform.required;
var cap_array = [];
// For each component required for the platform program.
angular.forEach(platform_components, function(component) {
// Get each capability belonging to each status.
angular.forEach(components[component], function(capabilities) {
cap_array = cap_array.concat(capabilities);
});
});
return (cap_array.indexOf(capability.id) > -1);
}
else {
var cap_array = [];
angular.forEach(components[$scope.target], function(capabilities) {
cap_array = cap_array.concat(capabilities);
});
return (cap_array.indexOf(capability.id) > -1);
}
};
$scope.getVersionList();
$scope.filterStatus = function(capability){
return capability.status === $scope.status.required ||
capability.status === $scope.status.advisory ||
capability.status === $scope.status.deprecated ||
capability.status === $scope.status.removed;
};
}]);
$scope.filterProgram = function (capability) {
var components = $scope.capabilities.components;
var cap_array = [];
if ($scope.target === 'platform') {
var platform_components =
$scope.capabilities.platform.required;
// For each component required for the platform program.
angular.forEach(platform_components, function (component) {
// Get each capability belonging to each status.
angular.forEach(components[component],
function (capabilities) {
cap_array = cap_array.concat(capabilities);
});
});
}
else {
angular.forEach(components[$scope.target],
function (capabilities) {
cap_array = cap_array.concat(capabilities);
});
}
return (cap_array.indexOf(capability.id) > -1);
};
$scope.filterStatus = function (capability) {
return capability.status === $scope.status.required ||
capability.status === $scope.status.advisory ||
capability.status === $scope.status.deprecated ||
capability.status === $scope.status.removed;
};
}]);

View File

@ -1,107 +1,122 @@
'use strict';
/* Refstack Results Report Controller */
var refstackApp = angular.module('refstackApp');
refstackApp.controller('resultsReportController', ['$scope', '$http', '$stateParams', 'refstackApiUrl',
function($scope, $http, $stateParams, refstackApiUrl) {
$scope.testId = $stateParams.testID
$scope.hideTests = true;
$scope.target = 'platform';
$scope.requiredOpen = true;
refstackApp.controller('resultsReportController',
['$scope', '$http', '$stateParams', 'refstackApiUrl',
function ($scope, $http, $stateParams, refstackApiUrl) {
'use strict';
$scope.targetMappings = {
'platform': 'Openstack Powered Platform',
'compute': 'OpenStack Powered Compute',
'object': 'OpenStack Powered Object Storage'
}
$scope.testId = $stateParams.testID;
$scope.hideTests = true;
$scope.target = 'platform';
$scope.requiredOpen = true;
var getResults = function() {
var content_url = refstackApiUrl +'/results/' + $scope.testId;
$scope.resultsRequest = $http.get(content_url).success(function(data) {
$scope.resultsData = data;
getVersionList();
}).error(function(error) {
$scope.showError = true;
$scope.resultsData = null;
$scope.error = "Error retrieving results from server: " + JSON.stringify(error);
$scope.targetMappings = {
'platform': 'Openstack Powered Platform',
'compute': 'OpenStack Powered Compute',
'object': 'OpenStack Powered Object Storage'
};
});
};
var getVersionList = function () {
var content_url = refstackApiUrl + '/capabilities';
$scope.versionsRequest =
$http.get(content_url).success(function (data) {
$scope.versionList = data.sort().reverse();
$scope.version = $scope.versionList[0];
$scope.updateCapabilities();
}).error(function (error) {
$scope.showError = true;
$scope.resultsData = null;
$scope.error = 'Error retrieving version list: ' +
JSON.stringify(error);
});
};
var getVersionList = function() {
var content_url = refstackApiUrl + '/capabilities';
$scope.versionsRequest = $http.get(content_url).success(function(data) {
$scope.versionList = data.sort().reverse();
$scope.version = $scope.versionList[0];
$scope.updateCapabilities();
}).error(function(error) {
$scope.showError = true;
$scope.resultsData = null;
$scope.error = "Error retrieving version list: " + JSON.stringify(error);;
});
};
var getResults = function () {
var content_url = refstackApiUrl + '/results/' + $scope.testId;
$scope.resultsRequest =
$http.get(content_url).success(function (data) {
$scope.resultsData = data;
getVersionList();
}).error(function (error) {
$scope.showError = true;
$scope.resultsData = null;
$scope.error = 'Error retrieving results from server: ' +
JSON.stringify(error);
$scope.updateCapabilities = function() {
$scope.showError = false;
var content_url = refstackApiUrl + '/capabilities/' + $scope.version;
$scope.capsRequest = $http.get(content_url).success(function(data) {
$scope.capabilityData = data;
$scope.buildCapabilityObject();
}).error(function(error) {
$scope.showError = true;
$scope.capabilityData = null;
$scope.error = 'Error retrieving capabilities: ' + JSON.stringify(error);
});
}
});
};
$scope.buildCapabilityObject = function() {
var capabilities = $scope.capabilityData.capabilities;
var caps = {'required': {'caps': [], 'count': 0, 'passedCount': 0},
'advisory': {'caps': [], 'count': 0, 'passedCount': 0},
'deprecated': {'caps': [], 'count': 0, 'passedCount': 0},
'removed': {'caps': [], 'count': 0, 'passedCount': 0}};
var components = $scope.capabilityData.components;
var cap_array = [];
// First determine which capabilities are relevant to the target.
if ($scope.target === 'platform') {
var platform_components = $scope.capabilityData.platform.required;
// For each component required for the platform program.
angular.forEach(platform_components, function(component) {
// Get each capability belonging to each status.
angular.forEach(components[component], function(capabilities) {
cap_array = cap_array.concat(capabilities);
});
});
}
else {
angular.forEach(components[$scope.target], function(capabilities) {
cap_array = cap_array.concat(capabilities);
});
}
$scope.updateCapabilities = function () {
$scope.showError = false;
var content_url = refstackApiUrl + '/capabilities/' +
$scope.version;
$scope.capsRequest =
$http.get(content_url).success(function (data) {
$scope.capabilityData = data;
$scope.buildCapabilityObject();
}).error(function (error) {
$scope.showError = true;
$scope.capabilityData = null;
$scope.error = 'Error retrieving capabilities: ' +
JSON.stringify(error);
});
};
angular.forEach(capabilities, function(value, key) {
if (cap_array.indexOf(key) > -1) {
var cap = { "id": key,
"passedTests": [],
"notPassedTests": []};
caps[value.status].count += value.tests.length;
angular.forEach(value.tests, function(test_id) {
if ($scope.resultsData.results.indexOf(test_id) > -1) {
cap.passedTests.push(test_id);
}
else {
cap.notPassedTests.push(test_id);
}
});
caps[value.status].passedCount += cap.passedTests.length;
caps[value.status].caps.push(cap);
}
});
$scope.caps = caps;
}
$scope.buildCapabilityObject = function () {
var capabilities = $scope.capabilityData.capabilities;
var caps = {
'required': {'caps': [], 'count': 0, 'passedCount': 0},
'advisory': {'caps': [], 'count': 0, 'passedCount': 0},
'deprecated': {'caps': [], 'count': 0, 'passedCount': 0},
'removed': {'caps': [], 'count': 0, 'passedCount': 0}
};
var components = $scope.capabilityData.components;
var cap_array = [];
// First determine which capabilities are relevant to the target.
if ($scope.target === 'platform') {
var platform_components =
$scope.capabilityData.platform.required;
// For each component required for the platform program.
angular.forEach(platform_components, function (component) {
// Get each capability belonging to each status.
angular.forEach(components[component],
function (compCapabilities) {
cap_array = cap_array.concat(compCapabilities);
});
});
}
else {
angular.forEach(components[$scope.target],
function (compCapabilities) {
cap_array = cap_array.concat(compCapabilities);
});
}
getResults();
}
]);
angular.forEach(capabilities, function (value, key) {
if (cap_array.indexOf(key) > -1) {
var cap = {
'id': key,
'passedTests': [],
'notPassedTests': []
};
caps[value.status].count += value.tests.length;
angular.forEach(value.tests, function (test_id) {
if ($scope.resultsData.results.indexOf(test_id) > -1) {
cap.passedTests.push(test_id);
}
else {
cap.notPassedTests.push(test_id);
}
});
caps[value.status].passedCount += cap.passedTests.length;
caps[value.status].caps.push(cap);
}
});
$scope.caps = caps;
};
getResults();
}
]);

View File

@ -1,51 +1,59 @@
'use strict';
/* Refstack Results Controller */
var refstackApp = angular.module('refstackApp');
refstackApp.controller('resultsController', ['$scope', '$http', '$filter', 'refstackApiUrl', function($scope, $http, $filter, refstackApiUrl) {
$scope.currentPage = 1;
$scope.itemsPerPage = 20;
$scope.maxSize = 5;
$scope.startDate = "";
$scope.endDate = "";
$scope.update = function() {
$scope.showError = false;
var content_url = refstackApiUrl + '/results?page=' + $scope.currentPage;
var start = $filter('date')($scope.startDate, "yyyy-MM-dd");
if (start) {
content_url = content_url + "&start_date=" + start + " 00:00:00";
}
var end = $filter('date')($scope.endDate, "yyyy-MM-dd");
if (end) {
content_url = content_url + "&end_date=" + end + " 23:59:59";
}
refstackApp.controller('resultsController',
['$scope', '$http', '$filter', 'refstackApiUrl',
function ($scope, $http, $filter, refstackApiUrl) {
'use strict';
$scope.resultsRequest = $http.get(content_url).success(function(data) {
$scope.data = data;
$scope.totalItems = $scope.data.pagination.total_pages * $scope.itemsPerPage;
$scope.currentPage = $scope.data.pagination.current_page;
}).error(function(error) {
$scope.data = null;
$scope.totalItems = 0
$scope.showError = true
$scope.error = "Error retrieving results listing from server: " + JSON.stringify(error);
});
}
$scope.currentPage = 1;
$scope.itemsPerPage = 20;
$scope.maxSize = 5;
$scope.startDate = '';
$scope.endDate = '';
$scope.update = function () {
$scope.showError = false;
var content_url = refstackApiUrl + '/results?page=' +
$scope.currentPage;
var start = $filter('date')($scope.startDate, 'yyyy-MM-dd');
if (start) {
content_url =
content_url + '&start_date=' + start + ' 00:00:00';
}
var end = $filter('date')($scope.endDate, 'yyyy-MM-dd');
if (end) {
content_url = content_url + '&end_date=' + end + ' 23:59:59';
}
$scope.update();
$scope.resultsRequest =
$http.get(content_url).success(function (data) {
$scope.data = data;
$scope.totalItems = $scope.data.pagination.total_pages *
$scope.itemsPerPage;
$scope.currentPage = $scope.data.pagination.current_page;
}).error(function (error) {
$scope.data = null;
$scope.totalItems = 0;
$scope.showError = true;
$scope.error =
'Error retrieving results listing from server: ' +
JSON.stringify(error);
});
};
// This is called when a date filter calendar is opened.
$scope.open = function($event, openVar) {
$event.preventDefault();
$event.stopPropagation();
$scope[openVar] = true;
};
$scope.update();
$scope.clearFilters = function() {
$scope.startDate = null;
$scope.endDate = null;
$scope.update();
};
}]);
// This is called when a date filter calendar is opened.
$scope.open = function ($event, openVar) {
$event.preventDefault();
$event.stopPropagation();
$scope[openVar] = true;
};
$scope.clearFilters = function () {
$scope.startDate = null;
$scope.endDate = null;
$scope.update();
};
}]);

View File

@ -1,16 +1,16 @@
'use strict';
/* Refstack Filters */
var refstackApp = angular.module('refstackApp');
// Convert an object of objects to an array of objects to use with ng-repeat
// filters.
refstackApp.filter('arrayConverter', function() {
return function(objects) {
refstackApp.filter('arrayConverter', function () {
'use strict';
return function (objects) {
var array = [];
angular.forEach(objects, function(object, key) {
object['id'] = key;
angular.forEach(objects, function (object, key) {
object.id = key;
array.push(object);
});
return array;

View File

@ -1,18 +1,20 @@
'use strict';
/* Refstack Header Controller */
var refstackApp = angular.module('refstackApp')
refstackApp.controller('headerController', ['$scope', '$location', function($scope, $location) {
$scope.navbarCollapsed = true;
$scope.isActive = function(viewLocation) {
var path = $location.path().substr(0, viewLocation.length);
if (path === viewLocation) {
// Make sure "/" only matches when viewLocation is "/".
if (!($location.path().substr(0).length > 1 && viewLocation.length === 1 )) {
return true;
var refstackApp = angular.module('refstackApp');
refstackApp.controller('headerController',
['$scope', '$location', function ($scope, $location) {
'use strict';
$scope.navbarCollapsed = true;
$scope.isActive = function (viewLocation) {
var path = $location.path().substr(0, viewLocation.length);
if (path === viewLocation) {
// Make sure "/" only matches when viewLocation is "/".
if (!($location.path().substr(0).length > 1 &&
viewLocation.length === 1 )) {
return true;
}
}
}
return false;
};
}]);
return false;
};
}]);

View File

@ -6,6 +6,7 @@
"license": "Apache2",
"devDependencies": {
"bower": "1.3.12",
"eslint": "^0.21.2",
"http-server": "^0.6.1",
"karma": "^0.12.23",
"karma-chrome-launcher": "^0.1.5",
@ -22,6 +23,7 @@
"start": "http-server ./app -a 0.0.0.0 -p 8080",
"pretest": "npm install",
"test": "karma start tests/karma.conf.js",
"test-single-run": "karma start tests/karma.conf.js --single-run"
"test-single-run": "karma start tests/karma.conf.js --single-run",
"lint": "eslint --no-color ./"
}
}

View File

@ -1,44 +1,46 @@
module.exports = function(config){
config.set({
module.exports = function (config) {
'use strict';
basePath : '../',
config.set({
files : [
// Angular libraries.
'app/assets/lib/angular/angular.js',
'app/assets/lib/angular-ui-router/release/angular-ui-router.js',
'app/assets/lib/angular-bootstrap/ui-bootstrap.min.js',
'app/assets/lib/angular-mocks/angular-mocks.js',
'app/assets/lib/angular-bootstrap/ui-bootstrap-tpls.min.js',
'app/assets/lib/angular-busy/dist/angular-busy.min.js',
basePath: '../',
// JS files.
'app/app.js',
'app/components/**/*.js',
'app/shared/*.js',
'app/shared/**/*.js',
'app/assets/js/*.js',
files: [
// Angular libraries.
'app/assets/lib/angular/angular.js',
'app/assets/lib/angular-ui-router/release/angular-ui-router.js',
'app/assets/lib/angular-bootstrap/ui-bootstrap.min.js',
'app/assets/lib/angular-mocks/angular-mocks.js',
'app/assets/lib/angular-bootstrap/ui-bootstrap-tpls.min.js',
'app/assets/lib/angular-busy/dist/angular-busy.min.js',
// Test Specs.
'tests/unit/*.js'
],
// JS files.
'app/app.js',
'app/components/**/*.js',
'app/shared/*.js',
'app/shared/**/*.js',
'app/assets/js/*.js',
autoWatch : true,
// Test Specs.
'tests/unit/*.js'
],
frameworks: ['jasmine'],
autoWatch: true,
browsers : ['Firefox'],
frameworks: ['jasmine'],
plugins : [
browsers: ['Firefox'],
plugins: [
'karma-chrome-launcher',
'karma-firefox-launcher',
'karma-jasmine',
],
'karma-jasmine'
],
junitReporter : {
outputFile: 'test_out/unit.xml',
suite: 'unit'
}
junitReporter: {
outputFile: 'test_out/unit.xml',
suite: 'unit'
}
});
});
};

View File

@ -1,225 +1,268 @@
'use strict';
/* Jasmine specs for Refstack controllers */
describe('Refstack controllers', function() {
describe('Refstack controllers', function () {
'use strict';
describe('headerController', function() {
var scope, ctrl, $location;
describe('headerController', function () {
var scope, $location;
beforeEach(module('refstackApp'));
beforeEach(inject(function($rootScope, $controller, _$location_) {
beforeEach(inject(function ($rootScope, $controller, _$location_) {
scope = $rootScope.$new();
$location = _$location_;
ctrl = $controller('headerController', {$scope: scope});
$controller('headerController', {$scope: scope});
}));
it('should set "navbarCollapsed" to true', function() {
it('should set "navbarCollapsed" to true', function () {
expect(scope.navbarCollapsed).toBe(true);
});
it('should have a function to check if the URL path is active', function() {
$location.path('/');
expect($location.path()).toBe('/');
expect(scope.isActive('/')).toBe(true);
expect(scope.isActive('/about')).toBe(false);
it('should have a function to check if the URL path is active',
function () {
$location.path('/');
expect($location.path()).toBe('/');
expect(scope.isActive('/')).toBe(true);
expect(scope.isActive('/about')).toBe(false);
$location.path('/results?cpid=123&foo=bar');
expect($location.path()).toBe('/results?cpid=123&foo=bar');
expect(scope.isActive('/results')).toBe(true);
});
$location.path('/results?cpid=123&foo=bar');
expect($location.path()).toBe('/results?cpid=123&foo=bar');
expect(scope.isActive('/results')).toBe(true);
});
});
describe('capabilitiesController', function() {
var scope, ctrl, $httpBackend, refstackApiUrl;
var fakeApiUrl = "http://foo.bar/v1";
beforeEach(function() {
describe('capabilitiesController', function () {
var scope, $httpBackend;
var fakeApiUrl = 'http://foo.bar/v1';
beforeEach(function () {
module('refstackApp');
module(function($provide) {
module(function ($provide) {
$provide.constant('refstackApiUrl', fakeApiUrl);
});
});
beforeEach(inject(function(_$httpBackend_, $rootScope, $controller) {
beforeEach(inject(function (_$httpBackend_, $rootScope, $controller) {
$httpBackend = _$httpBackend_;
scope = $rootScope.$new();
ctrl = $controller('capabilitiesController', {$scope: scope});
$controller('capabilitiesController', {$scope: scope});
}));
it('should set default states', function() {
it('should set default states', function () {
expect(scope.hideAchievements).toBe(true);
expect(scope.hideTests).toBe(true);
expect(scope.target).toBe('platform');
expect(scope.status).toEqual({required: 'required', advisory: '',
deprecated: '', removed: ''});
expect(scope.status).toEqual({
required: 'required', advisory: '',
deprecated: '', removed: ''
});
});
it('should fetch the selected capabilities version', function() {
$httpBackend.expectGET(fakeApiUrl+'/capabilities').respond(['2015.03.json', '2015.04.json']);
it('should fetch the selected capabilities version', function () {
$httpBackend.expectGET(fakeApiUrl +
'/capabilities').respond(['2015.03.json', '2015.04.json']);
// Should call request with latest version.
$httpBackend.expectGET(fakeApiUrl+'/capabilities/2015.04.json').respond({'foo': 'bar'});
$httpBackend.expectGET(fakeApiUrl +
'/capabilities/2015.04.json').respond({'foo': 'bar'});
$httpBackend.flush();
// The version list should be sorted latest first.
expect(scope.versionList).toEqual(['2015.04.json', '2015.03.json']);
expect(scope.capabilities).toEqual({'foo': 'bar'});
});
it('should have a function to check if a status filter is selected', function() {
expect(scope.filterStatus({'status': 'required'})).toBe(true);
expect(scope.filterStatus({'status': 'advisory'})).toBe(false);
expect(scope.filterStatus({'status': 'deprecated'})).toBe(false);
expect(scope.filterStatus({'status': 'removed'})).toBe(false);
it('should have a function to check if a status filter is selected',
function () {
expect(scope.filterStatus({'status': 'required'}))
.toBe(true);
expect(scope.filterStatus({'status': 'advisory'}))
.toBe(false);
expect(scope.filterStatus({'status': 'deprecated'}))
.toBe(false);
expect(scope.filterStatus({'status': 'removed'}))
.toBe(false);
scope.status = {
required: 'required',
advisory: 'advisory',
deprecated: 'deprecated',
removed: 'removed'
};
scope.status = {
required: 'required',
advisory: 'advisory',
deprecated: 'deprecated',
removed: 'removed'
};
expect(scope.filterStatus({'status': 'required'})).toBe(true);
expect(scope.filterStatus({'status': 'advisory'})).toBe(true);
expect(scope.filterStatus({'status': 'deprecated'})).toBe(true);
expect(scope.filterStatus({'status': 'removed'})).toBe(true);
});
expect(scope.filterStatus({'status': 'required'})).toBe(true);
expect(scope.filterStatus({'status': 'advisory'})).toBe(true);
expect(scope.filterStatus({'status': 'deprecated'})).toBe(true);
expect(scope.filterStatus({'status': 'removed'})).toBe(true);
});
it('should have a function to check if a capability belongs to a program', function() {
scope.capabilities = {'platform': {'required': ['compute']},
'components': {
'compute': {
'required': ['cap_id_1'],
'advisory': ['cap_id_2'],
'deprecated': ['cap_id_3'],
'removed': ['cap_id_4']
}
}};
expect(scope.filterProgram({'id': 'cap_id_1'})).toBe(true);
expect(scope.filterProgram({'id': 'cap_id_2'})).toBe(true);
expect(scope.filterProgram({'id': 'cap_id_3'})).toBe(true);
expect(scope.filterProgram({'id': 'cap_id_4'})).toBe(true);
expect(scope.filterProgram({'id': 'cap_id_5'})).toBe(false);
});
it('should have a function to check if a capability belongs' +
' to a program',
function () {
scope.capabilities = {
'platform': {'required': ['compute']},
'components': {
'compute': {
'required': ['cap_id_1'],
'advisory': ['cap_id_2'],
'deprecated': ['cap_id_3'],
'removed': ['cap_id_4']
}
}
};
expect(scope.filterProgram({'id': 'cap_id_1'})).toBe(true);
expect(scope.filterProgram({'id': 'cap_id_2'})).toBe(true);
expect(scope.filterProgram({'id': 'cap_id_3'})).toBe(true);
expect(scope.filterProgram({'id': 'cap_id_4'})).toBe(true);
expect(scope.filterProgram({'id': 'cap_id_5'})).toBe(false);
});
});
describe('resultsController', function() {
var scope, ctrl, $httpBackend, refstackApiUrl;
var fakeApiUrl = "http://foo.bar/v1";
var fakeResponse = {'pagination': {'current_page': 1, 'total_pages': 2},
'results': [{'created_at': '2015-03-09 01:23:45',
'test_id': 'some-id',
'cpid': 'some-cpid'}]};
describe('resultsController', function () {
var scope, $httpBackend;
var fakeApiUrl = 'http://foo.bar/v1';
var fakeResponse = {
'pagination': {'current_page': 1, 'total_pages': 2},
'results': [{
'created_at': '2015-03-09 01:23:45',
'test_id': 'some-id',
'cpid': 'some-cpid'
}]
};
beforeEach(function() {
beforeEach(function () {
module('refstackApp');
module(function($provide) {
module(function ($provide) {
$provide.constant('refstackApiUrl', fakeApiUrl);
});
});
beforeEach(inject(function(_$httpBackend_, $rootScope, $controller) {
beforeEach(inject(function (_$httpBackend_, $rootScope, $controller) {
$httpBackend = _$httpBackend_;
scope = $rootScope.$new();
ctrl = $controller('resultsController', {$scope: scope});
$controller('resultsController', {$scope: scope});
}));
it('should fetch the first page of results with proper URL args', function() {
// Initial results should be page 1 of all results.
$httpBackend.expectGET(fakeApiUrl+'/results?page=1').respond(fakeResponse);
$httpBackend.flush();
expect(scope.data).toEqual(fakeResponse);
expect(scope.currentPage).toBe(1);
it('should fetch the first page of results with proper URL args',
function () {
// Initial results should be page 1 of all results.
$httpBackend.expectGET(fakeApiUrl +
'/results?page=1').respond(fakeResponse);
$httpBackend.flush();
expect(scope.data).toEqual(fakeResponse);
expect(scope.currentPage).toBe(1);
// Simulate the user adding date filters.
scope.startDate = new Date('2015-03-10T11:51:00');
scope.endDate = new Date('2015-04-10T11:51:00');
scope.update();
$httpBackend.expectGET(fakeApiUrl+'/results?page=1&start_date=2015-03-10 00:00:00&end_date=2015-04-10 23:59:59').respond(fakeResponse);
$httpBackend.flush();
expect(scope.data).toEqual(fakeResponse);
expect(scope.currentPage).toBe(1);
});
// Simulate the user adding date filters.
scope.startDate = new Date('2015-03-10T11:51:00');
scope.endDate = new Date('2015-04-10T11:51:00');
scope.update();
$httpBackend.expectGET(fakeApiUrl +
'/results?page=1' +
'&start_date=2015-03-10 00:00:00' +
'&end_date=2015-04-10 23:59:59')
.respond(fakeResponse);
$httpBackend.flush();
expect(scope.data).toEqual(fakeResponse);
expect(scope.currentPage).toBe(1);
});
it('should set an error when results cannot be retrieved', function() {
$httpBackend.expectGET(fakeApiUrl+'/results?page=1').respond(404, {'detail': 'Not Found'});
it('should set an error when results cannot be retrieved', function () {
$httpBackend.expectGET(fakeApiUrl + '/results?page=1').respond(404,
{'detail': 'Not Found'});
$httpBackend.flush();
expect(scope.data).toBe(null);
expect(scope.error).toEqual('Error retrieving results listing from server: {"detail":"Not Found"}');
expect(scope.error).toEqual('Error retrieving results listing ' +
'from server: {"detail":"Not Found"}');
expect(scope.totalItems).toBe(0);
expect(scope.showError).toBe(true);
});
it('should have an function to clear filters and update the view', function() {
$httpBackend.expectGET(fakeApiUrl+'/results?page=1').respond(fakeResponse);
scope.startDate = "some date";
scope.endDate = "some other date";
scope.clearFilters();
expect(scope.startDate).toBe(null);
expect(scope.endDate).toBe(null);
$httpBackend.expectGET(fakeApiUrl+'/results?page=1').respond(fakeResponse);
$httpBackend.flush();
expect(scope.data).toEqual(fakeResponse);
});
it('should have an function to clear filters and update the view',
function () {
$httpBackend.expectGET(fakeApiUrl +
'/results?page=1').respond(fakeResponse);
scope.startDate = 'some date';
scope.endDate = 'some other date';
scope.clearFilters();
expect(scope.startDate).toBe(null);
expect(scope.endDate).toBe(null);
$httpBackend.expectGET(fakeApiUrl +
'/results?page=1').respond(fakeResponse);
$httpBackend.flush();
expect(scope.data).toEqual(fakeResponse);
});
});
describe('resultsReportController', function() {
var scope, ctrl, $httpBackend, refstackApiUrl, stateparams;
var fakeApiUrl = "http://foo.bar/v1";
var fakeResultResponse = {'results': ['test_id_1']}
var fakeCapabilityResponse = {'platform': {'required': ['compute']},
'components': {
'compute': {
'required': ['cap_id_1'],
'advisory': [],
'deprecated': [],
'removed': []
}
},
'capabilities': {
'cap_id_1': {
'status': 'required',
'flagged': [],
'tests': ['test_id_1', 'test_id_2']
}
}
};
describe('resultsReportController', function () {
var scope, $httpBackend, stateparams;
var fakeApiUrl = 'http://foo.bar/v1';
var fakeResultResponse = {'results': ['test_id_1']};
var fakeCapabilityResponse = {
'platform': {'required': ['compute']},
'components': {
'compute': {
'required': ['cap_id_1'],
'advisory': [],
'deprecated': [],
'removed': []
}
},
'capabilities': {
'cap_id_1': {
'status': 'required',
'flagged': [],
'tests': ['test_id_1', 'test_id_2']
}
}
};
beforeEach(function() {
beforeEach(function () {
module('refstackApp');
module(function($provide) {
module(function ($provide) {
$provide.constant('refstackApiUrl', fakeApiUrl);
});
});
beforeEach(inject(function(_$httpBackend_, $rootScope, $controller) {
beforeEach(inject(function (_$httpBackend_, $rootScope, $controller) {
$httpBackend = _$httpBackend_;
stateparams = {testID: 1234};
scope = $rootScope.$new();
ctrl = $controller('resultsReportController', {$scope: scope, $stateParams: stateparams});
$controller('resultsReportController',
{$scope: scope, $stateParams: stateparams});
}));
it('should make all necessary API requests to get results and capabilities', function() {
$httpBackend.expectGET(fakeApiUrl+'/results/1234').respond(fakeResultResponse);
$httpBackend.expectGET(fakeApiUrl+'/capabilities').respond(['2015.03.json', '2015.04.json']);
// Should call request with latest version.
$httpBackend.expectGET(fakeApiUrl+'/capabilities/2015.04.json').respond(fakeCapabilityResponse);
$httpBackend.flush();
expect(scope.resultsData).toEqual(fakeResultResponse);
// The version list should be sorted latest first.
expect(scope.versionList).toEqual(['2015.04.json', '2015.03.json']);
expect(scope.capabilityData).toEqual(fakeCapabilityResponse);
});
it('should make all necessary API requests to get results ' +
'and capabilities',
function () {
$httpBackend.expectGET(fakeApiUrl +
'/results/1234').respond(fakeResultResponse);
$httpBackend.expectGET(fakeApiUrl +
'/capabilities').respond(['2015.03.json', '2015.04.json']);
// Should call request with latest version.
$httpBackend.expectGET(fakeApiUrl +
'/capabilities/2015.04.json').respond(fakeCapabilityResponse);
$httpBackend.flush();
expect(scope.resultsData).toEqual(fakeResultResponse);
// The version list should be sorted latest first.
expect(scope.versionList).toEqual(['2015.04.json',
'2015.03.json']);
expect(scope.capabilityData).toEqual(fakeCapabilityResponse);
});
it('should be able to sort the results into a capability object', function() {
scope.resultsData = fakeResultResponse;
scope.capabilityData = fakeCapabilityResponse;
scope.buildCapabilityObject();
var expectedCapsObject = {'required': {'caps': [{'id': 'cap_id_1',
'passedTests': ['test_id_1'],
'notPassedTests': ['test_id_2']}],
'count': 2, 'passedCount': 1},
'advisory': {'caps': [], 'count': 0, 'passedCount': 0},
'deprecated': {'caps': [], 'count': 0, 'passedCount': 0},
'removed': {'caps': [], 'count': 0, 'passedCount': 0}};
expect(scope.caps).toEqual(expectedCapsObject);
});
it('should be able to sort the results into a capability object',
function () {
scope.resultsData = fakeResultResponse;
scope.capabilityData = fakeCapabilityResponse;
scope.buildCapabilityObject();
var expectedCapsObject = {
'required': {
'caps': [{
'id': 'cap_id_1',
'passedTests': ['test_id_1'],
'notPassedTests': ['test_id_2']
}],
'count': 2, 'passedCount': 1
},
'advisory': {'caps': [], 'count': 0, 'passedCount': 0},
'deprecated': {'caps': [], 'count': 0, 'passedCount': 0},
'removed': {'caps': [], 'count': 0, 'passedCount': 0}
};
expect(scope.caps).toEqual(expectedCapsObject);
});
});
});

View File

@ -1,19 +1,19 @@
'use strict';
/* Jasmine specs for Refstack filters */
describe('Refstack filters', function() {
describe('Refstack filters', function () {
'use strict';
describe('Filter: arrayConverter', function() {
describe('Filter: arrayConverter', function () {
var $filter;
beforeEach(module('refstackApp'));
beforeEach(inject(function(_$filter_) {
beforeEach(inject(function (_$filter_) {
$filter = _$filter_('arrayConverter');
}));
it('should convert dict to array of dict values', function () {
var object = { 'id1': {'key1': 'value1'}, 'id2': {'key2': 'value2'}};
var object = {'id1': {'key1': 'value1'}, 'id2': {'key2': 'value2'}};
var expected = [{'key1': 'value1', 'id': 'id1'},
{'key2': 'value2', 'id': 'id2'}];
{'key2': 'value2', 'id': 'id2'}];
expect($filter(object)).toEqual(expected);
});
});