mirror of
https://github.com/nasa/openmct.git
synced 2024-12-24 15:26:39 +00:00
Prevent infinite loop when updating a table row in place (#7154)
* bump index on update row in place * add test * Removing problematic test * spelling
This commit is contained in:
parent
2daec448da
commit
13311b9fc8
@ -153,40 +153,41 @@ define(['lodash', 'EventEmitter'], function (_, EventEmitter) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
mergeSortedRows(rows) {
|
mergeSortedRows(incomingRows) {
|
||||||
const mergedRows = [];
|
const mergedRows = [];
|
||||||
let i = 0;
|
let existingRowIndex = 0;
|
||||||
let j = 0;
|
let incomingRowIndex = 0;
|
||||||
|
|
||||||
while (i < this.rows.length && j < rows.length) {
|
while (existingRowIndex < this.rows.length && incomingRowIndex < incomingRows.length) {
|
||||||
const existingRow = this.rows[i];
|
const existingRow = this.rows[existingRowIndex];
|
||||||
const incomingRow = rows[j];
|
const incomingRow = incomingRows[incomingRowIndex];
|
||||||
|
|
||||||
const index = this.getInPlaceUpdateIndex(incomingRow);
|
const inPlaceIndex = this.getInPlaceUpdateIndex(incomingRow);
|
||||||
if (index > -1) {
|
if (inPlaceIndex > -1) {
|
||||||
this.updateRowInPlace(incomingRow, index);
|
this.updateRowInPlace(incomingRow, inPlaceIndex);
|
||||||
|
incomingRowIndex++;
|
||||||
} else {
|
} else {
|
||||||
if (this.firstRowInSortOrder(existingRow, incomingRow) === existingRow) {
|
if (this.firstRowInSortOrder(existingRow, incomingRow) === existingRow) {
|
||||||
mergedRows.push(existingRow);
|
mergedRows.push(existingRow);
|
||||||
i++;
|
existingRowIndex++;
|
||||||
} else {
|
} else {
|
||||||
mergedRows.push(incomingRow);
|
mergedRows.push(incomingRow);
|
||||||
j++;
|
incomingRowIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// tail of existing rows is all that is left to merge
|
// tail of existing rows is all that is left to merge
|
||||||
if (i < this.rows.length) {
|
if (existingRowIndex < this.rows.length) {
|
||||||
for (i; i < this.rows.length; i++) {
|
for (existingRowIndex; existingRowIndex < this.rows.length; existingRowIndex++) {
|
||||||
mergedRows.push(this.rows[i]);
|
mergedRows.push(this.rows[existingRowIndex]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// tail of incoming rows is all that is left to merge
|
// tail of incoming rows is all that is left to merge
|
||||||
if (j < rows.length) {
|
if (incomingRowIndex < incomingRows.length) {
|
||||||
for (j; j < rows.length; j++) {
|
for (incomingRowIndex; incomingRowIndex < incomingRows.length; incomingRowIndex++) {
|
||||||
mergedRows.push(rows[j]);
|
mergedRows.push(incomingRows[incomingRowIndex]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ describe('the plugin', () => {
|
|||||||
let tablePlugin;
|
let tablePlugin;
|
||||||
let element;
|
let element;
|
||||||
let child;
|
let child;
|
||||||
let historicalProvider;
|
let historicalTelemetryProvider;
|
||||||
let originalRouterPath;
|
let originalRouterPath;
|
||||||
let unlistenConfigMutation;
|
let unlistenConfigMutation;
|
||||||
|
|
||||||
@ -61,12 +61,12 @@ describe('the plugin', () => {
|
|||||||
tablePlugin = new TablePlugin();
|
tablePlugin = new TablePlugin();
|
||||||
openmct.install(tablePlugin);
|
openmct.install(tablePlugin);
|
||||||
|
|
||||||
historicalProvider = {
|
historicalTelemetryProvider = {
|
||||||
request: () => {
|
request: () => {
|
||||||
return Promise.resolve([]);
|
return Promise.resolve([]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
spyOn(openmct.telemetry, 'findRequestProvider').and.returnValue(historicalProvider);
|
spyOn(openmct.telemetry, 'findRequestProvider').and.returnValue(historicalTelemetryProvider);
|
||||||
|
|
||||||
element = document.createElement('div');
|
element = document.createElement('div');
|
||||||
child = document.createElement('div');
|
child = document.createElement('div');
|
||||||
@ -137,11 +137,12 @@ describe('the plugin', () => {
|
|||||||
let tableView;
|
let tableView;
|
||||||
let tableInstance;
|
let tableInstance;
|
||||||
let mockClock;
|
let mockClock;
|
||||||
|
let telemetryCallback;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
openmct.time.timeSystem('utc', {
|
openmct.time.timeSystem('utc', {
|
||||||
start: 0,
|
start: 0,
|
||||||
end: 4
|
end: 10
|
||||||
});
|
});
|
||||||
|
|
||||||
mockClock = jasmine.createSpyObj('clock', ['on', 'off', 'currentValue']);
|
mockClock = jasmine.createSpyObj('clock', ['on', 'off', 'currentValue']);
|
||||||
@ -151,7 +152,7 @@ describe('the plugin', () => {
|
|||||||
openmct.time.addClock(mockClock);
|
openmct.time.addClock(mockClock);
|
||||||
openmct.time.clock('mockClock', {
|
openmct.time.clock('mockClock', {
|
||||||
start: 0,
|
start: 0,
|
||||||
end: 4
|
end: 10
|
||||||
});
|
});
|
||||||
|
|
||||||
testTelemetryObject = {
|
testTelemetryObject = {
|
||||||
@ -214,7 +215,21 @@ describe('the plugin', () => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
historicalProvider.request = () => Promise.resolve(testTelemetry);
|
historicalTelemetryProvider.request = () => {
|
||||||
|
return Promise.resolve(testTelemetry);
|
||||||
|
};
|
||||||
|
|
||||||
|
const realtimeTelemetryProvider = {
|
||||||
|
supportsSubscribe: () => true,
|
||||||
|
subscribe: (domainObject, passedCallback) => {
|
||||||
|
telemetryCallback = passedCallback;
|
||||||
|
return Promise.resolve(() => {});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
spyOn(openmct.telemetry, 'findSubscriptionProvider').and.returnValue(
|
||||||
|
realtimeTelemetryProvider
|
||||||
|
);
|
||||||
|
|
||||||
openmct.router.path = [testTelemetryObject];
|
openmct.router.path = [testTelemetryObject];
|
||||||
|
|
||||||
@ -256,6 +271,23 @@ describe('the plugin', () => {
|
|||||||
expect(rows.length).toBe(3);
|
expect(rows.length).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Adds a row in place when updating with existing telemetry', async () => {
|
||||||
|
let rows = element.querySelectorAll('table.c-telemetry-table__body tr');
|
||||||
|
await nextTick();
|
||||||
|
expect(rows.length).toBe(3);
|
||||||
|
// fire some telemetry
|
||||||
|
const newTelemetry = {
|
||||||
|
utc: 2,
|
||||||
|
'some-key': 'some-value 2',
|
||||||
|
'some-other-key': 'spacecraft'
|
||||||
|
};
|
||||||
|
spyOn(tableInstance.tableRows, 'getInPlaceUpdateIndex').and.returnValue(1);
|
||||||
|
spyOn(tableInstance.tableRows, 'updateRowInPlace').and.callThrough();
|
||||||
|
telemetryCallback(newTelemetry);
|
||||||
|
|
||||||
|
expect(tableInstance.tableRows.updateRowInPlace.calls.count()).toBeGreaterThan(0);
|
||||||
|
});
|
||||||
|
|
||||||
it('Renders a column for every item in telemetry metadata', () => {
|
it('Renders a column for every item in telemetry metadata', () => {
|
||||||
let headers = element.querySelectorAll('span.c-telemetry-table__headers__label');
|
let headers = element.querySelectorAll('span.c-telemetry-table__headers__label');
|
||||||
expect(headers.length).toBe(4);
|
expect(headers.length).toBe(4);
|
||||||
|
Loading…
Reference in New Issue
Block a user