fix search (got broken in b789250) with tests and refactorings

This commit is contained in:
undergroundwires
2020-09-02 22:44:20 +01:00
parent a23d28f2cf
commit 8bbe6ebf75
10 changed files with 379 additions and 97 deletions

View File

@@ -0,0 +1,63 @@
import 'mocha';
import { expect } from 'chai';
import { NodeType, INode } from '@/presentation/Scripts/ScriptsTree/SelectableTree/Node/INode';
import { NodePredicateFilter } from '@/presentation/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: [],
};
}

View File

@@ -0,0 +1,110 @@
import 'mocha';
import { expect } from 'chai';
import { ILiquorTreeNode } from 'liquor-tree';
import { NodeType } from '@/presentation/Scripts/ScriptsTree/SelectableTree/Node/INode';
import { getNewCheckedState } from '@/presentation/Scripts/ScriptsTree/SelectableTree/LiquorTree/NodeWrapper/NodeStateUpdater';
describe('getNewCheckedState', () => {
describe('script node', () => {
it('state is true when selected', () => {
// arrange
const node = getScriptNode();
const selectedScriptNodeIds = [ 'a', 'b', node.id, 'c' ];
// act
const actual = getNewCheckedState(node, selectedScriptNodeIds);
// assert
expect(actual).to.equal(true);
});
it('state is false when unselected', () => {
// arrange
const node = getScriptNode();
const selectedScriptNodeIds = [ 'a', 'b', 'c' ];
// act
const actual = getNewCheckedState(node, selectedScriptNodeIds);
// assert
expect(actual).to.equal(false);
});
});
describe('category node', () => {
it('state is 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 actual = getNewCheckedState(node, selectedScriptNodeIds);
// assert
expect(actual).to.equal(true);
});
it('state is 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 actual = getNewCheckedState(node, selectedScriptNodeIds);
// assert
expect(actual).to.equal(false);
});
it('state is 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 actual = getNewCheckedState(node, selectedScriptNodeIds);
// assert
expect(actual).to.equal(false);
});
});
});
function getScriptNode(scriptNodeId: string = 'script'): ILiquorTreeNode {
return {
id: scriptNodeId,
data: {
type: NodeType.Script,
documentationUrls: [],
isReversible: false,
},
children: [],
};
}

View File

@@ -0,0 +1,141 @@
import 'mocha';
import { expect } from 'chai';
import { NodeType, INode } from '@/presentation/Scripts/ScriptsTree/SelectableTree/Node/INode';
import { ILiquorTreeExistingNode, ILiquorTreeNewNode, ILiquorTreeNodeData, ICustomLiquorTreeData } from 'liquor-tree';
import { convertExistingToNode, toNewLiquorTreeNode } from '@/presentation/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,
};
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: [],
}],
}],
};
}