Implement history helper and tests - #5508
This commit is contained in:
parent
8e562d6df4
commit
ac3b200561
70
src/vs/base/common/history.ts
Normal file
70
src/vs/base/common/history.ts
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ArraySet } from 'vs/base/common/set';
|
||||
import { INavigator, ArrayNavigator } from 'vs/base/common/iterator';
|
||||
|
||||
export class HistoryNavigator<T> implements INavigator<T> {
|
||||
|
||||
private _history: ArraySet<T>;
|
||||
private _limit: number;
|
||||
private _navigator: ArrayNavigator<T>;
|
||||
|
||||
constructor(history: T[] = [], limit: number = 10) {
|
||||
this._history = new ArraySet(history);
|
||||
this._limit = limit;
|
||||
this._onChange();
|
||||
}
|
||||
|
||||
public add(t: T) {
|
||||
this._history.set(t);
|
||||
this._onChange();
|
||||
}
|
||||
|
||||
public next(): T {
|
||||
if (this._navigator.next()) {
|
||||
return this._navigator.current();
|
||||
}
|
||||
this.last();
|
||||
return null;
|
||||
}
|
||||
|
||||
public previous(): T {
|
||||
if (this._navigator.previous()) {
|
||||
return this._navigator.current();
|
||||
}
|
||||
this.first();
|
||||
return null;
|
||||
}
|
||||
|
||||
public current(): T {
|
||||
return this._navigator.current();
|
||||
}
|
||||
|
||||
public parent(): T {
|
||||
return null;
|
||||
}
|
||||
|
||||
public first(): T {
|
||||
return this._navigator.first();
|
||||
}
|
||||
|
||||
public last(): T {
|
||||
return this._navigator.last();
|
||||
}
|
||||
|
||||
private _onChange() {
|
||||
this._reduceToLimit();
|
||||
this._navigator = new ArrayNavigator(this._history.elements);
|
||||
this._navigator.last();
|
||||
}
|
||||
|
||||
private _reduceToLimit() {
|
||||
let data = this._history.elements;
|
||||
if (data.length > this._limit) {
|
||||
this._history = new ArraySet<T>(data.slice(data.length - this._limit));
|
||||
}
|
||||
}
|
||||
}
|
114
src/vs/base/test/common/history.test.ts
Normal file
114
src/vs/base/test/common/history.test.ts
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import {HistoryNavigator} from 'vs/base/common/history';
|
||||
|
||||
suite('History Navigator', () => {
|
||||
|
||||
test('create reduces the input to limit', function () {
|
||||
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 2);
|
||||
|
||||
assert.deepEqual(['3', '4'], toArray(testObject));
|
||||
});
|
||||
|
||||
test('create sets the position to last', function () {
|
||||
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
|
||||
|
||||
assert.equal('4', testObject.current());
|
||||
assert.equal(null, testObject.next());
|
||||
assert.equal('3', testObject.previous());
|
||||
});
|
||||
|
||||
test('last returns last element', function () {
|
||||
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
|
||||
|
||||
testObject.first();
|
||||
|
||||
assert.equal('4', testObject.last());
|
||||
});
|
||||
|
||||
test('first returns first element', function () {
|
||||
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
|
||||
|
||||
assert.equal('2', testObject.first());
|
||||
});
|
||||
|
||||
test('next returns next element', function () {
|
||||
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
|
||||
|
||||
testObject.first();
|
||||
|
||||
assert.equal('3', testObject.next());
|
||||
assert.equal('4', testObject.next());
|
||||
assert.equal(null, testObject.next());
|
||||
});
|
||||
|
||||
test('previous returns previous element', function () {
|
||||
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
|
||||
|
||||
assert.equal('3', testObject.previous());
|
||||
assert.equal('2', testObject.previous());
|
||||
assert.equal(null, testObject.previous());
|
||||
});
|
||||
|
||||
test('next on last element returs null and remains on last', function () {
|
||||
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
|
||||
|
||||
testObject.first();
|
||||
testObject.last();
|
||||
|
||||
assert.equal('4', testObject.current());
|
||||
assert.equal(null, testObject.next());
|
||||
});
|
||||
|
||||
test('previous on first element returs null and remains on first', function () {
|
||||
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
|
||||
|
||||
testObject.first();
|
||||
|
||||
assert.equal('2', testObject.current());
|
||||
assert.equal(null, testObject.previous());
|
||||
});
|
||||
|
||||
test('add reduces the input to limit', function () {
|
||||
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 2);
|
||||
|
||||
testObject.add('5');
|
||||
|
||||
assert.deepEqual(['4', '5'], toArray(testObject));
|
||||
});
|
||||
|
||||
test('adding existing element changes the position', function () {
|
||||
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 2);
|
||||
|
||||
testObject.add('2');
|
||||
|
||||
assert.deepEqual(['4', '2'], toArray(testObject));
|
||||
});
|
||||
|
||||
test('add resets the navigator to last', function () {
|
||||
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
|
||||
|
||||
testObject.first();
|
||||
testObject.add('5');
|
||||
|
||||
assert.equal('5', testObject.current());
|
||||
assert.equal(null, testObject.next());
|
||||
});
|
||||
|
||||
function toArray(historyNavigator: HistoryNavigator<string>): string[] {
|
||||
let result = [];
|
||||
historyNavigator.first();
|
||||
if (historyNavigator.current()) {
|
||||
do {
|
||||
result.push(historyNavigator.current());
|
||||
} while (historyNavigator.next());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
Loading…
Reference in a new issue