diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2021-11-19 18:30:16 +0100 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2021-11-23 15:38:23 +0100 |
| commit | 15f64f737c5e3087e722937bfba472a9d3174a75 (patch) | |
| tree | 2bff8ea56023c6192f9b6fa1d4c1127004f72cee | |
| parent | 50a301f5d42304b53ddc84d9494f01550bd93b42 (diff) | |
| download | mullvadvpn-15f64f737c5e3087e722937bfba472a9d3174a75.tar.xz mullvadvpn-15f64f737c5e3087e722937bfba472a9d3174a75.zip | |
Implement tests for list diff
| -rw-r--r-- | gui/src/renderer/components/List.tsx | 4 | ||||
| -rw-r--r-- | gui/test/list-diff.spec.ts | 103 |
2 files changed, 105 insertions, 2 deletions
diff --git a/gui/src/renderer/components/List.tsx b/gui/src/renderer/components/List.tsx index 1d15752f4f..a0d7a3ec5c 100644 --- a/gui/src/renderer/components/List.tsx +++ b/gui/src/renderer/components/List.tsx @@ -12,12 +12,12 @@ interface ListProps<T> { skipRemoveTransition?: boolean; } -interface RowData<T> { +export interface RowData<T> { key: string; data: T; } -interface RowDisplayData<T> extends RowData<T> { +export interface RowDisplayData<T> extends RowData<T> { removing: boolean; } diff --git a/gui/test/list-diff.spec.ts b/gui/test/list-diff.spec.ts new file mode 100644 index 0000000000..bca3e72d84 --- /dev/null +++ b/gui/test/list-diff.spec.ts @@ -0,0 +1,103 @@ +import { expect } from 'chai'; +import { it, describe } from 'mocha'; +import { calculateItemList, RowDisplayData } from '../src/renderer/components/List'; + +const prevItems: Array<RowDisplayData<undefined>> = [ + { key: 'a', data: undefined, removing: false }, + { key: 'b', data: undefined, removing: false }, + { key: 'c', data: undefined, removing: false }, + { key: 'd', data: undefined, removing: false }, +]; + +describe('List diff', () => { + it('Should add item to the beginning', () => { + const nextItems: Array<RowDisplayData<undefined>> = [ + { key: '1', data: undefined, removing: false }, + ...prevItems, + ]; + const combinedItems = calculateItemList(prevItems, nextItems); + + expect(combinedItems).to.have.length(5); + expect(combinedItems.slice(1)).to.deep.equal(prevItems); + expect(combinedItems).to.deep.equal(nextItems); + }); + + it('Should add item to the end', () => { + const nextItems: Array<RowDisplayData<undefined>> = [ + ...prevItems, + { key: '1', data: undefined, removing: false }, + ]; + const combinedItems = calculateItemList(prevItems, nextItems); + + expect(combinedItems).to.have.length(5); + expect(combinedItems.slice(0, 4)).to.deep.equal(prevItems); + expect(combinedItems).to.deep.equal(nextItems); + }); + + it('Should add item to the middle', () => { + const nextItems: Array<RowDisplayData<undefined>> = [ + ...prevItems.slice(0, 2), + { key: '1', data: undefined, removing: false }, + ...prevItems.slice(2), + ]; + const combinedItems = calculateItemList(prevItems, nextItems); + + expect(combinedItems).to.have.length(5); + expect([...combinedItems.slice(0, 2), ...combinedItems.slice(3)]).to.deep.equal(prevItems); + expect(combinedItems).to.deep.equal(nextItems); + }); + + it('Should remove first item', () => { + const nextItems = prevItems.slice(1); + const combinedItems = calculateItemList(prevItems, nextItems); + + expect(combinedItems).to.have.length(4); + expect(combinedItems.slice(1, 4)).to.deep.equal(prevItems.slice(1, 4)); + expect(combinedItems[0]).to.deep.equal({ ...prevItems[0], removing: true }); + }); + + it('Should remove last item', () => { + const nextItems = prevItems.slice(0, -1); + const combinedItems = calculateItemList(prevItems, nextItems); + + expect(combinedItems).to.have.length(4); + expect(combinedItems.slice(0, -1)).to.deep.equal(prevItems.slice(0, -1)); + expect(combinedItems.at(-1)).to.deep.equal({ ...prevItems.at(-1), removing: true }); + }); + + it('Should remove middle item', () => { + const nextItems = [...prevItems.slice(0, 1), ...prevItems.slice(2)]; + const combinedItems = calculateItemList(prevItems, nextItems); + + expect(combinedItems).to.have.length(4); + expect(combinedItems.slice(0, 1)).to.deep.equal(prevItems.slice(0, 1)); + expect(combinedItems.slice(2)).to.deep.equal(prevItems.slice(2)); + expect(combinedItems[1]).to.deep.equal({ ...prevItems[1], removing: true }); + }); + + it('should both add and remove items', () => { + const nextItems = [ + { key: '1', data: undefined, removing: false }, + ...prevItems.slice(1, -1), + { key: '2', data: undefined, removing: false }, + ]; + const combinedItems = calculateItemList(prevItems, nextItems); + + expect(combinedItems).to.have.length(6); + expect(combinedItems[0]).to.deep.equal({ ...prevItems[0], removing: true }); + expect(combinedItems[1]).to.deep.equal(nextItems[0]); + expect(combinedItems.slice(2, -2)).to.deep.equal(prevItems.slice(1, -1)); + expect(combinedItems.at(-2)).to.deep.equal({ ...prevItems.at(-1), removing: true }); + expect(combinedItems.at(-1)).to.deep.equal(nextItems.at(-1)); + }); + + it('should remove item being removed', () => { + const prevItems: Array<RowDisplayData<undefined>> = [ + { key: '1', data: undefined, removing: true }, + ]; + const nextItems: Array<RowDisplayData<undefined>> = []; + const combinedItems = calculateItemList(prevItems, nextItems); + + expect(combinedItems).to.deep.equal(prevItems); + }); +}); |
