2015-02-19 17:13:45 +00:00
|
|
|
/*global define,describe,it,expect,beforeEach,jasmine,xit*/
|
2015-02-17 17:03:23 +00:00
|
|
|
|
|
|
|
define(
|
|
|
|
["../src/FixedController"],
|
|
|
|
function (FixedController) {
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
describe("The Fixed Position controller", function () {
|
|
|
|
var mockScope,
|
2015-02-20 23:53:41 +00:00
|
|
|
mockQ,
|
|
|
|
mockDialogService,
|
2015-02-17 17:03:23 +00:00
|
|
|
mockSubscriber,
|
|
|
|
mockFormatter,
|
|
|
|
mockDomainObject,
|
|
|
|
mockSubscription,
|
|
|
|
testGrid,
|
|
|
|
testModel,
|
|
|
|
testValues,
|
2015-02-20 00:24:45 +00:00
|
|
|
testConfiguration,
|
2015-02-17 17:03:23 +00:00
|
|
|
controller;
|
|
|
|
|
|
|
|
// Utility function; find a watch for a given expression
|
|
|
|
function findWatch(expr) {
|
|
|
|
var watch;
|
|
|
|
mockScope.$watch.calls.forEach(function (call) {
|
|
|
|
if (call.args[0] === expr) {
|
|
|
|
watch = call.args[1];
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return watch;
|
|
|
|
}
|
|
|
|
|
2015-02-17 18:50:02 +00:00
|
|
|
// As above, but for $on calls
|
|
|
|
function findOn(expr) {
|
|
|
|
var on;
|
|
|
|
mockScope.$on.calls.forEach(function (call) {
|
|
|
|
if (call.args[0] === expr) {
|
|
|
|
on = call.args[1];
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return on;
|
|
|
|
}
|
|
|
|
|
2015-02-17 17:03:23 +00:00
|
|
|
function makeMockDomainObject(id) {
|
|
|
|
var mockObject = jasmine.createSpyObj(
|
|
|
|
'domainObject-' + id,
|
2015-02-20 00:24:45 +00:00
|
|
|
[ 'getId', 'getModel' ]
|
2015-02-17 17:03:23 +00:00
|
|
|
);
|
|
|
|
mockObject.getId.andReturn(id);
|
2015-02-20 00:24:45 +00:00
|
|
|
mockObject.getModel.andReturn({ name: "Point " + id});
|
2015-02-17 17:03:23 +00:00
|
|
|
return mockObject;
|
|
|
|
}
|
|
|
|
|
|
|
|
beforeEach(function () {
|
|
|
|
mockScope = jasmine.createSpyObj(
|
|
|
|
'$scope',
|
2015-02-17 18:50:02 +00:00
|
|
|
[ "$on", "$watch", "commit" ]
|
2015-02-17 17:03:23 +00:00
|
|
|
);
|
|
|
|
mockSubscriber = jasmine.createSpyObj(
|
|
|
|
'telemetrySubscriber',
|
|
|
|
[ 'subscribe' ]
|
|
|
|
);
|
2015-02-20 23:53:41 +00:00
|
|
|
mockQ = jasmine.createSpyObj('$q', ['when']);
|
|
|
|
mockDialogService = jasmine.createSpyObj(
|
|
|
|
'dialogService',
|
|
|
|
['getUserInput']
|
|
|
|
);
|
2015-02-17 17:03:23 +00:00
|
|
|
mockFormatter = jasmine.createSpyObj(
|
|
|
|
'telemetryFormatter',
|
|
|
|
[ 'formatDomainValue', 'formatRangeValue' ]
|
|
|
|
);
|
|
|
|
mockDomainObject = jasmine.createSpyObj(
|
|
|
|
'domainObject',
|
|
|
|
[ 'getId', 'getModel', 'getCapability' ]
|
|
|
|
);
|
|
|
|
mockSubscription = jasmine.createSpyObj(
|
|
|
|
'subscription',
|
|
|
|
[ 'unsubscribe', 'getTelemetryObjects', 'getRangeValue' ]
|
|
|
|
);
|
|
|
|
|
|
|
|
testGrid = [ 123, 456 ];
|
|
|
|
testModel = {
|
|
|
|
composition: ['a', 'b', 'c'],
|
|
|
|
layoutGrid: testGrid
|
|
|
|
};
|
|
|
|
testValues = { a: 10, b: 42, c: 31.42 };
|
2015-02-20 00:24:45 +00:00
|
|
|
testConfiguration = { elements: [
|
|
|
|
{ type: "fixed.telemetry", id: 'a', x: 1, y: 1 },
|
|
|
|
{ type: "fixed.telemetry", id: 'b', x: 1, y: 1 },
|
|
|
|
{ type: "fixed.telemetry", id: 'c', x: 1, y: 1 }
|
|
|
|
]};
|
2015-02-17 17:03:23 +00:00
|
|
|
|
|
|
|
mockSubscriber.subscribe.andReturn(mockSubscription);
|
|
|
|
mockSubscription.getTelemetryObjects.andReturn(
|
|
|
|
testModel.composition.map(makeMockDomainObject)
|
|
|
|
);
|
|
|
|
mockSubscription.getRangeValue.andCallFake(function (o) {
|
|
|
|
return testValues[o.getId()];
|
|
|
|
});
|
|
|
|
mockFormatter.formatRangeValue.andCallFake(function (v) {
|
|
|
|
return "Formatted " + v;
|
|
|
|
});
|
2015-02-19 18:22:12 +00:00
|
|
|
mockScope.model = testModel;
|
2015-02-20 00:24:45 +00:00
|
|
|
mockScope.configuration = testConfiguration;
|
2015-03-04 02:47:44 +00:00
|
|
|
mockScope.selection = jasmine.createSpyObj(
|
|
|
|
'selection',
|
2015-03-04 02:52:13 +00:00
|
|
|
[ 'select', 'get', 'selected', 'deselect', 'proxy' ]
|
2015-03-04 02:47:44 +00:00
|
|
|
);
|
2015-02-17 17:03:23 +00:00
|
|
|
|
|
|
|
controller = new FixedController(
|
|
|
|
mockScope,
|
2015-02-20 23:53:41 +00:00
|
|
|
mockQ,
|
|
|
|
mockDialogService,
|
2015-02-17 17:03:23 +00:00
|
|
|
mockSubscriber,
|
|
|
|
mockFormatter
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
it("provides styles for cells", function () {
|
|
|
|
expect(controller.getCellStyles())
|
|
|
|
.toEqual(jasmine.any(Array));
|
|
|
|
});
|
|
|
|
|
|
|
|
it("subscribes when a domain object is available", function () {
|
|
|
|
mockScope.domainObject = mockDomainObject;
|
|
|
|
findWatch("domainObject")(mockDomainObject);
|
|
|
|
expect(mockSubscriber.subscribe).toHaveBeenCalledWith(
|
|
|
|
mockDomainObject,
|
|
|
|
jasmine.any(Function)
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2015-02-20 00:24:45 +00:00
|
|
|
it("releases subscriptions when domain objects change", function () {
|
2015-02-17 17:03:23 +00:00
|
|
|
mockScope.domainObject = mockDomainObject;
|
|
|
|
|
|
|
|
// First pass - should simply should subscribe
|
|
|
|
findWatch("domainObject")(mockDomainObject);
|
|
|
|
expect(mockSubscription.unsubscribe).not.toHaveBeenCalled();
|
|
|
|
expect(mockSubscriber.subscribe.calls.length).toEqual(1);
|
|
|
|
|
|
|
|
// Object changes - should unsubscribe then resubscribe
|
|
|
|
findWatch("domainObject")(mockDomainObject);
|
|
|
|
expect(mockSubscription.unsubscribe).toHaveBeenCalled();
|
|
|
|
expect(mockSubscriber.subscribe.calls.length).toEqual(2);
|
|
|
|
});
|
|
|
|
|
2015-02-20 00:24:45 +00:00
|
|
|
it("exposes visible elements based on configuration", function () {
|
|
|
|
var elements;
|
|
|
|
|
2015-02-17 17:03:23 +00:00
|
|
|
mockScope.model = testModel;
|
2015-02-20 00:24:45 +00:00
|
|
|
testModel.modified = 1;
|
|
|
|
findWatch("model.modified")(testModel.modified);
|
|
|
|
|
|
|
|
elements = controller.getElements();
|
|
|
|
expect(elements.length).toEqual(3);
|
|
|
|
expect(elements[0].id).toEqual('a');
|
|
|
|
expect(elements[1].id).toEqual('b');
|
|
|
|
expect(elements[2].id).toEqual('c');
|
|
|
|
});
|
|
|
|
|
|
|
|
it("allows elements to be selected", function () {
|
|
|
|
var elements;
|
|
|
|
|
|
|
|
testModel.modified = 1;
|
|
|
|
findWatch("model.modified")(testModel.modified);
|
|
|
|
|
|
|
|
elements = controller.getElements();
|
|
|
|
controller.select(elements[1]);
|
2015-03-04 02:47:44 +00:00
|
|
|
expect(mockScope.selection.select)
|
|
|
|
.toHaveBeenCalledWith(elements[1]);
|
2015-02-20 00:24:45 +00:00
|
|
|
});
|
|
|
|
|
2015-02-24 18:12:33 +00:00
|
|
|
it("allows selection retrieval", function () {
|
|
|
|
// selected with no arguments should give the current
|
|
|
|
// selection
|
|
|
|
var elements;
|
|
|
|
|
|
|
|
testModel.modified = 1;
|
|
|
|
findWatch("model.modified")(testModel.modified);
|
|
|
|
|
|
|
|
elements = controller.getElements();
|
|
|
|
controller.select(elements[1]);
|
2015-03-04 23:08:11 +00:00
|
|
|
mockScope.selection.get.andReturn(elements[1]);
|
2015-02-24 18:12:33 +00:00
|
|
|
expect(controller.selected()).toEqual(elements[1]);
|
|
|
|
});
|
|
|
|
|
2015-02-20 00:24:45 +00:00
|
|
|
it("allows selections to be cleared", function () {
|
|
|
|
var elements;
|
|
|
|
|
|
|
|
testModel.modified = 1;
|
|
|
|
findWatch("model.modified")(testModel.modified);
|
|
|
|
|
|
|
|
elements = controller.getElements();
|
|
|
|
controller.select(elements[1]);
|
|
|
|
controller.clearSelection();
|
|
|
|
expect(controller.selected(elements[1])).toBeFalsy();
|
|
|
|
});
|
|
|
|
|
|
|
|
it("retains selections during refresh", function () {
|
|
|
|
// Get elements; remove one of them; trigger refresh.
|
|
|
|
// Same element (at least by index) should still be selected.
|
|
|
|
var elements;
|
|
|
|
|
|
|
|
testModel.modified = 1;
|
|
|
|
findWatch("model.modified")(testModel.modified);
|
|
|
|
|
|
|
|
elements = controller.getElements();
|
|
|
|
controller.select(elements[1]);
|
|
|
|
|
2015-03-04 02:47:44 +00:00
|
|
|
// Verify precondition
|
|
|
|
expect(mockScope.selection.select.calls.length).toEqual(1);
|
|
|
|
|
|
|
|
// Mimic selection behavior
|
|
|
|
mockScope.selection.get.andReturn(elements[1]);
|
|
|
|
|
2015-02-20 00:24:45 +00:00
|
|
|
elements[2].remove();
|
|
|
|
testModel.modified = 2;
|
|
|
|
findWatch("model.modified")(testModel.modified);
|
|
|
|
|
|
|
|
elements = controller.getElements();
|
|
|
|
// Verify removal, as test assumes this
|
|
|
|
expect(elements.length).toEqual(2);
|
|
|
|
|
2015-03-04 02:47:44 +00:00
|
|
|
expect(mockScope.selection.select.calls.length).toEqual(2);
|
2015-02-17 17:03:23 +00:00
|
|
|
});
|
|
|
|
|
2015-02-20 00:24:45 +00:00
|
|
|
it("provides values for telemetry elements", function () {
|
|
|
|
var elements;
|
2015-02-17 17:03:23 +00:00
|
|
|
// Initialize
|
|
|
|
mockScope.domainObject = mockDomainObject;
|
|
|
|
mockScope.model = testModel;
|
|
|
|
findWatch("domainObject")(mockDomainObject);
|
2015-02-20 00:24:45 +00:00
|
|
|
findWatch("model.modified")(1);
|
2015-02-17 18:34:13 +00:00
|
|
|
findWatch("model.composition")(mockScope.model.composition);
|
2015-02-17 17:03:23 +00:00
|
|
|
|
|
|
|
// Invoke the subscription callback
|
|
|
|
mockSubscriber.subscribe.mostRecentCall.args[1]();
|
|
|
|
|
2015-02-20 00:24:45 +00:00
|
|
|
// Get elements that controller is now exposing
|
|
|
|
elements = controller.getElements();
|
|
|
|
|
2015-02-17 17:03:23 +00:00
|
|
|
// Formatted values should be available
|
2015-02-20 00:24:45 +00:00
|
|
|
expect(elements[0].value).toEqual("Formatted 10");
|
|
|
|
expect(elements[1].value).toEqual("Formatted 42");
|
|
|
|
expect(elements[2].value).toEqual("Formatted 31.42");
|
2015-02-17 17:03:23 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
it("adds grid cells to fill boundaries", function () {
|
|
|
|
var s1 = {
|
|
|
|
width: testGrid[0] * 8,
|
|
|
|
height: testGrid[1] * 4
|
|
|
|
},
|
|
|
|
s2 = {
|
|
|
|
width: testGrid[0] * 10,
|
|
|
|
height: testGrid[1] * 6
|
|
|
|
};
|
|
|
|
|
|
|
|
mockScope.model = testModel;
|
2015-02-17 18:34:13 +00:00
|
|
|
findWatch("model.composition")(mockScope.model.composition);
|
2015-02-17 17:03:23 +00:00
|
|
|
|
|
|
|
// Set first bounds
|
|
|
|
controller.setBounds(s1);
|
|
|
|
expect(controller.getCellStyles().length).toEqual(32); // 8 * 4
|
|
|
|
// Set new bounds
|
|
|
|
controller.setBounds(s2);
|
|
|
|
expect(controller.getCellStyles().length).toEqual(60); // 10 * 6
|
|
|
|
});
|
2015-02-17 18:50:02 +00:00
|
|
|
|
2015-02-20 00:24:45 +00:00
|
|
|
it("listens for drop events", function () {
|
2015-02-17 18:50:02 +00:00
|
|
|
// Layout should position panels according to
|
|
|
|
// where the user dropped them, so it needs to
|
|
|
|
// listen for drop events.
|
|
|
|
expect(mockScope.$on).toHaveBeenCalledWith(
|
|
|
|
'mctDrop',
|
|
|
|
jasmine.any(Function)
|
|
|
|
);
|
|
|
|
|
|
|
|
// Verify precondition
|
2015-02-20 00:24:45 +00:00
|
|
|
expect(testConfiguration.elements.length).toEqual(3);
|
2015-02-17 18:50:02 +00:00
|
|
|
|
|
|
|
// Notify that a drop occurred
|
|
|
|
testModel.composition.push('d');
|
|
|
|
findOn('mctDrop')(
|
|
|
|
{},
|
|
|
|
'd',
|
|
|
|
{ x: 300, y: 100 }
|
|
|
|
);
|
2015-02-20 00:24:45 +00:00
|
|
|
|
|
|
|
// Should have added an element
|
|
|
|
expect(testConfiguration.elements.length).toEqual(4);
|
2015-02-17 18:50:02 +00:00
|
|
|
|
|
|
|
// Should have triggered commit (provided by
|
|
|
|
// EditRepresenter) with some message.
|
|
|
|
expect(mockScope.commit)
|
|
|
|
.toHaveBeenCalledWith(jasmine.any(String));
|
|
|
|
});
|
2015-02-20 00:24:45 +00:00
|
|
|
|
|
|
|
it("unsubscribes when destroyed", function () {
|
|
|
|
// Make an object available
|
|
|
|
findWatch('domainObject')(mockDomainObject);
|
|
|
|
// Also verify precondition
|
|
|
|
expect(mockSubscription.unsubscribe).not.toHaveBeenCalled();
|
|
|
|
// Destroy the scope
|
|
|
|
findOn('$destroy')();
|
|
|
|
// Should have unsubscribed
|
|
|
|
expect(mockSubscription.unsubscribe).toHaveBeenCalled();
|
|
|
|
});
|
2015-02-20 23:59:22 +00:00
|
|
|
|
|
|
|
it("exposes its grid size", function () {
|
|
|
|
// Template needs to be able to pass this into line
|
|
|
|
// elements to size SVGs appropriately
|
|
|
|
expect(controller.getGridSize()).toEqual(testGrid);
|
|
|
|
});
|
2015-03-04 02:52:13 +00:00
|
|
|
|
|
|
|
it("exposes a view-level selection proxy", function () {
|
|
|
|
expect(mockScope.selection.proxy).toHaveBeenCalledWith(
|
|
|
|
jasmine.any(Object)
|
|
|
|
);
|
|
|
|
});
|
2015-03-04 23:08:11 +00:00
|
|
|
|
2015-02-24 18:12:33 +00:00
|
|
|
it("exposes drag handles", function () {
|
|
|
|
var handles;
|
|
|
|
|
|
|
|
// Select something so that drag handles are expected
|
|
|
|
testModel.modified = 1;
|
|
|
|
findWatch("model.modified")(testModel.modified);
|
|
|
|
controller.select(controller.getElements()[1]);
|
|
|
|
|
|
|
|
// Should have a non-empty array of handles
|
|
|
|
handles = controller.handles();
|
|
|
|
expect(handles).toEqual(jasmine.any(Array));
|
|
|
|
expect(handles.length).not.toEqual(0);
|
|
|
|
|
|
|
|
// And they should have start/continue/end drag methods
|
|
|
|
handles.forEach(function (handle) {
|
|
|
|
expect(handle.startDrag).toEqual(jasmine.any(Function));
|
|
|
|
expect(handle.continueDrag).toEqual(jasmine.any(Function));
|
|
|
|
expect(handle.endDrag).toEqual(jasmine.any(Function));
|
|
|
|
});
|
|
|
|
});
|
2015-02-24 20:02:43 +00:00
|
|
|
|
|
|
|
it("exposes a move handle", function () {
|
|
|
|
var handle;
|
|
|
|
|
|
|
|
// Select something so that drag handles are expected
|
|
|
|
testModel.modified = 1;
|
|
|
|
findWatch("model.modified")(testModel.modified);
|
|
|
|
controller.select(controller.getElements()[1]);
|
|
|
|
|
|
|
|
// Should have a move handle
|
|
|
|
handle = controller.moveHandle();
|
|
|
|
|
|
|
|
// And it should have start/continue/end drag methods
|
|
|
|
expect(handle.startDrag).toEqual(jasmine.any(Function));
|
|
|
|
expect(handle.continueDrag).toEqual(jasmine.any(Function));
|
|
|
|
expect(handle.endDrag).toEqual(jasmine.any(Function));
|
|
|
|
});
|
|
|
|
|
|
|
|
it("updates selection style during drag", function () {
|
|
|
|
var oldStyle;
|
|
|
|
|
|
|
|
// Select something so that drag handles are expected
|
|
|
|
testModel.modified = 1;
|
|
|
|
findWatch("model.modified")(testModel.modified);
|
|
|
|
controller.select(controller.getElements()[1]);
|
2015-03-04 23:08:11 +00:00
|
|
|
mockScope.selection.get.andReturn(controller.getElements()[1]);
|
2015-02-24 20:02:43 +00:00
|
|
|
|
|
|
|
// Get style
|
|
|
|
oldStyle = controller.selected().style;
|
|
|
|
|
|
|
|
// Start a drag gesture
|
|
|
|
controller.moveHandle().startDrag();
|
|
|
|
|
|
|
|
// Haven't moved yet; style shouldn't have updated yet
|
|
|
|
expect(controller.selected().style).toEqual(oldStyle);
|
|
|
|
|
|
|
|
// Drag a little
|
|
|
|
controller.moveHandle().continueDrag([ 1000, 100 ]);
|
|
|
|
|
|
|
|
// Style should have been updated
|
|
|
|
expect(controller.selected().style).not.toEqual(oldStyle);
|
|
|
|
});
|
2015-02-17 17:03:23 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
);
|