mirror of
https://github.com/mapillary/mapillary-js.git
synced 2026-01-18 13:56:53 +00:00
839 lines
39 KiB
TypeScript
839 lines
39 KiB
TypeScript
|
|
import { of as observableOf, ReplaySubject, Subject, VirtualTimeScheduler } from "rxjs";
|
|
|
|
import { ContainerMockCreator } from "../../helper/ContainerMockCreator";
|
|
import { MockCreator } from "../../helper/MockCreator";
|
|
import { NavigatorMockCreator } from "../../helper/NavigatorMockCreator";
|
|
import { NodeHelper } from "../../helper/NodeHelper";
|
|
|
|
import { Navigator } from "../../../src/viewer/Navigator";
|
|
import { Node } from "../../../src/graph/Node";
|
|
import { SequenceComponent } from "../../../src/component/sequence/SequenceComponent";
|
|
import { SequenceDOMRenderer } from "../../../src/component/sequence/SequenceDOMRenderer";
|
|
import { GraphMode } from "../../../src/graph/GraphMode";
|
|
import { NavigationEdgeStatus } from "../../../src/graph/interfaces/NavigationEdgeStatus";
|
|
import { Sequence } from "../../../src/graph/Sequence";
|
|
import { ViewportSize } from "../../../src/render/interfaces/ViewportSize";
|
|
import { State } from "../../../src/state/State";
|
|
import { Container } from "../../../src/viewer/Container";
|
|
|
|
describe("SequenceComponent.ctor", () => {
|
|
it("should be defined", () => {
|
|
const sequenceComponent: SequenceComponent =
|
|
new SequenceComponent(
|
|
SequenceComponent.componentName,
|
|
new ContainerMockCreator().create(),
|
|
new NavigatorMockCreator().create());
|
|
|
|
expect(sequenceComponent).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe("SequenceComponent.deactivate", () => {
|
|
it("should deactivate properly", () => {
|
|
const component: SequenceComponent =
|
|
new SequenceComponent(
|
|
SequenceComponent.componentName,
|
|
new ContainerMockCreator().create(),
|
|
new NavigatorMockCreator().create());
|
|
|
|
component.activate();
|
|
component.deactivate();
|
|
});
|
|
});
|
|
|
|
describe("SequenceComponent.activate", () => {
|
|
let mockCreator: MockCreator;
|
|
let containerMock: Container;
|
|
let navigatorMock: Navigator;
|
|
let nodeHelper: NodeHelper;
|
|
|
|
let renderer: SequenceDOMRenderer;
|
|
|
|
beforeEach((): void => {
|
|
mockCreator = new MockCreator();
|
|
containerMock = new ContainerMockCreator().create();
|
|
navigatorMock = new NavigatorMockCreator().create();
|
|
nodeHelper = new NodeHelper();
|
|
|
|
renderer = new SequenceDOMRenderer(containerMock);
|
|
});
|
|
|
|
const createComponent: () => SequenceComponent = (): SequenceComponent => {
|
|
const component: SequenceComponent = new SequenceComponent(
|
|
SequenceComponent.componentName,
|
|
containerMock,
|
|
navigatorMock,
|
|
renderer);
|
|
|
|
return component;
|
|
};
|
|
|
|
it("should set graph mode to sequence when changing position", () => {
|
|
const setGraphModeSpy: jasmine.Spy = <jasmine.Spy>navigatorMock.graphService.setGraphMode;
|
|
|
|
const changingPositionChangedSubject$: Subject<boolean> = new Subject<boolean>();
|
|
mockCreator.mockProperty(renderer, "changingPositionChanged$", changingPositionChangedSubject$);
|
|
|
|
const component: SequenceComponent = createComponent();
|
|
component.activate();
|
|
|
|
changingPositionChangedSubject$.next(true);
|
|
|
|
expect(setGraphModeSpy.calls.count()).toBe(1);
|
|
expect(setGraphModeSpy.calls.argsFor(0)[0]).toBe(GraphMode.Sequence);
|
|
});
|
|
|
|
it("should set graph mode to spatial when not changing position", () => {
|
|
const setGraphModeSpy: jasmine.Spy = <jasmine.Spy>navigatorMock.graphService.setGraphMode;
|
|
|
|
const changingPositionChangedSubject$: Subject<boolean> = new Subject<boolean>();
|
|
mockCreator.mockProperty(renderer, "changingPositionChanged$", changingPositionChangedSubject$);
|
|
|
|
const component: SequenceComponent = createComponent();
|
|
component.activate();
|
|
|
|
changingPositionChangedSubject$.next(false);
|
|
|
|
expect(setGraphModeSpy.calls.count()).toBe(1);
|
|
expect(setGraphModeSpy.calls.argsFor(0)[0]).toBe(GraphMode.Spatial);
|
|
});
|
|
|
|
it("should stop play when changing position", () => {
|
|
const stopSpy: jasmine.Spy = <jasmine.Spy>navigatorMock.playService.stop;
|
|
|
|
const changedSubject$: Subject<SequenceDOMRenderer> = new Subject<SequenceDOMRenderer>();
|
|
mockCreator.mockProperty(renderer, "changed$", changedSubject$);
|
|
const changingPositionChangedSubject$: Subject<boolean> = new Subject<boolean>();
|
|
mockCreator.mockProperty(renderer, "changingPositionChanged$", changingPositionChangedSubject$);
|
|
|
|
const component: SequenceComponent = createComponent();
|
|
component.activate();
|
|
|
|
const count: number = stopSpy.calls.count();
|
|
|
|
changingPositionChangedSubject$.next(true);
|
|
|
|
expect(stopSpy.calls.count() - count).toBe(1);
|
|
});
|
|
|
|
it("should cache two nodes when graph mode changes to spatial if not spatial edges cached", () => {
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequence$).and.returnValue(new Subject<Sequence>());
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequenceNodes$).and.returnValue(new Subject<Sequence>());
|
|
|
|
const cacheNodeSpy: jasmine.Spy = <jasmine.Spy>navigatorMock.graphService.cacheNode$;
|
|
cacheNodeSpy.and.returnValue(new Subject<Node>());
|
|
|
|
const component: SequenceComponent = createComponent();
|
|
component.activate();
|
|
|
|
const graphModeSubject$: Subject<GraphMode> = <Subject<GraphMode>>navigatorMock.graphService.graphMode$;
|
|
graphModeSubject$.next(GraphMode.Spatial);
|
|
|
|
const node1: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node1, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node1, "sequenceEdges$", new Subject<NavigationEdgeStatus>());
|
|
mockCreator.mockProperty(node1, "id", "nodeKey1");
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node1);
|
|
|
|
expect(cacheNodeSpy.calls.count()).toBe(1);
|
|
expect(cacheNodeSpy.calls.argsFor(0)[0]).toBe(node1.id);
|
|
|
|
const node2: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node2, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node2, "sequenceEdges$", new Subject<NavigationEdgeStatus>());
|
|
mockCreator.mockProperty(node2, "id", "nodeKey2");
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node2);
|
|
|
|
expect(cacheNodeSpy.calls.count()).toBe(2);
|
|
expect(cacheNodeSpy.calls.argsFor(1)[0]).toBe(node2.id);
|
|
|
|
const node3: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node3, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node3, "sequenceEdges$", new Subject<NavigationEdgeStatus>());
|
|
mockCreator.mockProperty(node3, "id", "nodeKey2");
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node3);
|
|
|
|
expect(cacheNodeSpy.calls.count()).toBe(2);
|
|
});
|
|
|
|
it("should cache sequence when sequence key of current node changes", () => {
|
|
const cacheSequenceSpy: jasmine.Spy = <jasmine.Spy>navigatorMock.graphService.cacheSequence$;
|
|
cacheSequenceSpy.and.returnValue(new Subject<Sequence>());
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequenceNodes$).and.returnValue(new Subject<Sequence>());
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheNode$).and.returnValue(new Subject<Node>());
|
|
|
|
const component: SequenceComponent = createComponent();
|
|
component.activate();
|
|
|
|
const graphModeSubject$: Subject<GraphMode> = <Subject<GraphMode>>navigatorMock.graphService.graphMode$;
|
|
graphModeSubject$.next(GraphMode.Spatial);
|
|
|
|
const node1: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node1, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node1, "sequenceEdges$", new Subject<NavigationEdgeStatus>());
|
|
mockCreator.mockProperty(node1, "id", "nodeKey1");
|
|
mockCreator.mockProperty(node1, "sequenceId", "sequenceKey1");
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node1);
|
|
|
|
expect(cacheSequenceSpy.calls.count()).toBe(1);
|
|
expect(cacheSequenceSpy.calls.argsFor(0)[0]).toBe("sequenceKey1");
|
|
|
|
const node2: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node2, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node2, "sequenceEdges$", new Subject<NavigationEdgeStatus>());
|
|
mockCreator.mockProperty(node2, "id", "nodeKey2");
|
|
mockCreator.mockProperty(node2, "sequenceId", "sequenceKey1");
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node2);
|
|
|
|
expect(cacheSequenceSpy.calls.count()).toBe(1);
|
|
|
|
const node3: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node3, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node3, "sequenceEdges$", new Subject<NavigationEdgeStatus>());
|
|
mockCreator.mockProperty(node3, "id", "nodeKey3");
|
|
mockCreator.mockProperty(node3, "sequenceId", "sequenceKey2");
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node3);
|
|
|
|
expect(cacheSequenceSpy.calls.count()).toBe(2);
|
|
expect(cacheSequenceSpy.calls.argsFor(1)[0]).toBe("sequenceKey2");
|
|
});
|
|
|
|
it("should cache sequence nodes when changing and in sequence graph mode", () => {
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequence$).and.returnValue(new Subject<Sequence>());
|
|
const cacheSequenceNodesSpy: jasmine.Spy = <jasmine.Spy>navigatorMock.graphService.cacheSequenceNodes$;
|
|
cacheSequenceNodesSpy.and.returnValue(new Subject<Sequence>());
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheNode$).and.returnValue(new Subject<Node>());
|
|
|
|
const changedSubject$: Subject<SequenceDOMRenderer> = new Subject<SequenceDOMRenderer>();
|
|
mockCreator.mockProperty(renderer, "changed$", changedSubject$);
|
|
const changingPositionChangedSubject$: Subject<boolean> = new Subject<boolean>();
|
|
mockCreator.mockProperty(renderer, "changingPositionChanged$", changingPositionChangedSubject$);
|
|
|
|
const component: SequenceComponent = createComponent();
|
|
component.activate();
|
|
|
|
const node1: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node1, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node1, "sequenceEdges$", new Subject<NavigationEdgeStatus>());
|
|
mockCreator.mockProperty(node1, "id", "nodeKey1");
|
|
mockCreator.mockProperty(node1, "sequenceId", "sequenceKey1");
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node1);
|
|
|
|
const graphModeSubject$: Subject<GraphMode> = <Subject<GraphMode>>navigatorMock.graphService.graphMode$;
|
|
graphModeSubject$.next(GraphMode.Sequence);
|
|
|
|
changingPositionChangedSubject$.next(true);
|
|
changedSubject$.next(renderer);
|
|
|
|
expect(cacheSequenceNodesSpy.calls.count()).toBe(1);
|
|
expect(cacheSequenceNodesSpy.calls.argsFor(0)[0]).toBe("sequenceKey1");
|
|
expect(cacheSequenceNodesSpy.calls.argsFor(0)[1]).toBe("nodeKey1");
|
|
|
|
changedSubject$.next(renderer);
|
|
|
|
expect(cacheSequenceNodesSpy.calls.count()).toBe(1);
|
|
|
|
changingPositionChangedSubject$.next(false);
|
|
|
|
expect(cacheSequenceNodesSpy.calls.count()).toBe(1);
|
|
|
|
graphModeSubject$.next(GraphMode.Spatial);
|
|
|
|
expect(cacheSequenceNodesSpy.calls.count()).toBe(1);
|
|
|
|
graphModeSubject$.next(GraphMode.Sequence);
|
|
|
|
expect(cacheSequenceNodesSpy.calls.count()).toBe(1);
|
|
|
|
changingPositionChangedSubject$.next(true);
|
|
|
|
expect(cacheSequenceNodesSpy.calls.count()).toBe(2);
|
|
expect(cacheSequenceNodesSpy.calls.argsFor(1)[0]).toBe("sequenceKey1");
|
|
expect(cacheSequenceNodesSpy.calls.argsFor(1)[1]).toBe("nodeKey1");
|
|
});
|
|
|
|
it("should render null index and null max when sequence is not cached", () => {
|
|
const cacheSequenceSpy: jasmine.Spy = <jasmine.Spy>navigatorMock.graphService.cacheSequence$;
|
|
cacheSequenceSpy.and.returnValue(new Subject<Sequence>());
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequenceNodes$).and.returnValue(new Subject<Sequence>());
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheNode$).and.returnValue(new Subject<Node>());
|
|
|
|
const changedSubject$: Subject<SequenceDOMRenderer> = new Subject<SequenceDOMRenderer>();
|
|
mockCreator.mockProperty(renderer, "changed$", changedSubject$);
|
|
spyOn(renderer, "getContainerWidth").and.returnValue(100);
|
|
|
|
const renderSpy: jasmine.Spy = spyOn(renderer, "render").and.stub();
|
|
|
|
const component: SequenceComponent = createComponent();
|
|
component.activate();
|
|
|
|
(<Subject<State>>navigatorMock.stateService.state$).next(State.Traversing);
|
|
(<Subject<number>>navigatorMock.playService.speed$).next(1);
|
|
(<Subject<ViewportSize>>containerMock.renderService.size$).next({ height: 1, width: 1 });
|
|
|
|
const node1: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node1, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node1, "sequenceEdges$", observableOf({ cached: false, edges: [] }));
|
|
mockCreator.mockProperty(node1, "id", "nodeKey1");
|
|
mockCreator.mockProperty(node1, "sequenceId", "sequenceKey1");
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node1);
|
|
|
|
expect(renderSpy.calls.count()).toBe(1);
|
|
expect(renderSpy.calls.argsFor(0)[4]).toBe(null);
|
|
expect(renderSpy.calls.argsFor(0)[5]).toBe(null);
|
|
});
|
|
|
|
it("should render 0 index and 0 max when sequence is cached with single node", () => {
|
|
const sequenceSubject$: Subject<Sequence> = new Subject<Sequence>();
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequence$).and.returnValue(sequenceSubject$);
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequenceNodes$).and.returnValue(new Subject<Sequence>());
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheNode$).and.returnValue(new Subject<Node>());
|
|
|
|
const changedSubject$: Subject<SequenceDOMRenderer> = new Subject<SequenceDOMRenderer>();
|
|
mockCreator.mockProperty(renderer, "changed$", changedSubject$);
|
|
spyOn(renderer, "getContainerWidth").and.returnValue(100);
|
|
|
|
const renderSpy: jasmine.Spy = spyOn(renderer, "render").and.stub();
|
|
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$) = new ReplaySubject<Node>(1);
|
|
|
|
const component: SequenceComponent = createComponent();
|
|
component.activate();
|
|
|
|
(<Subject<State>>navigatorMock.stateService.state$).next(State.Traversing);
|
|
(<Subject<number>>navigatorMock.playService.speed$).next(1);
|
|
(<Subject<ViewportSize>>containerMock.renderService.size$).next({ height: 1, width: 1 });
|
|
|
|
const sequenceKey1: string = "sequenceKey1";
|
|
const nodeKey1: string = "nodeKey1";
|
|
|
|
const node1: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node1, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node1, "sequenceEdges$", observableOf({ cached: false, edges: [] }));
|
|
mockCreator.mockProperty(node1, "id", nodeKey1);
|
|
mockCreator.mockProperty(node1, "sequenceId", sequenceKey1);
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node1);
|
|
|
|
expect(renderSpy.calls.count()).toBe(1);
|
|
|
|
sequenceSubject$.next(new Sequence({ id: sequenceKey1, image_ids: [nodeKey1] }));
|
|
|
|
expect(renderSpy.calls.count()).toBe(2);
|
|
expect(renderSpy.calls.argsFor(1)[4]).toBe(0);
|
|
expect(renderSpy.calls.argsFor(1)[5]).toBe(0);
|
|
});
|
|
|
|
it("should render correct index on new node emit", () => {
|
|
const sequenceSubject$: Subject<Sequence> = new Subject<Sequence>();
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequence$).and.returnValue(sequenceSubject$);
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequenceNodes$).and.returnValue(new Subject<Sequence>());
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheNode$).and.returnValue(new Subject<Node>());
|
|
|
|
const changedSubject$: Subject<SequenceDOMRenderer> = new Subject<SequenceDOMRenderer>();
|
|
mockCreator.mockProperty(renderer, "changed$", changedSubject$);
|
|
spyOn(renderer, "getContainerWidth").and.returnValue(100);
|
|
|
|
const renderSpy: jasmine.Spy = spyOn(renderer, "render").and.stub();
|
|
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$) = new ReplaySubject<Node>(1);
|
|
|
|
const component: SequenceComponent = createComponent();
|
|
component.activate();
|
|
|
|
(<Subject<State>>navigatorMock.stateService.state$).next(State.Traversing);
|
|
(<Subject<number>>navigatorMock.playService.speed$).next(1);
|
|
(<Subject<ViewportSize>>containerMock.renderService.size$).next({ height: 1, width: 1 });
|
|
|
|
const sequenceKey1: string = "sequenceKey1";
|
|
const nodeKey1: string = "nodeKey1";
|
|
const nodeKey2: string = "nodeKey2";
|
|
|
|
const node1: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node1, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node1, "sequenceEdges$", observableOf({ cached: false, edges: [] }));
|
|
mockCreator.mockProperty(node1, "id", nodeKey1);
|
|
mockCreator.mockProperty(node1, "sequenceId", sequenceKey1);
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node1);
|
|
|
|
expect(renderSpy.calls.count()).toBe(1);
|
|
|
|
sequenceSubject$.next(new Sequence({ id: sequenceKey1, image_ids: [nodeKey1, nodeKey2] }));
|
|
|
|
expect(renderSpy.calls.count()).toBe(2);
|
|
expect(renderSpy.calls.argsFor(1)[4]).toBe(0);
|
|
expect(renderSpy.calls.argsFor(1)[5]).toBe(1);
|
|
|
|
const node2: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node2, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node2, "sequenceEdges$", observableOf({ cached: false, edges: [] }));
|
|
mockCreator.mockProperty(node2, "id", nodeKey2);
|
|
mockCreator.mockProperty(node2, "sequenceId", sequenceKey1);
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node2);
|
|
|
|
expect(renderSpy.calls.count()).toBe(4);
|
|
expect(renderSpy.calls.mostRecent().args[4]).toBe(1);
|
|
expect(renderSpy.calls.mostRecent().args[5]).toBe(1);
|
|
});
|
|
|
|
it("should render correct index on sequence change when changing position simultaneously", () => {
|
|
const sequenceSubject$: Subject<Sequence> = new Subject<Sequence>();
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequence$).and.returnValue(sequenceSubject$);
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequenceNodes$).and.returnValue(new Subject<Sequence>());
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheNode$).and.returnValue(new Subject<Node>());
|
|
|
|
const changedSubject$: Subject<SequenceDOMRenderer> = new Subject<SequenceDOMRenderer>();
|
|
mockCreator.mockProperty(renderer, "changed$", changedSubject$);
|
|
const changingPositionChangedSubject$: Subject<boolean> = new Subject<boolean>();
|
|
mockCreator.mockProperty(renderer, "changingPositionChanged$", changingPositionChangedSubject$);
|
|
spyOn(renderer, "getContainerWidth").and.returnValue(100);
|
|
|
|
const renderSpy: jasmine.Spy = spyOn(renderer, "render").and.stub();
|
|
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$) = new ReplaySubject<Node>(1);
|
|
|
|
const component: SequenceComponent = createComponent();
|
|
component.activate();
|
|
|
|
(<Subject<State>>navigatorMock.stateService.state$).next(State.Traversing);
|
|
(<Subject<number>>navigatorMock.playService.speed$).next(1);
|
|
(<Subject<ViewportSize>>containerMock.renderService.size$).next({ height: 1, width: 1 });
|
|
|
|
const sequenceKey1: string = "sequenceKey1";
|
|
const sequenceKey2: string = "sequenceKey2";
|
|
const nodeKey1: string = "nodeKey1";
|
|
const nodeKey2: string = "nodeKey2";
|
|
|
|
const node1: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node1, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node1, "sequenceEdges$", observableOf({ cached: false, edges: [] }));
|
|
mockCreator.mockProperty(node1, "id", nodeKey1);
|
|
mockCreator.mockProperty(node1, "sequenceId", sequenceKey1);
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node1);
|
|
|
|
expect(renderSpy.calls.count()).toBe(1);
|
|
|
|
sequenceSubject$.next(new Sequence({ id: sequenceKey1, image_ids: [nodeKey1] }));
|
|
|
|
expect(renderSpy.calls.count()).toBe(2);
|
|
expect(renderSpy.calls.mostRecent().args[4]).toBe(0);
|
|
expect(renderSpy.calls.mostRecent().args[5]).toBe(0);
|
|
|
|
changingPositionChangedSubject$.next(true);
|
|
|
|
const node2: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node2, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node2, "sequenceEdges$", observableOf({ cached: false, edges: [] }));
|
|
mockCreator.mockProperty(node2, "id", nodeKey2);
|
|
mockCreator.mockProperty(node2, "sequenceId", sequenceKey2);
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node2);
|
|
|
|
changingPositionChangedSubject$.next(false);
|
|
|
|
sequenceSubject$.next(new Sequence({ id: sequenceKey2, image_ids: [nodeKey2] }));
|
|
|
|
expect(renderSpy.calls.count()).toBeGreaterThan(2);
|
|
expect(renderSpy.calls.mostRecent().args[4]).toBe(0);
|
|
expect(renderSpy.calls.mostRecent().args[5]).toBe(0);
|
|
|
|
});
|
|
|
|
it("should render correct index on input emit", () => {
|
|
const sequenceSubject$: Subject<Sequence> = new Subject<Sequence>();
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequence$).and.returnValue(sequenceSubject$);
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequenceNodes$).and.returnValue(new Subject<Sequence>());
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheNode$).and.returnValue(new Subject<Node>());
|
|
|
|
(<jasmine.Spy>navigatorMock.moveTo$).and.returnValue(new Subject<Node>());
|
|
|
|
const changedSubject$: Subject<SequenceDOMRenderer> = new Subject<SequenceDOMRenderer>();
|
|
mockCreator.mockProperty(renderer, "changed$", changedSubject$);
|
|
const indexSubject$: Subject<number> = new Subject<number>();
|
|
mockCreator.mockProperty(renderer, "index$", indexSubject$);
|
|
const changingPositionChangedSubject$: Subject<boolean> = new Subject<boolean>();
|
|
mockCreator.mockProperty(renderer, "changingPositionChanged$", changingPositionChangedSubject$);
|
|
spyOn(renderer, "getContainerWidth").and.returnValue(100);
|
|
|
|
const renderSpy: jasmine.Spy = spyOn(renderer, "render").and.stub();
|
|
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$) = new ReplaySubject<Node>(1);
|
|
|
|
const component: SequenceComponent = createComponent();
|
|
component.activate();
|
|
|
|
(<Subject<State>>navigatorMock.stateService.state$).next(State.Traversing);
|
|
(<Subject<number>>navigatorMock.playService.speed$).next(1);
|
|
(<Subject<ViewportSize>>containerMock.renderService.size$).next({ height: 1, width: 1 });
|
|
|
|
const sequenceKey1: string = "sequenceKey1";
|
|
const nodeKey1: string = "nodeKey1";
|
|
const nodeKey2: string = "nodeKey2";
|
|
const nodeKey3: string = "nodeKey3";
|
|
|
|
const node1: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node1, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node1, "sequenceEdges$", observableOf({ cached: false, edges: [] }));
|
|
mockCreator.mockProperty(node1, "id", nodeKey2);
|
|
mockCreator.mockProperty(node1, "sequenceId", sequenceKey1);
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node1);
|
|
|
|
expect(renderSpy.calls.count()).toBe(1);
|
|
|
|
sequenceSubject$.next(new Sequence({ id: sequenceKey1, image_ids: [nodeKey1, nodeKey2, nodeKey3] }));
|
|
changingPositionChangedSubject$.next(true);
|
|
indexSubject$.next(0);
|
|
|
|
expect(renderSpy.calls.count()).toBeGreaterThan(1);
|
|
expect(renderSpy.calls.mostRecent().args[4]).toBe(0);
|
|
expect(renderSpy.calls.mostRecent().args[5]).toBe(2);
|
|
});
|
|
|
|
it("should render on first node emit after sequence change and on second thereafter", () => {
|
|
const sequenceSubject$: Subject<Sequence> = new Subject<Sequence>();
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequence$).and.returnValue(sequenceSubject$);
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequenceNodes$).and.returnValue(new Subject<Sequence>());
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheNode$).and.returnValue(new Subject<Node>());
|
|
|
|
(<jasmine.Spy>navigatorMock.moveTo$).and.returnValue(new Subject<Node>());
|
|
|
|
const changedSubject$: Subject<SequenceDOMRenderer> = new Subject<SequenceDOMRenderer>();
|
|
mockCreator.mockProperty(renderer, "changed$", changedSubject$);
|
|
const indexSubject$: Subject<number> = new Subject<number>();
|
|
mockCreator.mockProperty(renderer, "index$", indexSubject$);
|
|
const changingPositionChangedSubject$: Subject<boolean> = new Subject<boolean>();
|
|
mockCreator.mockProperty(renderer, "changingPositionChanged$", changingPositionChangedSubject$);
|
|
spyOn(renderer, "getContainerWidth").and.returnValue(100);
|
|
|
|
const renderSpy: jasmine.Spy = spyOn(renderer, "render").and.stub();
|
|
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$) = new ReplaySubject<Node>(1);
|
|
|
|
const component: SequenceComponent = createComponent();
|
|
component.activate();
|
|
|
|
(<Subject<State>>navigatorMock.stateService.state$).next(State.Traversing);
|
|
(<Subject<number>>navigatorMock.playService.speed$).next(1);
|
|
(<Subject<ViewportSize>>containerMock.renderService.size$).next({ height: 1, width: 1 });
|
|
|
|
const sequenceKey1: string = "sequenceKey1";
|
|
const nodeKey1: string = "nodeKey1";
|
|
const nodeKey2: string = "nodeKey2";
|
|
const nodeKey3: string = "nodeKey3";
|
|
|
|
const node1: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node1, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node1, "sequenceEdges$", observableOf({ cached: false, edges: [] }));
|
|
mockCreator.mockProperty(node1, "id", nodeKey1);
|
|
mockCreator.mockProperty(node1, "sequenceId", sequenceKey1);
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node1);
|
|
|
|
expect(renderSpy.calls.count()).toBe(1);
|
|
expect(renderSpy.calls.mostRecent().args[4]).toBe(null);
|
|
expect(renderSpy.calls.mostRecent().args[5]).toBe(null);
|
|
|
|
sequenceSubject$.next(new Sequence({ id: sequenceKey1, image_ids: [nodeKey1, nodeKey2, nodeKey3] }));
|
|
|
|
expect(renderSpy.calls.count()).toBe(2);
|
|
expect(renderSpy.calls.mostRecent().args[4]).toBe(0);
|
|
expect(renderSpy.calls.mostRecent().args[5]).toBe(2);
|
|
|
|
changingPositionChangedSubject$.next(true);
|
|
changedSubject$.next(renderer);
|
|
|
|
let callCount: number = renderSpy.calls.count();
|
|
|
|
expect(callCount).toBeGreaterThan(2);
|
|
expect(renderSpy.calls.mostRecent().args[4]).toBe(0);
|
|
expect(renderSpy.calls.mostRecent().args[5]).toBe(2);
|
|
|
|
indexSubject$.next(1);
|
|
|
|
expect(renderSpy.calls.count()).toBeGreaterThan(callCount);
|
|
callCount = renderSpy.calls.count();
|
|
|
|
expect(renderSpy.calls.mostRecent().args[4]).toBe(1);
|
|
expect(renderSpy.calls.mostRecent().args[5]).toBe(2);
|
|
|
|
changingPositionChangedSubject$.next(false);
|
|
changedSubject$.next(renderer);
|
|
|
|
expect(renderSpy.calls.mostRecent().args[4]).toBe(1);
|
|
expect(renderSpy.calls.mostRecent().args[5]).toBe(2);
|
|
|
|
const node3: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node3, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node3, "sequenceEdges$", observableOf({ cached: false, edges: [] }));
|
|
mockCreator.mockProperty(node3, "id", nodeKey3);
|
|
mockCreator.mockProperty(node3, "sequenceId", sequenceKey1);
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node3);
|
|
|
|
expect(renderSpy.calls.mostRecent().args[4]).toBe(2);
|
|
expect(renderSpy.calls.mostRecent().args[5]).toBe(2);
|
|
});
|
|
|
|
it("should not move to key before debounce time", () => {
|
|
const sequenceSubject$: Subject<Sequence> = new Subject<Sequence>();
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequence$).and.returnValue(sequenceSubject$);
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequenceNodes$).and.returnValue(new Subject<Sequence>());
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheNode$).and.returnValue(new Subject<Node>());
|
|
|
|
const moveToKeySpy: jasmine.Spy = <jasmine.Spy>navigatorMock.moveTo$;
|
|
moveToKeySpy.and.returnValue(new Subject<Node>());
|
|
|
|
const indexSubject$: Subject<number> = new Subject<number>();
|
|
mockCreator.mockProperty(renderer, "index$", indexSubject$);
|
|
|
|
const scheduler: VirtualTimeScheduler = new VirtualTimeScheduler();
|
|
const component: SequenceComponent = new SequenceComponent(
|
|
SequenceComponent.componentName,
|
|
containerMock,
|
|
navigatorMock,
|
|
renderer,
|
|
scheduler);
|
|
|
|
component.activate();
|
|
|
|
const sequenceKey1: string = "sequenceKey1";
|
|
const nodeKey1: string = "nodeKey1";
|
|
const nodeKey2: string = "nodeKey2";
|
|
const nodeKey3: string = "nodeKey3";
|
|
|
|
const node1: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node1, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node1, "sequenceEdges$", observableOf({ cached: false, edges: [] }));
|
|
mockCreator.mockProperty(node1, "id", nodeKey2);
|
|
mockCreator.mockProperty(node1, "sequenceId", sequenceKey1);
|
|
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node1);
|
|
sequenceSubject$.next(new Sequence({ id: sequenceKey1, image_ids: [nodeKey1, nodeKey2, nodeKey3] }));
|
|
indexSubject$.next(1);
|
|
|
|
expect(moveToKeySpy.calls.count()).toBe(0);
|
|
|
|
scheduler.maxFrames = 99;
|
|
scheduler.flush();
|
|
|
|
expect(moveToKeySpy.calls.count()).toBe(0);
|
|
});
|
|
|
|
it("should move to key on first index change after debounce time", () => {
|
|
const sequenceSubject$: Subject<Sequence> = new Subject<Sequence>();
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequence$).and.returnValue(sequenceSubject$);
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequenceNodes$).and.returnValue(new Subject<Sequence>());
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheNode$).and.returnValue(new Subject<Node>());
|
|
|
|
const moveToKeySpy: jasmine.Spy = <jasmine.Spy>navigatorMock.moveTo$;
|
|
moveToKeySpy.and.returnValue(new Subject<Node>());
|
|
|
|
const indexSubject$: Subject<number> = new Subject<number>();
|
|
mockCreator.mockProperty(renderer, "index$", indexSubject$);
|
|
|
|
const scheduler: VirtualTimeScheduler = new VirtualTimeScheduler();
|
|
const component: SequenceComponent = new SequenceComponent(
|
|
SequenceComponent.componentName,
|
|
containerMock,
|
|
navigatorMock,
|
|
renderer,
|
|
scheduler);
|
|
|
|
component.activate();
|
|
|
|
const sequenceKey1: string = "sequenceKey1";
|
|
const nodeKey1: string = "nodeKey1";
|
|
const nodeKey2: string = "nodeKey2";
|
|
const nodeKey3: string = "nodeKey3";
|
|
|
|
const node1: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node1, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node1, "sequenceEdges$", observableOf({ cached: false, edges: [] }));
|
|
mockCreator.mockProperty(node1, "id", nodeKey2);
|
|
mockCreator.mockProperty(node1, "sequenceId", sequenceKey1);
|
|
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node1);
|
|
sequenceSubject$.next(new Sequence({ id: sequenceKey1, image_ids: [nodeKey1, nodeKey2, nodeKey3] }));
|
|
indexSubject$.next(1);
|
|
|
|
expect(moveToKeySpy.calls.count()).toBe(0);
|
|
|
|
scheduler.maxFrames = 101;
|
|
scheduler.flush();
|
|
|
|
expect(moveToKeySpy.calls.count()).toBe(1);
|
|
expect(moveToKeySpy.calls.argsFor(0)[0]).toBe(nodeKey2);
|
|
});
|
|
|
|
it("should not move to same key if audit time expires", () => {
|
|
const sequenceSubject$: Subject<Sequence> = new Subject<Sequence>();
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequence$).and.returnValue(sequenceSubject$);
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequenceNodes$).and.returnValue(new Subject<Sequence>());
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheNode$).and.returnValue(new Subject<Node>());
|
|
|
|
const moveToKeySpy: jasmine.Spy = <jasmine.Spy>navigatorMock.moveTo$;
|
|
moveToKeySpy.and.returnValue(new Subject<Node>());
|
|
|
|
const indexSubject$: Subject<number> = new Subject<number>();
|
|
mockCreator.mockProperty(renderer, "index$", indexSubject$);
|
|
|
|
const scheduler: VirtualTimeScheduler = new VirtualTimeScheduler();
|
|
const component: SequenceComponent = new SequenceComponent(
|
|
SequenceComponent.componentName,
|
|
containerMock,
|
|
navigatorMock,
|
|
renderer,
|
|
scheduler);
|
|
|
|
component.activate();
|
|
|
|
const sequenceKey1: string = "sequenceKey1";
|
|
const nodeKey1: string = "nodeKey1";
|
|
const nodeKey2: string = "nodeKey2";
|
|
const nodeKey3: string = "nodeKey3";
|
|
|
|
const node1: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node1, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node1, "sequenceEdges$", observableOf({ cached: false, edges: [] }));
|
|
mockCreator.mockProperty(node1, "id", nodeKey2);
|
|
mockCreator.mockProperty(node1, "sequenceId", sequenceKey1);
|
|
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node1);
|
|
sequenceSubject$.next(new Sequence({ id: sequenceKey1, image_ids: [nodeKey1, nodeKey2, nodeKey3] }));
|
|
indexSubject$.next(1);
|
|
|
|
expect(moveToKeySpy.calls.count()).toBe(0);
|
|
|
|
scheduler.maxFrames = 401;
|
|
scheduler.flush();
|
|
|
|
expect(moveToKeySpy.calls.count()).toBe(1);
|
|
});
|
|
|
|
it("should move to key on second index change if debounce time is reached", () => {
|
|
const sequenceSubject$: Subject<Sequence> = new Subject<Sequence>();
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequence$).and.returnValue(sequenceSubject$);
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequenceNodes$).and.returnValue(new Subject<Sequence>());
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheNode$).and.returnValue(new Subject<Node>());
|
|
|
|
const moveToKeySpy: jasmine.Spy = <jasmine.Spy>navigatorMock.moveTo$;
|
|
moveToKeySpy.and.returnValue(new Subject<Node>());
|
|
|
|
const indexSubject$: Subject<number> = new Subject<number>();
|
|
mockCreator.mockProperty(renderer, "index$", indexSubject$);
|
|
|
|
const scheduler: VirtualTimeScheduler = new VirtualTimeScheduler();
|
|
const component: SequenceComponent = new SequenceComponent(
|
|
SequenceComponent.componentName,
|
|
containerMock,
|
|
navigatorMock,
|
|
renderer,
|
|
scheduler);
|
|
|
|
component.activate();
|
|
|
|
const sequenceKey1: string = "sequenceKey1";
|
|
const nodeKey1: string = "nodeKey1";
|
|
const nodeKey2: string = "nodeKey2";
|
|
const nodeKey3: string = "nodeKey3";
|
|
|
|
const node1: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node1, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node1, "sequenceEdges$", observableOf({ cached: false, edges: [] }));
|
|
mockCreator.mockProperty(node1, "id", nodeKey2);
|
|
mockCreator.mockProperty(node1, "sequenceId", sequenceKey1);
|
|
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node1);
|
|
sequenceSubject$.next(new Sequence({ id: sequenceKey1, image_ids: [nodeKey1, nodeKey2, nodeKey3] }));
|
|
indexSubject$.next(1);
|
|
|
|
expect(moveToKeySpy.calls.count()).toBe(0);
|
|
|
|
scheduler.maxFrames = 99;
|
|
scheduler.flush();
|
|
scheduler.frame = 99;
|
|
|
|
indexSubject$.next(2);
|
|
|
|
expect(moveToKeySpy.calls.count()).toBe(0);
|
|
|
|
scheduler.maxFrames = 200;
|
|
scheduler.flush();
|
|
|
|
expect(moveToKeySpy.calls.count()).toBe(1);
|
|
expect(moveToKeySpy.calls.mostRecent().args[0]).toBe(nodeKey3);
|
|
});
|
|
|
|
it("should move to key after multiple index emits with less than 100 ms in between if 400 ms has passed", () => {
|
|
const sequenceSubject$: Subject<Sequence> = new Subject<Sequence>();
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequence$).and.returnValue(sequenceSubject$);
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheSequenceNodes$).and.returnValue(new Subject<Sequence>());
|
|
(<jasmine.Spy>navigatorMock.graphService.cacheNode$).and.returnValue(new Subject<Node>());
|
|
|
|
const moveToKeySpy: jasmine.Spy = <jasmine.Spy>navigatorMock.moveTo$;
|
|
moveToKeySpy.and.returnValue(new Subject<Node>());
|
|
|
|
const indexSubject$: Subject<number> = new Subject<number>();
|
|
mockCreator.mockProperty(renderer, "index$", indexSubject$);
|
|
|
|
const scheduler: VirtualTimeScheduler = new VirtualTimeScheduler();
|
|
const component: SequenceComponent = new SequenceComponent(
|
|
SequenceComponent.componentName,
|
|
containerMock,
|
|
navigatorMock,
|
|
renderer,
|
|
scheduler);
|
|
|
|
component.activate();
|
|
|
|
const sequenceKey1: string = "sequenceKey1";
|
|
const nodeKey1: string = "nodeKey1";
|
|
const nodeKey2: string = "nodeKey2";
|
|
const nodeKey3: string = "nodeKey3";
|
|
|
|
const node1: Node = nodeHelper.createNode();
|
|
mockCreator.mockProperty(node1, "spatialEdges", { cached: false, edges: [] });
|
|
mockCreator.mockProperty(node1, "sequenceEdges$", observableOf({ cached: false, edges: [] }));
|
|
mockCreator.mockProperty(node1, "id", nodeKey2);
|
|
mockCreator.mockProperty(node1, "sequenceId", sequenceKey1);
|
|
|
|
(<Subject<Node>>navigatorMock.stateService.currentNode$).next(node1);
|
|
sequenceSubject$.next(new Sequence({ id: sequenceKey1, image_ids: [nodeKey1, nodeKey2, nodeKey3] }));
|
|
indexSubject$.next(1);
|
|
|
|
expect(moveToKeySpy.calls.count()).toBe(0);
|
|
|
|
scheduler.maxFrames = 90;
|
|
scheduler.flush();
|
|
scheduler.frame = 90;
|
|
|
|
indexSubject$.next(0);
|
|
expect(moveToKeySpy.calls.count()).toBe(0);
|
|
|
|
scheduler.maxFrames = 180;
|
|
scheduler.flush();
|
|
scheduler.frame = 180;
|
|
|
|
indexSubject$.next(1);
|
|
expect(moveToKeySpy.calls.count()).toBe(0);
|
|
|
|
scheduler.maxFrames = 270;
|
|
scheduler.flush();
|
|
scheduler.frame = 270;
|
|
|
|
indexSubject$.next(0);
|
|
expect(moveToKeySpy.calls.count()).toBe(0);
|
|
|
|
scheduler.maxFrames = 360;
|
|
scheduler.flush();
|
|
scheduler.frame = 360;
|
|
|
|
indexSubject$.next(2);
|
|
expect(moveToKeySpy.calls.count()).toBe(0);
|
|
|
|
scheduler.maxFrames = 450;
|
|
scheduler.flush();
|
|
scheduler.frame = 450;
|
|
|
|
expect(moveToKeySpy.calls.count()).toBe(1);
|
|
expect(moveToKeySpy.calls.mostRecent().args[0]).toBe(nodeKey3);
|
|
});
|
|
});
|