Merge pull request #962 from nasa/csv-export-update-751
[Timeline] Updates to CSV Export
This commit is contained in:
@@ -91,7 +91,12 @@ define([
|
|||||||
"name": "Export Timeline as CSV",
|
"name": "Export Timeline as CSV",
|
||||||
"category": "contextual",
|
"category": "contextual",
|
||||||
"implementation": ExportTimelineAsCSVAction,
|
"implementation": ExportTimelineAsCSVAction,
|
||||||
"depends": ["exportService", "notificationService"]
|
"depends": [
|
||||||
|
"$log",
|
||||||
|
"exportService",
|
||||||
|
"notificationService",
|
||||||
|
"resources[]"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"constants": [
|
"constants": [
|
||||||
|
|||||||
@@ -27,11 +27,15 @@ define([], function () {
|
|||||||
* in a domain object's composition.
|
* in a domain object's composition.
|
||||||
* @param {number} index the zero-based index of the composition
|
* @param {number} index the zero-based index of the composition
|
||||||
* element associated with this column
|
* element associated with this column
|
||||||
|
* @param idMap an object containing key value pairs, where keys
|
||||||
|
* are domain object identifiers and values are whatever
|
||||||
|
* should appear in CSV output in their place
|
||||||
* @constructor
|
* @constructor
|
||||||
* @implements {platform/features/timeline.TimelineCSVColumn}
|
* @implements {platform/features/timeline.TimelineCSVColumn}
|
||||||
*/
|
*/
|
||||||
function CompositionColumn(index) {
|
function CompositionColumn(index, idMap) {
|
||||||
this.index = index;
|
this.index = index;
|
||||||
|
this.idMap = idMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
CompositionColumn.prototype.name = function () {
|
CompositionColumn.prototype.name = function () {
|
||||||
@@ -41,7 +45,9 @@ define([], function () {
|
|||||||
CompositionColumn.prototype.value = function (domainObject) {
|
CompositionColumn.prototype.value = function (domainObject) {
|
||||||
var model = domainObject.getModel(),
|
var model = domainObject.getModel(),
|
||||||
composition = model.composition || [];
|
composition = model.composition || [];
|
||||||
return (composition[this.index]) || "";
|
|
||||||
|
return composition.length > this.index ?
|
||||||
|
this.idMap[composition[this.index]] : "";
|
||||||
};
|
};
|
||||||
|
|
||||||
return CompositionColumn;
|
return CompositionColumn;
|
||||||
|
|||||||
@@ -27,14 +27,23 @@ define(["./ExportTimelineAsCSVTask"], function (ExportTimelineAsCSVTask) {
|
|||||||
*
|
*
|
||||||
* @param exportService the service used to perform the CSV export
|
* @param exportService the service used to perform the CSV export
|
||||||
* @param notificationService the service used to show notifications
|
* @param notificationService the service used to show notifications
|
||||||
|
* @param {Array} resources an array of `resources` extensions
|
||||||
* @param context the Action's context
|
* @param context the Action's context
|
||||||
* @implements {Action}
|
* @implements {Action}
|
||||||
* @constructor
|
* @constructor
|
||||||
* @memberof {platform/features/timeline}
|
* @memberof {platform/features/timeline}
|
||||||
*/
|
*/
|
||||||
function ExportTimelineAsCSVAction(exportService, notificationService, context) {
|
function ExportTimelineAsCSVAction(
|
||||||
|
$log,
|
||||||
|
exportService,
|
||||||
|
notificationService,
|
||||||
|
resources,
|
||||||
|
context
|
||||||
|
) {
|
||||||
|
this.$log = $log;
|
||||||
this.task = new ExportTimelineAsCSVTask(
|
this.task = new ExportTimelineAsCSVTask(
|
||||||
exportService,
|
exportService,
|
||||||
|
resources,
|
||||||
context.domainObject
|
context.domainObject
|
||||||
);
|
);
|
||||||
this.notificationService = notificationService;
|
this.notificationService = notificationService;
|
||||||
@@ -45,13 +54,15 @@ define(["./ExportTimelineAsCSVTask"], function (ExportTimelineAsCSVTask) {
|
|||||||
notification = notificationService.notify({
|
notification = notificationService.notify({
|
||||||
title: "Exporting CSV",
|
title: "Exporting CSV",
|
||||||
unknownProgress: true
|
unknownProgress: true
|
||||||
});
|
}),
|
||||||
|
$log = this.$log;
|
||||||
|
|
||||||
return this.task.run()
|
return this.task.run()
|
||||||
.then(function () {
|
.then(function () {
|
||||||
notification.dismiss();
|
notification.dismiss();
|
||||||
})
|
})
|
||||||
.catch(function () {
|
.catch(function (err) {
|
||||||
|
$log.warn(err);
|
||||||
notification.dismiss();
|
notification.dismiss();
|
||||||
notificationService.error("Error exporting CSV");
|
notificationService.error("Error exporting CSV");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -35,11 +35,13 @@ define([
|
|||||||
* @constructor
|
* @constructor
|
||||||
* @memberof {platform/features/timeline}
|
* @memberof {platform/features/timeline}
|
||||||
* @param exportService the service used to export as CSV
|
* @param exportService the service used to export as CSV
|
||||||
|
* @param resources the `resources` extension category
|
||||||
* @param {DomainObject} domainObject the timeline being exported
|
* @param {DomainObject} domainObject the timeline being exported
|
||||||
*/
|
*/
|
||||||
function ExportTimelineAsCSVTask(exportService, domainObject) {
|
function ExportTimelineAsCSVTask(exportService, resources, domainObject) {
|
||||||
this.domainObject = domainObject;
|
this.domainObject = domainObject;
|
||||||
this.exportService = exportService;
|
this.exportService = exportService;
|
||||||
|
this.resources = resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,9 +52,10 @@ define([
|
|||||||
*/
|
*/
|
||||||
ExportTimelineAsCSVTask.prototype.run = function () {
|
ExportTimelineAsCSVTask.prototype.run = function () {
|
||||||
var exportService = this.exportService;
|
var exportService = this.exportService;
|
||||||
|
var resources = this.resources;
|
||||||
|
|
||||||
function doExport(objects) {
|
function doExport(objects) {
|
||||||
var exporter = new TimelineColumnizer(objects),
|
var exporter = new TimelineColumnizer(objects, resources),
|
||||||
options = { headers: exporter.headers() };
|
options = { headers: exporter.headers() };
|
||||||
return exporter.rows().then(function (rows) {
|
return exporter.rows().then(function (rows) {
|
||||||
return exportService.exportCSV(rows, options);
|
return exportService.exportCSV(rows, options);
|
||||||
|
|||||||
@@ -23,19 +23,23 @@
|
|||||||
define([], function () {
|
define([], function () {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A column showing domain object identifiers.
|
* A column showing identifying domain objects.
|
||||||
* @constructor
|
* @constructor
|
||||||
|
* @param idMap an object containing key value pairs, where keys
|
||||||
|
* are domain object identifiers and values are whatever
|
||||||
|
* should appear in CSV output in their place
|
||||||
* @implements {platform/features/timeline.TimelineCSVColumn}
|
* @implements {platform/features/timeline.TimelineCSVColumn}
|
||||||
*/
|
*/
|
||||||
function IdColumn() {
|
function IdColumn(idMap) {
|
||||||
|
this.idMap = idMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
IdColumn.prototype.name = function () {
|
IdColumn.prototype.name = function () {
|
||||||
return "Identifier";
|
return "Index";
|
||||||
};
|
};
|
||||||
|
|
||||||
IdColumn.prototype.value = function (domainObject) {
|
IdColumn.prototype.value = function (domainObject) {
|
||||||
return domainObject.getId();
|
return this.idMap[domainObject.getId()];
|
||||||
};
|
};
|
||||||
|
|
||||||
return IdColumn;
|
return IdColumn;
|
||||||
|
|||||||
@@ -27,10 +27,14 @@ define([], function () {
|
|||||||
* @constructor
|
* @constructor
|
||||||
* @param {number} index the zero-based index of the composition
|
* @param {number} index the zero-based index of the composition
|
||||||
* element associated with this column
|
* element associated with this column
|
||||||
|
* @param idMap an object containing key value pairs, where keys
|
||||||
|
* are domain object identifiers and values are whatever
|
||||||
|
* should appear in CSV output in their place
|
||||||
* @implements {platform/features/timeline.TimelineCSVColumn}
|
* @implements {platform/features/timeline.TimelineCSVColumn}
|
||||||
*/
|
*/
|
||||||
function ModeColumn(index) {
|
function ModeColumn(index, idMap) {
|
||||||
this.index = index;
|
this.index = index;
|
||||||
|
this.idMap = idMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModeColumn.prototype.name = function () {
|
ModeColumn.prototype.name = function () {
|
||||||
@@ -39,8 +43,9 @@ define([], function () {
|
|||||||
|
|
||||||
ModeColumn.prototype.value = function (domainObject) {
|
ModeColumn.prototype.value = function (domainObject) {
|
||||||
var model = domainObject.getModel(),
|
var model = domainObject.getModel(),
|
||||||
composition = (model.relationships || {}).modes || [];
|
modes = (model.relationships || {}).modes || [];
|
||||||
return (composition[this.index]) || "";
|
return modes.length > this.index ?
|
||||||
|
this.idMap[modes[this.index]] : "";
|
||||||
};
|
};
|
||||||
|
|
||||||
return ModeColumn;
|
return ModeColumn;
|
||||||
|
|||||||
@@ -25,13 +25,15 @@ define([
|
|||||||
"./ModeColumn",
|
"./ModeColumn",
|
||||||
"./CompositionColumn",
|
"./CompositionColumn",
|
||||||
"./MetadataColumn",
|
"./MetadataColumn",
|
||||||
"./TimespanColumn"
|
"./TimespanColumn",
|
||||||
|
"./UtilizationColumn"
|
||||||
], function (
|
], function (
|
||||||
IdColumn,
|
IdColumn,
|
||||||
ModeColumn,
|
ModeColumn,
|
||||||
CompositionColumn,
|
CompositionColumn,
|
||||||
MetadataColumn,
|
MetadataColumn,
|
||||||
TimespanColumn
|
TimespanColumn,
|
||||||
|
UtilizationColumn
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,15 +65,17 @@ define([
|
|||||||
*
|
*
|
||||||
* @param {DomainObject[]} domainObjects the objects to include
|
* @param {DomainObject[]} domainObjects the objects to include
|
||||||
* in the exported data
|
* in the exported data
|
||||||
|
* @param {Array} resources an array of `resources` extensions
|
||||||
* @constructor
|
* @constructor
|
||||||
* @memberof {platform/features/timeline}
|
* @memberof {platform/features/timeline}
|
||||||
*/
|
*/
|
||||||
function TimelineColumnizer(domainObjects) {
|
function TimelineColumnizer(domainObjects, resources) {
|
||||||
var maxComposition = 0,
|
var maxComposition = 0,
|
||||||
maxRelationships = 0,
|
maxRelationships = 0,
|
||||||
columnNames = {},
|
columnNames = {},
|
||||||
columns = [],
|
columns = [],
|
||||||
foundTimespan = false,
|
foundTimespan = false,
|
||||||
|
idMap,
|
||||||
i;
|
i;
|
||||||
|
|
||||||
function addMetadataProperty(property) {
|
function addMetadataProperty(property) {
|
||||||
@@ -82,7 +86,12 @@ define([
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
columns.push(new IdColumn());
|
idMap = domainObjects.reduce(function (map, domainObject, index) {
|
||||||
|
map[domainObject.getId()] = index + 1;
|
||||||
|
return map;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
columns.push(new IdColumn(idMap));
|
||||||
|
|
||||||
domainObjects.forEach(function (domainObject) {
|
domainObjects.forEach(function (domainObject) {
|
||||||
var model = domainObject.getModel(),
|
var model = domainObject.getModel(),
|
||||||
@@ -113,12 +122,16 @@ define([
|
|||||||
columns.push(new TimespanColumn(false));
|
columns.push(new TimespanColumn(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resources.forEach(function (resource) {
|
||||||
|
columns.push(new UtilizationColumn(resource));
|
||||||
|
});
|
||||||
|
|
||||||
for (i = 0; i < maxComposition; i += 1) {
|
for (i = 0; i < maxComposition; i += 1) {
|
||||||
columns.push(new CompositionColumn(i));
|
columns.push(new CompositionColumn(i, idMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < maxRelationships; i += 1) {
|
for (i = 0; i < maxRelationships; i += 1) {
|
||||||
columns.push(new ModeColumn(i));
|
columns.push(new ModeColumn(i, idMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.domainObjects = domainObjects;
|
this.domainObjects = domainObjects;
|
||||||
|
|||||||
72
platform/features/timeline/src/actions/UtilizationColumn.js
Normal file
72
platform/features/timeline/src/actions/UtilizationColumn.js
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2009-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web is 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.
|
||||||
|
*
|
||||||
|
* Open MCT Web includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
define([], function () {
|
||||||
|
/**
|
||||||
|
* A column showing utilization costs associated with activities.
|
||||||
|
* @constructor
|
||||||
|
* @param {string} key the key for the particular cost
|
||||||
|
* @implements {platform/features/timeline.TimelineCSVColumn}
|
||||||
|
*/
|
||||||
|
function UtilizationColumn(resource) {
|
||||||
|
this.resource = resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
UtilizationColumn.prototype.name = function () {
|
||||||
|
var units = {
|
||||||
|
"Kbps": "Kb",
|
||||||
|
"watts": "watt-seconds"
|
||||||
|
}[this.resource.units] || "unknown units";
|
||||||
|
|
||||||
|
return this.resource.name + " (" + units + ")";
|
||||||
|
};
|
||||||
|
|
||||||
|
UtilizationColumn.prototype.value = function (domainObject) {
|
||||||
|
var resource = this.resource;
|
||||||
|
|
||||||
|
function getCost(utilization) {
|
||||||
|
var seconds = (utilization.end - utilization.start) / 1000;
|
||||||
|
return seconds * utilization.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUtilizationValue(utilizations) {
|
||||||
|
utilizations = utilizations.filter(function (utilization) {
|
||||||
|
return utilization.key === resource.key;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (utilizations.length === 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return utilizations.map(getCost).reduce(function (a, b) {
|
||||||
|
return a + b;
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return domainObject.hasCapability('utilization') ?
|
||||||
|
domainObject.getCapability('utilization').internal()
|
||||||
|
.then(getUtilizationValue) :
|
||||||
|
"";
|
||||||
|
};
|
||||||
|
|
||||||
|
return UtilizationColumn;
|
||||||
|
});
|
||||||
@@ -193,6 +193,13 @@ define(
|
|||||||
* @returns {Promise.<string[]>} a promise for resource identifiers
|
* @returns {Promise.<string[]>} a promise for resource identifiers
|
||||||
*/
|
*/
|
||||||
resources: promiseResourceKeys,
|
resources: promiseResourceKeys,
|
||||||
|
/**
|
||||||
|
* Get the resource utilization associated with this object
|
||||||
|
* directly, not including any resource utilization associated
|
||||||
|
* with contained objects.
|
||||||
|
* @returns {Promise.<Array>}
|
||||||
|
*/
|
||||||
|
internal: promiseInternalUtilization,
|
||||||
/**
|
/**
|
||||||
* Get the resource utilization associated with this
|
* Get the resource utilization associated with this
|
||||||
* object. Results are not sorted. This requires looking
|
* object. Results are not sorted. This requires looking
|
||||||
|
|||||||
@@ -23,13 +23,20 @@
|
|||||||
define(
|
define(
|
||||||
['../../src/actions/CompositionColumn'],
|
['../../src/actions/CompositionColumn'],
|
||||||
function (CompositionColumn) {
|
function (CompositionColumn) {
|
||||||
|
var TEST_IDS = ['a', 'b', 'c', 'd', 'e', 'f'];
|
||||||
|
|
||||||
describe("CompositionColumn", function () {
|
describe("CompositionColumn", function () {
|
||||||
var testIndex,
|
var testIndex,
|
||||||
|
testIdMap,
|
||||||
column;
|
column;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
testIndex = 3;
|
testIndex = 3;
|
||||||
column = new CompositionColumn(testIndex);
|
testIdMap = TEST_IDS.reduce(function (map, id, index) {
|
||||||
|
map[id] = index;
|
||||||
|
return map;
|
||||||
|
}, {});
|
||||||
|
column = new CompositionColumn(testIndex, testIdMap);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("includes a one-based index in its name", function () {
|
it("includes a one-based index in its name", function () {
|
||||||
@@ -46,15 +53,13 @@ define(
|
|||||||
'domainObject',
|
'domainObject',
|
||||||
['getId', 'getModel', 'getCapability']
|
['getId', 'getModel', 'getCapability']
|
||||||
);
|
);
|
||||||
testModel = {
|
testModel = { composition: TEST_IDS };
|
||||||
composition: ['a', 'b', 'c', 'd', 'e', 'f']
|
|
||||||
};
|
|
||||||
mockDomainObject.getModel.andReturn(testModel);
|
mockDomainObject.getModel.andReturn(testModel);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns a corresponding identifier", function () {
|
it("returns a corresponding value from the map", function () {
|
||||||
expect(column.value(mockDomainObject))
|
expect(column.value(mockDomainObject))
|
||||||
.toEqual(testModel.composition[testIndex]);
|
.toEqual(testIdMap[testModel.composition[testIndex]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns nothing when composition is exceeded", function () {
|
it("returns nothing when composition is exceeded", function () {
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ define(
|
|||||||
['../../src/actions/ExportTimelineAsCSVAction'],
|
['../../src/actions/ExportTimelineAsCSVAction'],
|
||||||
function (ExportTimelineAsCSVAction) {
|
function (ExportTimelineAsCSVAction) {
|
||||||
describe("ExportTimelineAsCSVAction", function () {
|
describe("ExportTimelineAsCSVAction", function () {
|
||||||
var mockExportService,
|
var mockLog,
|
||||||
|
mockExportService,
|
||||||
mockNotificationService,
|
mockNotificationService,
|
||||||
mockNotification,
|
mockNotification,
|
||||||
mockDomainObject,
|
mockDomainObject,
|
||||||
@@ -39,6 +40,13 @@ define(
|
|||||||
['getId', 'getModel', 'getCapability', 'hasCapability']
|
['getId', 'getModel', 'getCapability', 'hasCapability']
|
||||||
);
|
);
|
||||||
mockType = jasmine.createSpyObj('type', ['instanceOf']);
|
mockType = jasmine.createSpyObj('type', ['instanceOf']);
|
||||||
|
|
||||||
|
mockLog = jasmine.createSpyObj('$log', [
|
||||||
|
'warn',
|
||||||
|
'error',
|
||||||
|
'info',
|
||||||
|
'debug'
|
||||||
|
]);
|
||||||
mockExportService = jasmine.createSpyObj(
|
mockExportService = jasmine.createSpyObj(
|
||||||
'exportService',
|
'exportService',
|
||||||
['exportCSV']
|
['exportCSV']
|
||||||
@@ -63,8 +71,10 @@ define(
|
|||||||
testContext = { domainObject: mockDomainObject };
|
testContext = { domainObject: mockDomainObject };
|
||||||
|
|
||||||
action = new ExportTimelineAsCSVAction(
|
action = new ExportTimelineAsCSVAction(
|
||||||
|
mockLog,
|
||||||
mockExportService,
|
mockExportService,
|
||||||
mockNotificationService,
|
mockNotificationService,
|
||||||
|
[],
|
||||||
testContext
|
testContext
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -129,8 +139,11 @@ define(
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("and an error occurs", function () {
|
describe("and an error occurs", function () {
|
||||||
|
var testError;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
testPromise.reject();
|
testError = { someProperty: "some value" };
|
||||||
|
testPromise.reject(testError);
|
||||||
waitsFor(function () {
|
waitsFor(function () {
|
||||||
return mockCallback.calls.length > 0;
|
return mockCallback.calls.length > 0;
|
||||||
});
|
});
|
||||||
@@ -145,6 +158,10 @@ define(
|
|||||||
expect(mockNotificationService.error)
|
expect(mockNotificationService.error)
|
||||||
.toHaveBeenCalledWith(jasmine.any(String));
|
.toHaveBeenCalledWith(jasmine.any(String));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("logs the root cause", function () {
|
||||||
|
expect(mockLog.warn).toHaveBeenCalledWith(testError);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ define(
|
|||||||
|
|
||||||
task = new ExportTimelineAsCSVTask(
|
task = new ExportTimelineAsCSVTask(
|
||||||
mockExportService,
|
mockExportService,
|
||||||
|
[],
|
||||||
mockDomainObject
|
mockDomainObject
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -24,10 +24,12 @@ define(
|
|||||||
['../../src/actions/IdColumn'],
|
['../../src/actions/IdColumn'],
|
||||||
function (IdColumn) {
|
function (IdColumn) {
|
||||||
describe("IdColumn", function () {
|
describe("IdColumn", function () {
|
||||||
var column;
|
var testIdMap,
|
||||||
|
column;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
column = new IdColumn();
|
testIdMap = { "foo": "bar" };
|
||||||
|
column = new IdColumn(testIdMap);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("has a name", function () {
|
it("has a name", function () {
|
||||||
@@ -47,9 +49,9 @@ define(
|
|||||||
mockDomainObject.getId.andReturn(testId);
|
mockDomainObject.getId.andReturn(testId);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("provides a domain object's identifier", function () {
|
it("provides a value mapped from domain object's identifier", function () {
|
||||||
expect(column.value(mockDomainObject))
|
expect(column.value(mockDomainObject))
|
||||||
.toEqual(testId);
|
.toEqual(testIdMap[testId]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -23,13 +23,20 @@
|
|||||||
define(
|
define(
|
||||||
['../../src/actions/ModeColumn'],
|
['../../src/actions/ModeColumn'],
|
||||||
function (ModeColumn) {
|
function (ModeColumn) {
|
||||||
|
var TEST_IDS = ['a', 'b', 'c', 'd', 'e', 'f'];
|
||||||
|
|
||||||
describe("ModeColumn", function () {
|
describe("ModeColumn", function () {
|
||||||
var testIndex,
|
var testIndex,
|
||||||
|
testIdMap,
|
||||||
column;
|
column;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
testIndex = 3;
|
testIndex = 3;
|
||||||
column = new ModeColumn(testIndex);
|
testIdMap = TEST_IDS.reduce(function (map, id, index) {
|
||||||
|
map[id] = index;
|
||||||
|
return map;
|
||||||
|
}, {});
|
||||||
|
column = new ModeColumn(testIndex, testIdMap);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("includes a one-based index in its name", function () {
|
it("includes a one-based index in its name", function () {
|
||||||
@@ -48,15 +55,15 @@ define(
|
|||||||
);
|
);
|
||||||
testModel = {
|
testModel = {
|
||||||
relationships: {
|
relationships: {
|
||||||
modes: ['a', 'b', 'c', 'd', 'e', 'f']
|
modes: TEST_IDS
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
mockDomainObject.getModel.andReturn(testModel);
|
mockDomainObject.getModel.andReturn(testModel);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns a corresponding identifier", function () {
|
it("returns a corresponding value from the map", function () {
|
||||||
expect(column.value(mockDomainObject))
|
expect(column.value(mockDomainObject))
|
||||||
.toEqual(testModel.relationships.modes[testIndex]);
|
.toEqual(testIdMap[testModel.relationships.modes[testIndex]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns nothing when relationships are exceeded", function () {
|
it("returns nothing when relationships are exceeded", function () {
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ define(
|
|||||||
return c === 'metadata' && testMetadata;
|
return c === 'metadata' && testMetadata;
|
||||||
});
|
});
|
||||||
|
|
||||||
exporter = new TimelineColumnizer(mockDomainObjects);
|
exporter = new TimelineColumnizer(mockDomainObjects, []);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("rows", function () {
|
describe("rows", function () {
|
||||||
@@ -94,13 +94,6 @@ define(
|
|||||||
it("include one row per domain object", function () {
|
it("include one row per domain object", function () {
|
||||||
expect(rows.length).toEqual(mockDomainObjects.length);
|
expect(rows.length).toEqual(mockDomainObjects.length);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("includes identifiers for each domain object", function () {
|
|
||||||
rows.forEach(function (row, index) {
|
|
||||||
var id = mockDomainObjects[index].getId();
|
|
||||||
expect(row.indexOf(id)).not.toEqual(-1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("headers", function () {
|
describe("headers", function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user