restructure presentation layer
- Move most GUI related code to /presentation - Move components to /components (separate from bootstrap and style) - Move shared components helpers to /components/shared - Rename Bootstrapping to bootstrapping to enforce same naming convention in /presentation
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { getScriptNodeId, getScriptId, getCategoryNodeId, getCategoryId } from '@/presentation/components/Scripts/ScriptsTree/ScriptNodeParser';
|
||||
import { parseSingleCategory,
|
||||
parseAllCategories } from '@/presentation/components/Scripts/ScriptsTree/ScriptNodeParser';
|
||||
import { INode, NodeType } from '@/presentation/components/Scripts/ScriptsTree/SelectableTree/Node/INode';
|
||||
import { IScript } from '@/domain/IScript';
|
||||
import { ICategory } from '@/domain/ICategory';
|
||||
import { CategoryStub } from '../../../../stubs/CategoryStub';
|
||||
import { ScriptStub } from '../../../../stubs/ScriptStub';
|
||||
import { CategoryCollectionStub } from '../../../../stubs/CategoryCollectionStub';
|
||||
|
||||
describe('ScriptNodeParser', () => {
|
||||
it('can convert script id and back', () => {
|
||||
// arrange
|
||||
const script = new ScriptStub('test');
|
||||
// act
|
||||
const nodeId = getScriptNodeId(script);
|
||||
const scriptId = getScriptId(nodeId);
|
||||
// assert
|
||||
expect(scriptId).to.equal(script.id);
|
||||
});
|
||||
it('can convert category id and back', () => {
|
||||
// arrange
|
||||
const category = new CategoryStub(55);
|
||||
// act
|
||||
const nodeId = getCategoryNodeId(category);
|
||||
const scriptId = getCategoryId(nodeId);
|
||||
// assert
|
||||
expect(scriptId).to.equal(category.id);
|
||||
});
|
||||
describe('parseSingleCategory', () => {
|
||||
it('can parse when category has sub categories', () => {
|
||||
// arrange
|
||||
const categoryId = 31;
|
||||
const firstSubCategory = new CategoryStub(11).withScriptIds('111', '112');
|
||||
const secondSubCategory = new CategoryStub(categoryId)
|
||||
.withCategory(new CategoryStub(33).withScriptIds('331', '331'))
|
||||
.withCategory(new CategoryStub(44).withScriptIds('44'));
|
||||
const collection = new CategoryCollectionStub().withAction(new CategoryStub(categoryId)
|
||||
.withCategory(firstSubCategory)
|
||||
.withCategory(secondSubCategory));
|
||||
// act
|
||||
const nodes = parseSingleCategory(categoryId, collection);
|
||||
// assert
|
||||
expect(nodes).to.have.lengthOf(2);
|
||||
expectSameCategory(nodes[0], firstSubCategory);
|
||||
expectSameCategory(nodes[1], secondSubCategory);
|
||||
});
|
||||
it('can parse when category has sub scripts', () => {
|
||||
// arrange
|
||||
const categoryId = 31;
|
||||
const scripts = [ new ScriptStub('script1'), new ScriptStub('script2'), new ScriptStub('script3') ];
|
||||
const collection = new CategoryCollectionStub()
|
||||
.withAction(new CategoryStub(categoryId).withScripts(...scripts));
|
||||
// act
|
||||
const nodes = parseSingleCategory(categoryId, collection);
|
||||
// assert
|
||||
expect(nodes).to.have.lengthOf(3);
|
||||
expectSameScript(nodes[0], scripts[0]);
|
||||
expectSameScript(nodes[1], scripts[1]);
|
||||
expectSameScript(nodes[2], scripts[2]);
|
||||
});
|
||||
});
|
||||
|
||||
it('parseAllCategories parses as expected', () => {
|
||||
// arrange
|
||||
const collection = new CategoryCollectionStub()
|
||||
.withAction(new CategoryStub(0).withScriptIds('1, 2'))
|
||||
.withAction(new CategoryStub(1).withCategories(
|
||||
new CategoryStub(3).withScriptIds('3', '4'),
|
||||
new CategoryStub(4).withCategory(new CategoryStub(5).withScriptIds('6')),
|
||||
));
|
||||
// act
|
||||
const nodes = parseAllCategories(collection);
|
||||
// assert
|
||||
expect(nodes).to.have.lengthOf(2);
|
||||
expectSameCategory(nodes[0], collection.actions[0]);
|
||||
expectSameCategory(nodes[1], collection.actions[1]);
|
||||
});
|
||||
});
|
||||
|
||||
function isReversible(category: ICategory): boolean {
|
||||
if (category.scripts) {
|
||||
return category.scripts.every((s) => s.canRevert());
|
||||
}
|
||||
return category.subCategories.every((c) => isReversible(c));
|
||||
}
|
||||
|
||||
function expectSameCategory(node: INode, category: ICategory): void {
|
||||
expect(node.type).to.equal(NodeType.Category, getErrorMessage('type'));
|
||||
expect(node.id).to.equal(getCategoryNodeId(category), getErrorMessage('id'));
|
||||
expect(node.documentationUrls).to.equal(category.documentationUrls, getErrorMessage('documentationUrls'));
|
||||
expect(node.text).to.equal(category.name, getErrorMessage('name'));
|
||||
expect(node.isReversible).to.equal(isReversible(category), getErrorMessage('isReversible'));
|
||||
expect(node.children).to.have.lengthOf(category.scripts.length || category.subCategories.length, getErrorMessage('name'));
|
||||
for (let i = 0; i < category.subCategories.length; i++) {
|
||||
expectSameCategory(node.children[i], category.subCategories[i]);
|
||||
}
|
||||
for (let i = 0; i < category.scripts.length; i++) {
|
||||
expectSameScript(node.children[i], category.scripts[i]);
|
||||
}
|
||||
function getErrorMessage(field: string) {
|
||||
return `Unexpected node field: ${field}.\n` +
|
||||
`\nActual node:\n${print(node)}` +
|
||||
`\nExpected category:\n${print(category)}`;
|
||||
}
|
||||
}
|
||||
|
||||
function expectSameScript(node: INode, script: IScript): void {
|
||||
expect(node.type).to.equal(NodeType.Script, getErrorMessage('type'));
|
||||
expect(node.id).to.equal(getScriptNodeId(script), getErrorMessage('id'));
|
||||
expect(node.documentationUrls).to.equal(script.documentationUrls, getErrorMessage('documentationUrls'));
|
||||
expect(node.text).to.equal(script.name, getErrorMessage('name'));
|
||||
expect(node.isReversible).to.equal(script.canRevert(), getErrorMessage('canRevert'));
|
||||
expect(node.children).to.equal(undefined);
|
||||
function getErrorMessage(field: string) {
|
||||
return `Unexpected node field: ${field}.` +
|
||||
`\nActual node:\n${print(node)}\n` +
|
||||
`\nExpected script:\n${print(script)}`;
|
||||
}
|
||||
}
|
||||
|
||||
function print(object: any) {
|
||||
return JSON.stringify(object, null, 2);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { NodeType, INode } from '@/presentation/components/Scripts/ScriptsTree/SelectableTree/Node/INode';
|
||||
import { NodePredicateFilter } from '@/presentation/components/Scripts/ScriptsTree/SelectableTree/LiquorTree/NodeWrapper/NodePredicateFilter';
|
||||
import { ILiquorTreeExistingNode } from 'liquor-tree';
|
||||
|
||||
describe('NodePredicateFilter', () => {
|
||||
it('calls predicate with expected node', () => {
|
||||
// arrange
|
||||
const object: ILiquorTreeExistingNode = {
|
||||
id: 'script',
|
||||
data: {
|
||||
text: 'script-text',
|
||||
type: NodeType.Script,
|
||||
documentationUrls: [],
|
||||
isReversible: false,
|
||||
},
|
||||
states: undefined,
|
||||
children: [],
|
||||
};
|
||||
const expected: INode = {
|
||||
id: 'script',
|
||||
text: 'script-text',
|
||||
isReversible: false,
|
||||
documentationUrls: [],
|
||||
children: [],
|
||||
type: NodeType.Script,
|
||||
};
|
||||
let actual: INode;
|
||||
const predicate = (node: INode) => { actual = node; return true; };
|
||||
const sut = new NodePredicateFilter(predicate);
|
||||
// act
|
||||
sut.matcher('nop query', object);
|
||||
// assert
|
||||
expect(actual).to.deep.equal(expected);
|
||||
});
|
||||
describe('returns result from the predicate', () => {
|
||||
for (const expected of [false, true]) {
|
||||
it(expected.toString(), () => {
|
||||
// arrange
|
||||
const sut = new NodePredicateFilter(() => expected);
|
||||
// act
|
||||
const actual = sut.matcher('nop query', getExistingNode());
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function getExistingNode(): ILiquorTreeExistingNode {
|
||||
return {
|
||||
id: 'script',
|
||||
data: {
|
||||
text: 'script-text',
|
||||
type: NodeType.Script,
|
||||
documentationUrls: [],
|
||||
isReversible: false,
|
||||
},
|
||||
states: undefined,
|
||||
children: [],
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { ILiquorTreeNode } from 'liquor-tree';
|
||||
import { NodeType } from '@/presentation/components/Scripts/ScriptsTree/SelectableTree/Node/INode';
|
||||
import { getNewState } from '@/presentation/components/Scripts/ScriptsTree/SelectableTree/LiquorTree/NodeWrapper/NodeStateUpdater';
|
||||
|
||||
describe('NodeStateUpdater', () => {
|
||||
describe('getNewState', () => {
|
||||
describe('checked', () => {
|
||||
describe('script node', () => {
|
||||
it('true when selected', () => {
|
||||
// arrange
|
||||
const node = getScriptNode();
|
||||
const selectedScriptNodeIds = [ 'a', 'b', node.id, 'c' ];
|
||||
// act
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(state.checked).to.equal(true);
|
||||
});
|
||||
it('false when unselected', () => {
|
||||
// arrange
|
||||
const node = getScriptNode();
|
||||
const selectedScriptNodeIds = [ 'a', 'b', 'c' ];
|
||||
// act
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(state.checked).to.equal(false);
|
||||
});
|
||||
});
|
||||
describe('category node', () => {
|
||||
it('true when every child selected', () => {
|
||||
// arrange
|
||||
const node = {
|
||||
id: '1',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [
|
||||
{ id: '2',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [ getScriptNode('a'), getScriptNode('b') ],
|
||||
},
|
||||
{ id: '3',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [ getScriptNode('c') ],
|
||||
},
|
||||
],
|
||||
};
|
||||
const selectedScriptNodeIds = [ 'a', 'b', 'c' ];
|
||||
// act
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(state.checked).to.equal(true);
|
||||
});
|
||||
it('false when none of the children is selected', () => {
|
||||
// arrange
|
||||
const node = {
|
||||
id: '1',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [
|
||||
{ id: '2',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [ getScriptNode('a'), getScriptNode('b') ],
|
||||
},
|
||||
{ id: '3',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [ getScriptNode('c') ],
|
||||
},
|
||||
],
|
||||
};
|
||||
const selectedScriptNodeIds = [ 'none', 'of', 'them', 'are', 'selected' ];
|
||||
// act
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(state.checked).to.equal(false);
|
||||
});
|
||||
it('false when some of the children is selected', () => {
|
||||
// arrange
|
||||
const node = {
|
||||
id: '1',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [
|
||||
{
|
||||
id: '2',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [ getScriptNode('a'), getScriptNode('b') ],
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [ getScriptNode('c') ],
|
||||
},
|
||||
],
|
||||
};
|
||||
const selectedScriptNodeIds = [ 'a', 'c', 'unrelated' ];
|
||||
// act
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(state.checked).to.equal(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('indeterminate', () => {
|
||||
describe('script node', () => {
|
||||
it('false when selected', () => {
|
||||
// arrange
|
||||
const node = getScriptNode();
|
||||
const selectedScriptNodeIds = [ 'a', 'b', node.id, 'c' ];
|
||||
// act
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(state.indeterminate).to.equal(false);
|
||||
});
|
||||
it('false when not selected', () => {
|
||||
// arrange
|
||||
const node = getScriptNode();
|
||||
const selectedScriptNodeIds = [ 'a', 'b', 'c' ];
|
||||
// act
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(state.indeterminate).to.equal(false);
|
||||
});
|
||||
});
|
||||
describe('category node', () => {
|
||||
it('false when all children are selected', () => {
|
||||
// arrange
|
||||
const node = {
|
||||
id: '1',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [
|
||||
{ id: '2',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [ getScriptNode('a'), getScriptNode('b') ],
|
||||
},
|
||||
{ id: '3',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [ getScriptNode('c') ],
|
||||
},
|
||||
],
|
||||
};
|
||||
const selectedScriptNodeIds = [ 'a', 'b', 'c' ];
|
||||
// act
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(state.indeterminate).to.equal(false);
|
||||
});
|
||||
it('true when all some are selected', () => {
|
||||
// arrange
|
||||
const node = {
|
||||
id: '1',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [
|
||||
{ id: '2',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [ getScriptNode('a'), getScriptNode('b') ],
|
||||
},
|
||||
{ id: '3',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [ getScriptNode('c') ],
|
||||
},
|
||||
],
|
||||
};
|
||||
const selectedScriptNodeIds = [ 'a' ];
|
||||
// act
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(state.indeterminate).to.equal(true);
|
||||
});
|
||||
it('false when no children are selected', () => {
|
||||
// arrange
|
||||
const node = {
|
||||
id: '1',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [
|
||||
{ id: '2',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [ getScriptNode('a'), getScriptNode('b') ],
|
||||
},
|
||||
{ id: '3',
|
||||
data: { type: NodeType.Category, documentationUrls: [], isReversible: false },
|
||||
children: [ getScriptNode('c') ],
|
||||
},
|
||||
],
|
||||
};
|
||||
const selectedScriptNodeIds = [ 'none', 'of', 'them', 'are', 'selected' ];
|
||||
// act
|
||||
const state = getNewState(node, selectedScriptNodeIds);
|
||||
// assert
|
||||
expect(state.indeterminate).to.equal(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
function getScriptNode(scriptNodeId: string = 'script'): ILiquorTreeNode {
|
||||
return {
|
||||
id: scriptNodeId,
|
||||
data: {
|
||||
type: NodeType.Script,
|
||||
documentationUrls: [],
|
||||
isReversible: false,
|
||||
},
|
||||
children: [],
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,142 @@
|
||||
import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { NodeType, INode } from '@/presentation/components/Scripts/ScriptsTree/SelectableTree/Node/INode';
|
||||
import { ILiquorTreeExistingNode, ILiquorTreeNewNode, ILiquorTreeNodeData, ICustomLiquorTreeData } from 'liquor-tree';
|
||||
import { convertExistingToNode, toNewLiquorTreeNode } from '@/presentation/components/Scripts/ScriptsTree/SelectableTree/LiquorTree/NodeWrapper/NodeTranslator';
|
||||
|
||||
describe('NodeTranslator', () => {
|
||||
it('convertExistingToNode', () => {
|
||||
// arrange
|
||||
const existingNode = getExistingNode();
|
||||
const expected = getNode();
|
||||
// act
|
||||
const actual = convertExistingToNode(existingNode);
|
||||
// assert
|
||||
expect(actual).to.deep.equal(expected);
|
||||
});
|
||||
it('toNewLiquorTreeNode', () => {
|
||||
// arrange
|
||||
const node = getNode();
|
||||
const expected = getNewNode();
|
||||
// act
|
||||
const actual = toNewLiquorTreeNode(node);
|
||||
// assert
|
||||
expect(actual).to.deep.equal(expected);
|
||||
});
|
||||
});
|
||||
|
||||
function getNode(): INode {
|
||||
return {
|
||||
id: '1',
|
||||
text: 'parentcategory',
|
||||
isReversible: true,
|
||||
type: NodeType.Category,
|
||||
documentationUrls: [ 'parentcategory-url1', 'parentcategory-url2 '],
|
||||
children: [
|
||||
{
|
||||
id: '2',
|
||||
text: 'subcategory',
|
||||
isReversible: true,
|
||||
documentationUrls: [ 'subcategory-url1', 'subcategory-url2 '],
|
||||
type: NodeType.Category,
|
||||
children: [
|
||||
{
|
||||
id: 'script1',
|
||||
text: 'cool script 1',
|
||||
isReversible: true,
|
||||
documentationUrls: [ 'script1url1', 'script1url2'],
|
||||
children: [],
|
||||
type: NodeType.Script,
|
||||
},
|
||||
{
|
||||
id: 'script2',
|
||||
text: 'cool script 2',
|
||||
isReversible: true,
|
||||
documentationUrls: [ 'script2url1', 'script2url2'],
|
||||
children: [],
|
||||
type: NodeType.Script,
|
||||
}],
|
||||
}],
|
||||
};
|
||||
}
|
||||
|
||||
function getExpectedExistingNodeData(node: INode): ILiquorTreeNodeData {
|
||||
return {
|
||||
text: node.text,
|
||||
type: node.type,
|
||||
documentationUrls: node.documentationUrls,
|
||||
isReversible: node.isReversible,
|
||||
};
|
||||
}
|
||||
function getExpectedNewNodeData(node: INode): ICustomLiquorTreeData {
|
||||
return {
|
||||
type: node.type,
|
||||
documentationUrls: node.documentationUrls,
|
||||
isReversible: node.isReversible,
|
||||
};
|
||||
}
|
||||
|
||||
function getExistingNode(): ILiquorTreeExistingNode {
|
||||
const base = getNode();
|
||||
return {
|
||||
id: base.id,
|
||||
data: getExpectedExistingNodeData(base),
|
||||
states: undefined,
|
||||
children: [
|
||||
{
|
||||
id: base.children[0].id,
|
||||
data: getExpectedExistingNodeData(base.children[0]),
|
||||
states: undefined,
|
||||
children: [
|
||||
{
|
||||
id: base.children[0].children[0].id,
|
||||
data: getExpectedExistingNodeData(base.children[0].children[0]),
|
||||
states: undefined,
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
id: base.children[0].children[1].id,
|
||||
data: getExpectedExistingNodeData(base.children[0].children[1]),
|
||||
states: undefined,
|
||||
children: [],
|
||||
}],
|
||||
}],
|
||||
};
|
||||
}
|
||||
|
||||
function getNewNode(): ILiquorTreeNewNode {
|
||||
const base = getNode();
|
||||
const commonState = {
|
||||
checked: false,
|
||||
indeterminate: false,
|
||||
};
|
||||
return {
|
||||
id: base.id,
|
||||
text: base.text,
|
||||
data: getExpectedNewNodeData(base),
|
||||
state: commonState,
|
||||
children: [
|
||||
{
|
||||
id: base.children[0].id,
|
||||
text: base.children[0].text,
|
||||
data: getExpectedNewNodeData(base.children[0]),
|
||||
state: commonState,
|
||||
children: [
|
||||
{
|
||||
id: base.children[0].children[0].id,
|
||||
text: base.children[0].children[0].text,
|
||||
data: getExpectedNewNodeData(base.children[0].children[0]),
|
||||
state: commonState,
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
id: base.children[0].children[1].id,
|
||||
text: base.children[0].children[1].text,
|
||||
data: getExpectedNewNodeData(base.children[0].children[1]),
|
||||
state: commonState,
|
||||
children: [],
|
||||
}],
|
||||
}],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { CategoryReverter } from '@/presentation/components/Scripts/ScriptsTree/SelectableTree/Node/Reverter/CategoryReverter';
|
||||
import { getCategoryNodeId } from '@/presentation/components/Scripts/ScriptsTree/ScriptNodeParser';
|
||||
import { SelectedScript } from '@/application/Context/State/Selection/SelectedScript';
|
||||
import { UserSelection } from '@/application/Context/State/Selection/UserSelection';
|
||||
import { CategoryStub } from '../../../../../../../stubs/CategoryStub';
|
||||
import { CategoryCollectionStub } from '../../../../../../../stubs/CategoryCollectionStub';
|
||||
import { ScriptStub } from '../../../../../../../stubs/ScriptStub';
|
||||
|
||||
describe('CategoryReverter', () => {
|
||||
describe('getState', () => {
|
||||
// arrange
|
||||
const scripts = [
|
||||
new ScriptStub('revertable').withRevertCode('REM revert me'),
|
||||
new ScriptStub('revertable2').withRevertCode('REM revert me 2'),
|
||||
];
|
||||
const category = new CategoryStub(1).withScripts(...scripts);
|
||||
const nodeId = getCategoryNodeId(category);
|
||||
const collection = new CategoryCollectionStub().withAction(category);
|
||||
const sut = new CategoryReverter(nodeId, collection);
|
||||
const testCases = [
|
||||
{
|
||||
name: 'false when subscripts are not reverted',
|
||||
state: scripts.map((script) => new SelectedScript(script, false)),
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: 'false when some subscripts are reverted',
|
||||
state: [new SelectedScript(scripts[0], false), new SelectedScript(scripts[0], true)],
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: 'false when subscripts are not reverted',
|
||||
state: scripts.map((script) => new SelectedScript(script, true)),
|
||||
expected: true,
|
||||
},
|
||||
];
|
||||
for (const testCase of testCases) {
|
||||
it(testCase.name, () => {
|
||||
// act
|
||||
const actual = sut.getState(testCase.state);
|
||||
// assert
|
||||
expect(actual).to.equal(testCase.expected);
|
||||
});
|
||||
}
|
||||
});
|
||||
describe('selectWithRevertState', () => {
|
||||
// arrange
|
||||
const scripts = [
|
||||
new ScriptStub('revertable').withRevertCode('REM revert me'),
|
||||
new ScriptStub('revertable2').withRevertCode('REM revert me 2'),
|
||||
];
|
||||
const category = new CategoryStub(1).withScripts(...scripts);
|
||||
const collection = new CategoryCollectionStub().withAction(category);
|
||||
const testCases = [
|
||||
{
|
||||
name: 'selects with revert state when not selected',
|
||||
selection: [],
|
||||
revert: true, expectRevert: true,
|
||||
},
|
||||
{
|
||||
name: 'selects with non-revert state when not selected',
|
||||
selection: [],
|
||||
revert: false, expectRevert: false,
|
||||
},
|
||||
{
|
||||
name: 'switches when already selected with revert state',
|
||||
selection: scripts.map((script) => new SelectedScript(script, true)),
|
||||
revert: false, expectRevert: false,
|
||||
},
|
||||
{
|
||||
name: 'switches when already selected with not revert state',
|
||||
selection: scripts.map((script) => new SelectedScript(script, false)),
|
||||
revert: true, expectRevert: true,
|
||||
},
|
||||
{
|
||||
name: 'keeps revert state when already selected with revert state',
|
||||
selection: scripts.map((script) => new SelectedScript(script, true)),
|
||||
revert: true, expectRevert: true,
|
||||
},
|
||||
{
|
||||
name: 'keeps revert state deselected when already selected wtih non revert state',
|
||||
selection: scripts.map((script) => new SelectedScript(script, false)),
|
||||
revert: false, expectRevert: false,
|
||||
},
|
||||
];
|
||||
const nodeId = getCategoryNodeId(category);
|
||||
for (const testCase of testCases) {
|
||||
it(testCase.name, () => {
|
||||
const selection = new UserSelection(collection, testCase.selection);
|
||||
const sut = new CategoryReverter(nodeId, collection);
|
||||
// act
|
||||
sut.selectWithRevertState(testCase.revert, selection);
|
||||
// assert
|
||||
expect(sut.getState(selection.selectedScripts)).to.equal(testCase.expectRevert);
|
||||
expect(selection.selectedScripts).has.lengthOf(2);
|
||||
expect(selection.selectedScripts[0].id).equal(scripts[0].id);
|
||||
expect(selection.selectedScripts[1].id).equal(scripts[1].id);
|
||||
expect(selection.selectedScripts[0].revert).equal(testCase.expectRevert);
|
||||
expect(selection.selectedScripts[1].revert).equal(testCase.expectRevert);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,48 @@
|
||||
import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { INode, NodeType } from '@/presentation/components/Scripts/ScriptsTree/SelectableTree/Node/INode';
|
||||
import {
|
||||
getReverter } from '@/presentation/components/Scripts/ScriptsTree/SelectableTree/Node/Reverter/ReverterFactory';
|
||||
import { ScriptReverter } from '@/presentation/components/Scripts/ScriptsTree/SelectableTree/Node/Reverter/ScriptReverter';
|
||||
import { CategoryReverter } from '@/presentation/components/Scripts/ScriptsTree/SelectableTree/Node/Reverter/CategoryReverter';
|
||||
import { getScriptNodeId, getCategoryNodeId } from '@/presentation/components/Scripts/ScriptsTree/ScriptNodeParser';
|
||||
import { CategoryCollectionStub } from '../../../../../../../stubs/CategoryCollectionStub';
|
||||
import { CategoryStub } from '../../../../../../../stubs/CategoryStub';
|
||||
import { ScriptStub } from '../../../../../../../stubs/ScriptStub';
|
||||
|
||||
describe('ReverterFactory', () => {
|
||||
describe('getReverter', () => {
|
||||
it('gets CategoryReverter for category node', () => {
|
||||
// arrange
|
||||
const category = new CategoryStub(0).withScriptIds('55');
|
||||
const node = getNodeStub(getCategoryNodeId(category), NodeType.Category);
|
||||
const collection = new CategoryCollectionStub()
|
||||
.withAction(category);
|
||||
// act
|
||||
const result = getReverter(node, collection);
|
||||
// assert
|
||||
expect(result instanceof CategoryReverter).to.equal(true);
|
||||
});
|
||||
it('gets ScriptReverter for script node', () => {
|
||||
// arrange
|
||||
const script = new ScriptStub('test');
|
||||
const node = getNodeStub(getScriptNodeId(script), NodeType.Script);
|
||||
const collection = new CategoryCollectionStub()
|
||||
.withAction(new CategoryStub(0).withScript(script));
|
||||
// act
|
||||
const result = getReverter(node, collection);
|
||||
// assert
|
||||
expect(result instanceof ScriptReverter).to.equal(true);
|
||||
});
|
||||
});
|
||||
function getNodeStub(nodeId: string, type: NodeType): INode {
|
||||
return {
|
||||
id: nodeId,
|
||||
text: 'text',
|
||||
isReversible: false,
|
||||
documentationUrls: [],
|
||||
children: [],
|
||||
type,
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,89 @@
|
||||
import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { ScriptReverter } from '@/presentation/components/Scripts/ScriptsTree/SelectableTree/Node/Reverter/ScriptReverter';
|
||||
import { getScriptNodeId } from '@/presentation/components/Scripts/ScriptsTree/ScriptNodeParser';
|
||||
import { UserSelection } from '@/application/Context/State/Selection/UserSelection';
|
||||
import { SelectedScript } from '@/application/Context/State/Selection/SelectedScript';
|
||||
import { CategoryCollectionStub } from '../../../../../../../stubs/CategoryCollectionStub';
|
||||
import { CategoryStub } from '../../../../../../../stubs/CategoryStub';
|
||||
import { ScriptStub } from '../../../../../../../stubs/ScriptStub';
|
||||
import { SelectedScriptStub } from '../../../../../../../stubs/SelectedScriptStub';
|
||||
|
||||
describe('ScriptReverter', () => {
|
||||
describe('getState', () => {
|
||||
it('false when script is not selected', () => {
|
||||
// arrange
|
||||
const script = new ScriptStub('id');
|
||||
const nodeId = getScriptNodeId(script);
|
||||
const sut = new ScriptReverter(nodeId);
|
||||
// act
|
||||
const actual = sut.getState([]);
|
||||
// assert
|
||||
expect(actual).to.equal(false);
|
||||
});
|
||||
it('false when script is selected but not reverted', () => {
|
||||
// arrange
|
||||
const scripts = [ new SelectedScriptStub('id'), new SelectedScriptStub('dummy') ];
|
||||
const nodeId = getScriptNodeId(scripts[0].script);
|
||||
const sut = new ScriptReverter(nodeId);
|
||||
// act
|
||||
const actual = sut.getState(scripts);
|
||||
// assert
|
||||
expect(actual).to.equal(false);
|
||||
});
|
||||
it('true when script is selected and reverted', () => {
|
||||
// arrange
|
||||
const scripts = [ new SelectedScriptStub('id', true), new SelectedScriptStub('dummy') ];
|
||||
const nodeId = getScriptNodeId(scripts[0].script);
|
||||
const sut = new ScriptReverter(nodeId);
|
||||
// act
|
||||
const actual = sut.getState(scripts);
|
||||
// assert
|
||||
expect(actual).to.equal(true);
|
||||
});
|
||||
});
|
||||
describe('selectWithRevertState', () => {
|
||||
// arrange
|
||||
const script = new ScriptStub('id');
|
||||
const collection = new CategoryCollectionStub()
|
||||
.withAction(new CategoryStub(5).withScript(script));
|
||||
const testCases = [
|
||||
{
|
||||
name: 'selects with revert state when not selected',
|
||||
selection: [], revert: true, expectRevert: true,
|
||||
},
|
||||
{
|
||||
name: 'selects with non-revert state when not selected',
|
||||
selection: [], revert: false, expectRevert: false,
|
||||
},
|
||||
{
|
||||
name: 'switches when already selected with revert state',
|
||||
selection: [ new SelectedScript(script, true)], revert: false, expectRevert: false,
|
||||
},
|
||||
{
|
||||
name: 'switches when already selected with not revert state',
|
||||
selection: [ new SelectedScript(script, false)], revert: true, expectRevert: true,
|
||||
},
|
||||
{
|
||||
name: 'keeps revert state when already selected with revert state',
|
||||
selection: [ new SelectedScript(script, true)], revert: true, expectRevert: true,
|
||||
},
|
||||
{
|
||||
name: 'keeps revert state deselected when already selected with non revert state',
|
||||
selection: [ new SelectedScript(script, false)], revert: false, expectRevert: false,
|
||||
},
|
||||
];
|
||||
const nodeId = getScriptNodeId(script);
|
||||
for (const testCase of testCases) {
|
||||
it(testCase.name, () => {
|
||||
const selection = new UserSelection(collection, testCase.selection);
|
||||
const sut = new ScriptReverter(nodeId);
|
||||
// act
|
||||
sut.selectWithRevertState(testCase.revert, selection);
|
||||
// assert
|
||||
expect(selection.isSelected(script.id)).to.equal(true);
|
||||
expect(selection.selectedScripts[0].revert).equal(testCase.expectRevert);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user