Skip to content

Commit

Permalink
Implement history helper and tests - #5508
Browse files Browse the repository at this point in the history
  • Loading branch information
sandy081 committed Sep 12, 2016
1 parent 8e562d6 commit ac3b200
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 0 deletions.
70 changes: 70 additions & 0 deletions src/vs/base/common/history.ts
Original file line number Diff line number Diff line change
@@ -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 changes: 114 additions & 0 deletions src/vs/base/test/common/history.test.ts
Original file line number Diff line number Diff line change
@@ -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;
}
});

0 comments on commit ac3b200

Please sign in to comment.