@hashgraph/solo
Version:
An opinionated CLI tool to deploy and manage private Hedera Networks.
180 lines • 9.41 kB
JavaScript
// SPDX-License-Identifier: Apache-2.0
import { expect } from 'chai';
import { Lexer } from '../../../../../src/data/key/lexer/lexer.js';
import { Forest } from '../../../../../src/data/key/lexer/forest.js';
import { ConfigKeyError } from '../../../../../src/data/key/config-key-error.js';
function overlappingPathLexer() {
const lexerMap = new Map([
['root.object.value1', '1'],
['root.object.value2', '2'],
['root.object.value3', '3'],
['root.array.0.index1', '4'],
['root.array.0.index2', '5'],
['root.array.0.index3', '6'],
['deployments.0.clusters.0', 'true'],
['deployments.0.clusters.1', 'false'],
['deployments.0.settings.0.0', 'bob'],
['deployments.0.settings.0.1', 'charlie'],
]);
const lexer = new Lexer(lexerMap);
lexer.renderTrees();
expect(lexer.rootNodes).to.have.lengthOf(2);
const rootNode = lexer.rootNodes.find(v => v.name === 'root');
expect(rootNode.name).to.equal('root');
expect(rootNode.children).to.have.lengthOf(2);
const subObjectNode = rootNode.children.find(v => v.name === 'object');
expect(subObjectNode).to.not.be.undefined.and.not.be.null;
expect(subObjectNode.children).to.have.lengthOf(3);
const subArrayNode = rootNode.children.find(v => v.name === 'array');
expect(subArrayNode).to.not.be.undefined.and.not.be.null;
expect(subArrayNode.children).to.have.lengthOf(1);
expect(subArrayNode.isArray()).to.be.true;
const subArrayIndexNode = subArrayNode.children[0];
expect(subArrayIndexNode).to.not.be.undefined.and.not.be.null;
expect(subArrayIndexNode.name).to.equal('0');
expect(subArrayIndexNode.isArrayIndex()).to.be.true;
expect(subArrayIndexNode.children).to.have.lengthOf(3);
const index1Node = subArrayIndexNode.children.find(v => v.name === 'index1');
expect(index1Node).to.not.be.undefined.and.not.be.null;
expect(index1Node.isLeaf()).to.be.true;
expect(index1Node.value).to.be.equal('4');
const deploymentsNode = lexer.rootNodes.find(v => v.name === 'deployments');
expect(deploymentsNode).to.not.be.undefined.and.not.be.null;
expect(deploymentsNode.children).to.have.lengthOf(1);
expect(deploymentsNode.isArray()).to.be.true;
const deploymentsArrayIndexNode = deploymentsNode.children[0];
expect(deploymentsArrayIndexNode).to.not.be.undefined.and.not.be.null;
expect(deploymentsArrayIndexNode.isArrayIndex()).to.be.true;
const clustersNode = deploymentsArrayIndexNode.children[0];
expect(clustersNode).to.not.be.undefined.and.not.be.null;
expect(clustersNode.name).to.equal('clusters');
expect(clustersNode.isArray()).to.be.true;
expect(clustersNode.children).to.have.lengthOf(2);
const clustersArrayIndex0Node = clustersNode.children[0];
expect(clustersArrayIndex0Node).to.not.be.undefined.and.not.be.null;
expect(clustersArrayIndex0Node.isArrayIndex()).to.be.true;
expect(clustersArrayIndex0Node.isLeaf()).to.be.true;
expect(clustersArrayIndex0Node.value).to.be.equal('true');
const clustersArrayIndex1Node = clustersNode.children[1];
expect(clustersArrayIndex1Node).to.not.be.undefined.and.not.be.null;
expect(clustersArrayIndex1Node.isArrayIndex()).to.be.true;
expect(clustersArrayIndex1Node.isLeaf()).to.be.true;
expect(clustersArrayIndex1Node.value).to.be.equal('false');
const settingsNode = deploymentsArrayIndexNode.children[1];
expect(settingsNode).to.not.be.undefined.and.not.be.null;
expect(settingsNode.name).to.equal('settings');
expect(settingsNode.isArray()).to.be.true;
expect(settingsNode.children).to.have.lengthOf(1);
const settingsArrayIndex0Node = settingsNode.children[0];
expect(settingsArrayIndex0Node).to.not.be.undefined.and.not.be.null;
expect(settingsArrayIndex0Node.name).to.equal('0');
expect(settingsArrayIndex0Node.isArrayIndex()).to.be.true;
expect(settingsArrayIndex0Node.children).to.have.lengthOf(2);
const settingsArrayIndex0Index0Node = settingsArrayIndex0Node.children[0];
expect(settingsArrayIndex0Index0Node).to.not.be.undefined.and.not.be.null;
expect(settingsArrayIndex0Index0Node.name).to.equal('0');
expect(settingsArrayIndex0Index0Node.isLeaf()).to.be.true;
expect(settingsArrayIndex0Index0Node.value).to.be.equal('bob');
const settingsArrayIndex0Index1Node = settingsArrayIndex0Node.children[1];
expect(settingsArrayIndex0Index1Node).to.not.be.undefined.and.not.be.null;
expect(settingsArrayIndex0Index1Node.name).to.equal('1');
expect(settingsArrayIndex0Index1Node.isLeaf()).to.be.true;
expect(settingsArrayIndex0Index1Node.value).to.be.equal('charlie');
return {
lexer,
rootNode,
subObjectNode,
subArrayNode,
subArrayIndexNode,
deploymentsNode,
deploymentsArrayIndexNode,
clustersNode,
};
}
describe('Lexer', () => {
it('with empty token in constructor should throw error', () => {
expect(() => {
new Lexer(null);
}).to.throw('tokens must be provided');
});
it('with empty formatter in constructor should throw error', () => {
expect(() => {
new Lexer(new Map(), null);
}).to.throw('formatter must be provided');
});
it('get rootNodes should return empty array', () => {
const lexer = new Lexer(new Map());
expect(lexer.rootNodes).to.be.empty;
});
it('rootNodeFor with array segment', () => {
const lexer = new Lexer(new Map());
// @ts-expect-error - access private method for testing
const node = lexer.rootNodeFor(['secret', '42', 'everything', 'is', '42', 'true']);
expect(node.name).to.equal('secret');
expect(node.isArray()).to.be.true;
});
it('processKeys with an array segment', () => {
const lexerMap = new Map([
['secret.42.is.everything', 'true'],
['everything-is-42', 'true'],
['secret.42.is.42', 'true'],
['42.is.everything', 'true'],
['array.0.is.everything', 'true'],
['array.1.is.everything', 'true'],
['array.alpha.2.is.everything', 'true'],
]);
let lexer = new Lexer(lexerMap);
expect(() => lexer.rootNodes).to.throw(ConfigKeyError, "Cannot add a leaf node to an array node [ parent: 'secret.42.is', child: 'everything' ]");
lexerMap.delete('secret.42.is.everything');
lexer = new Lexer(lexerMap);
const nodes = lexer.rootNodes;
expect(nodes).to.have.lengthOf(4);
});
it('processKeys works with overlapping paths', () => {
overlappingPathLexer();
});
it('addValue works with overlapping paths', () => {
const { lexer, rootNode, subObjectNode, subArrayIndexNode } = overlappingPathLexer();
lexer.addValue('root.array.0.index4', '7');
lexer.addValue('root.object.value4', '8');
lexer.addValue('root.object.clusterRef', 'SoloCheck');
expect(lexer.rootNodes).to.have.lengthOf(2);
expect(rootNode.children).to.have.lengthOf(2);
expect(subObjectNode.children).to.have.lengthOf(5);
expect(subArrayIndexNode.children).to.have.lengthOf(4);
const index4Node = subArrayIndexNode.children.find((v) => v.name === 'index4');
expect(index4Node).to.not.be.undefined.and.not.be.null;
expect(index4Node.isLeaf()).to.be.true;
expect(index4Node.value).to.be.equal('7');
expect(subObjectNode.children.some((v) => v.name === 'clusterref')).to.be.false;
expect(subObjectNode.children.some((v) => v.name === 'clusterRef')).to.be.true;
const value4Node = subObjectNode.children.find((v) => v.name === 'value4');
expect(value4Node).to.not.be.undefined.and.not.be.null;
expect(value4Node.isLeaf()).to.be.true;
expect(value4Node.value).to.be.equal('8');
const clusterReference = subObjectNode.children.find((v) => v.name === 'clusterRef');
expect(clusterReference).to.not.be.undefined.and.not.be.null;
expect(clusterReference.isLeaf()).to.be.true;
expect(clusterReference.value).to.be.equal('SoloCheck');
});
it('replaceValue works with overlapping paths', () => {
const { lexer, rootNode, subObjectNode, subArrayNode, subArrayIndexNode } = overlappingPathLexer();
const forest = Forest.fromLexer(lexer);
lexer.replaceValue(forest.nodeFor('root.array.0.index1'), '9');
lexer.replaceValue(forest.nodeFor('root.object.value1'), '10');
expect(lexer.rootNodes).to.have.lengthOf(2);
expect(rootNode.children).to.have.lengthOf(2);
expect(subObjectNode.children).to.have.lengthOf(3);
expect(subArrayNode.children).to.have.lengthOf(1);
expect(subArrayIndexNode.children).to.have.lengthOf(3);
const index1Node = subArrayIndexNode.children.find(v => v.name === 'index1');
expect(index1Node).to.not.be.undefined.and.not.be.null;
expect(index1Node.isLeaf()).to.be.true;
expect(index1Node.value).to.be.equal('9');
const value1Node = subObjectNode.children.find(v => v.name === 'value1');
expect(value1Node).to.not.be.undefined.and.not.be.null;
expect(value1Node.isLeaf()).to.be.true;
expect(value1Node.value).to.be.equal('10');
});
});
//# sourceMappingURL=lexer.test.js.map