Bri Prebilic Cole

GUI -- Cleaned up table directives, device view, fixed flash-spec unit tests, st…

…arted unt tests for table.js.

Change-Id: I3020fec5f3f57cebc237c1a6cbfd07deb3607189
......@@ -28,10 +28,6 @@ svg.embeddedIcon .icon .glyph {
fill-rule: evenodd;
}
div.inline-icon {
display: inline-block;
}
.light svg.embeddedIcon .icon.deviceOnline,
.light svg.embeddedIcon .icon.deviceOffline {
fill: none;
......
......@@ -34,8 +34,7 @@
devIcon_SWITCH: 'switch',
tableColSortAsc: 'triangleUp',
tableColSortDesc: 'triangleDown',
tableColSortNone: '-'
tableColSortDesc: 'triangleDown'
};
......@@ -86,15 +85,13 @@
rx: cornerSize
});
if (gid !== '-') {
g.append('use').attr({
width: vboxSize,
height: vboxSize,
'class': 'glyph',
'xlink:href': '#' + gid
});
}
}
}
function loadEmbeddedIcon(div, iconCls, size) {
loadIcon(div, iconCls, size, true);
......
......@@ -21,51 +21,11 @@
'use strict';
var $log, $window, fs, is,
div,
currCol = {},
prevCol = {},
tableIconTdSize = 30,
tableIconTdSize = 33,
bottomMargin = 200;
// Render a plain d3 table by giving it the div, a config file, and data
function renderTable(div, config, data) {
var table = div.append('table'),
colIds = config.colIds,
colText = config.colText,
dataObjects = data[Object.keys(data)[0]],
thead, tbody, tRows;
thead = table.append('thead');
tbody = table.append('tbody');
thead.append('tr').selectAll('th')
.data(colText)
.enter()
.append('th')
.text(function(d) { return d });
tRows = tbody.selectAll('tr')
.data(dataObjects)
.enter()
.append('tr');
tRows.selectAll('td')
.data(function(row) {
return colIds.map(function(headerId) {
return {
column: headerId, value: row[headerId]
};
});
})
.enter()
.append('td')
.html(function(d) { return d.value });
return table;
}
// Functions for creating a fixed header on a table (Angular Directive)
function setTableWidth(t) {
......@@ -106,7 +66,10 @@
setTableHeight(th, tb);
}
// Functions for sorting table rows by header and choosing appropriate icon
function updateSortingIcons(thElem, api) {
var div;
currCol.colId = thElem.attr('colId');
if (currCol.colId === prevCol.colId) {
......@@ -120,7 +83,7 @@
}
div = thElem.select('div');
div.remove();
api.sortNone(div);
div = thElem.append('div');
if (currCol.icon === 'tableColSortAsc') {
......@@ -151,15 +114,8 @@
}
angular.module('onosWidget')
.factory('TableService', [function () {
return {
renderTable: renderTable
};
}])
.directive('onosFixedHeader', ['$window', '$timeout',
'MastService', 'FnService',
function (_$window_, $timeout, mast, _fs_) {
.directive('onosFixedHeader', ['$window', 'FnService',
function (_$window_, _fs_) {
return function (scope, element) {
$window = _$window_;
fs = _fs_;
......@@ -206,7 +162,7 @@
scope: {
ctrlCallback: '&sortCallback'
},
link: function (scope, element, attrs) {
link: function (scope, element) {
$log = _$log_;
is = _is_;
var table = d3.select(element[0]),
......@@ -219,7 +175,6 @@
if (thElem.attr('sortable') === '') {
updateSortingIcons(thElem, sortIconAPI);
// call the ctrl's rest callback function
scope.ctrlCallback({
urlSuffix: generateQueryParams()
});
......
......@@ -27,20 +27,15 @@
var self = this;
self.deviceData = [];
// TODO: remove test code
var testCase = $location.search().test;
var url = testCase ? 'test/' + testCase : 'device';
$scope.sortCallback = function (urlSuffix) {
if (!urlSuffix) {
urlSuffix = '';
}
url = 'device' + urlSuffix;
var url = 'device' + urlSuffix;
rs.get(url, function (data) {
self.deviceData = data.devices;
});
};
$scope.sortCallback();
$log.log('OvDeviceCtrl has been created');
......
......@@ -27,11 +27,13 @@ describe('factory: fw/layer/flash.js', function () {
$timeout = _$timeout_;
fs = FnService;
flash = FlashService;
jasmine.clock().install();
d3Elem = d3.select('body').append('div').attr('id', 'myflashdiv');
flash.initFlash();
}));
afterEach(function () {
jasmine.clock().uninstall();
d3.select('#myflashdiv').remove();
});
......@@ -56,6 +58,7 @@ describe('factory: fw/layer/flash.js', function () {
it('should flash the message Foo', function () {
var item, rect, text;
flash.flash('foo');
jasmine.clock().tick(101);
setTimeout(function () {
item = flashItemSelection();
expect(item.size()).toEqual(1);
......@@ -64,9 +67,6 @@ describe('factory: fw/layer/flash.js', function () {
text = item.select('text');
expect(text.size()).toEqual(1);
expect(text.text()).toEqual('foo');
}, 2000);
}, 100);
});
// TODO: testing these time-sensitive behaviors is hard...
// need to work on this some other time.
});
......
......@@ -17,116 +17,94 @@
/*
ONOS GUI -- Widget -- Table Service - Unit Tests
*/
describe('factory: fw/widget/table.js', function() {
var ts, $log, d3Elem;
describe('factory: fw/widget/table.js', function () {
var $log, $compile, $rootScope,
fs, is,
table;
var config = {
colIds: ['id', 'mfr', 'hw', 'sw', 'serial', 'annotations.protocol'],
colText: ['URI', 'Vendor', 'Hardware Version', 'Software Version',
'Serial Number', 'Protocol']
},
fakeData = {
"devices": [{
"id": "of:0000000000000001",
"available": true,
"_iconid_available": "deviceOnline",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
"sw": "2.0.1",
"serial": "None",
"annotations": {
"protocol": "OF_10"
}
},
{
"id": "of:0000000000000004",
"available": false,
"_iconid_available": "deviceOffline",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
"sw": "2.0.1",
"serial": "None",
"annotations": {
"protocol": "OF_10"
}
},
{
"id": "of:0000000000000092",
"available": false,
"_iconid_available": "deviceOffline",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
"sw": "2.0.1",
"serial": "None",
"annotations": {
"protocol": "OF_10"
}
}]
};
var onosFixedHeaderTags = '<table ' +
'onos-fixed-header ' +
'ng-style="setTableHW()">' +
'<thead>' +
'<tr>' +
'<th></th>' +
'<th>Device ID </th>' +
'<th>H/W Version </th>' +
'<th>S/W Version </th>' +
'</tr>' +
'</thead>' +
'<tbody>' +
'<tr>' +
'<td>' +
'<div icon icon-id="{{dev._iconid_available}}">' +
'</div>' +
'</td>' +
'<td>Some ID</td>' +
'<td>Some HW</td>' +
'<td>Some Software</td>' +
'</tr>' +
'</tbody>' +
'</table>',
beforeEach(module('onosWidget'));
onosSortableHeaderTags = '<table class="summary-list" ' +
'onos-sortable-header ' +
'sort-callback="sortCallback(urlSuffix)">' +
'<thead>' +
'<tr>' +
'<th colId="available"></th>' +
'<th colId="id" sortable>Device ID </th>' +
'<th colId="hw" sortable>H/W Version </th>' +
'<th colId="sw" sortable>S/W Version </th>' +
'</tr>' +
'</thead>' +
'<tbody>' +
'<tr>' +
'<td>' +
'<div icon icon-id="{{dev._iconid_available}}">' +
'</div>' +
'</td>' +
'<td>Some ID</td>' +
'<td>Some HW</td>' +
'<td>Some Software</td>' +
'</tr>' +
'</tbody>' +
'</table>';
beforeEach(inject(function (TableService, _$log_) {
ts = TableService;
beforeEach(module('onosWidget', 'onosUtil', 'onosSvg'));
beforeEach(inject(function (_$log_, _$compile_, _$rootScope_,
FnService, IconService) {
$log = _$log_;
d3Elem = d3.select('body').append('div').attr('id', 'myDiv');
$compile = _$compile_;
$rootScope = _$rootScope_;
fs = FnService;
is = IconService;
}));
afterEach(function () {
d3.select('#myDiv').remove();
beforeEach(function () {
});
it('should define TableService', function () {
expect(ts).toBeDefined();
afterEach(function () {
table = null;
});
function verifyTableTags(div) {
var table = div.select('table'),
tableHeaders;
expect(table).toBeTruthy();
expect(table.attr('fixed-header')).toBeFalsy();
expect(table.select('thead')).toBeTruthy();
expect(table.select('tbody')).toBeTruthy();
it('should affirm that onos-fixed-header is working', function () {
table = $compile(onosFixedHeaderTags)($rootScope);
$rootScope.$digest();
tableHeaders = table.select('thead').selectAll('th');
tableHeaders.each(function(thElement, i) {
thElement = d3.select(this);
expect(thElement).toBeTruthy();
expect(thElement.html()).toBe(config.colText[i]);
});
}
table = d3.select(table);
expect(table).toBeDefined();
function verifyData(div) {
var tbody = div.select('tbody'),
tableBoxes = tbody.selectAll('td');
expect(tbody).toBeTruthy();
expect(tbody.select('tr')).toBeTruthy();
tableBoxes.each(function(tdElement, i){
tdElement = d3.select(this);
if(i === 0) {
expect(tdElement.html()).toBe('of:0000000000000001');
}
if(i === 1) {
expect(tdElement.html()).toBe('Nicira, Inc.');
}
if(i === 2) {
expect(tdElement.html()).toBe('Open vSwitch');
}
expect(tdElement).toBeTruthy();
//expect(table.select('thead').style('display')).toBe('block');
});
}
it('should create table tags', function () {
ts.renderTable(d3Elem, config, fakeData);
verifyTableTags(d3Elem);
});
it('should affirm that onos-sortable-header is working', function () {
table = $compile(onosSortableHeaderTags)($rootScope);
$rootScope.$digest();
it('should load data into table', function () {
ts.renderTable(d3Elem, config, fakeData);
verifyData(d3Elem);
table = d3.select(table);
expect(table).toBeDefined();
});
// TODO: write directive unit tests for table.js
});
......
......@@ -45,14 +45,16 @@ describe('Controller: OvDeviceCtrl', function () {
$scope = $rootScope.$new();
$controller = _$controller_;
$mockHttp = $httpBackend;
}));
beforeEach(function() {
$scope = {};
ctrl = $controller('OvDeviceCtrl', { $scope: $scope });
$mockHttp.whenGET(/\/device$/).respond(fakeData);
}));
});
it('should be an empty array and then have device data', function () {
ctrl = $controller('OvDeviceCtrl', {
$scope: $scope
});
expect(ctrl.deviceData).toEqual([]);
$scope.sortCallback();
$mockHttp.flush();
......