Refactor to unify scripts/categories as Executable

This commit consolidates scripts and categories under a unified
'Executable' concept. This simplifies the architecture and improves code
readability.

- Introduce subfolders within `src/domain` to segregate domain elements.
- Update class and interface names by removing the 'I' prefix in
  alignment with new coding standards.
- Replace 'Node' with 'Executable' to clarify usage; reserve 'Node'
  exclusively for the UI's tree component.
This commit is contained in:
undergroundwires
2024-06-12 12:36:40 +02:00
parent 8becc7dbc4
commit c138f74460
230 changed files with 1120 additions and 1039 deletions

View File

@@ -2,7 +2,8 @@ import { describe, it, expect } from 'vitest';
import { CategoryStub } from '@tests/unit/shared/Stubs/CategoryStub';
import { ScriptStub } from '@tests/unit/shared/Stubs/ScriptStub';
import { AppliedFilterResult } from '@/application/Context/State/Filter/Result/AppliedFilterResult';
import type { ICategory, IScript } from '@/domain/ICategory';
import type { Category } from '@/domain/Executables/Category/Category';
import type { Script } from '@/domain/Executables/Script/Script';
describe('AppliedFilterResult', () => {
describe('constructor', () => {
@@ -68,18 +69,18 @@ describe('AppliedFilterResult', () => {
});
class ResultBuilder {
private scriptMatches: readonly IScript[] = [new ScriptStub('id')];
private scriptMatches: readonly Script[] = [new ScriptStub('id')];
private categoryMatches: readonly ICategory[] = [new CategoryStub(5)];
private categoryMatches: readonly Category[] = [new CategoryStub(5)];
private query: string = `[${ResultBuilder.name}]query`;
public withScriptMatches(scriptMatches: readonly IScript[]): this {
public withScriptMatches(scriptMatches: readonly Script[]): this {
this.scriptMatches = scriptMatches;
return this;
}
public withCategoryMatches(categoryMatches: readonly ICategory[]): this {
public withCategoryMatches(categoryMatches: readonly Category[]): this {
this.categoryMatches = categoryMatches;
return this;
}

View File

@@ -3,8 +3,8 @@ import { CategoryStub } from '@tests/unit/shared/Stubs/CategoryStub';
import { ScriptStub } from '@tests/unit/shared/Stubs/ScriptStub';
import { CategoryCollectionStub } from '@tests/unit/shared/Stubs/CategoryCollectionStub';
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
import type { ICategory } from '@/domain/ICategory';
import type { IScript } from '@/domain/IScript';
import type { Category } from '@/domain/Executables/Category/Category';
import type { Script } from '@/domain/Executables/Script/Script';
import type { FilterResult } from '@/application/Context/State/Filter/Result/FilterResult';
import { LinearFilterStrategy } from '@/application/Context/State/Filter/Strategy/LinearFilterStrategy';
@@ -89,7 +89,7 @@ describe('LinearFilterStrategy', () => {
interface ScriptMatchTestScenario {
readonly description: string;
readonly filter: string;
readonly matchingScript: IScript;
readonly matchingScript: Script;
}
const testScenarios: readonly ScriptMatchTestScenario[] = [
{
@@ -134,7 +134,7 @@ describe('LinearFilterStrategy', () => {
it('returns multiple matching scripts', () => {
// arrange
const filter = 'matching filter';
const matchingScripts: readonly IScript[] = [
const matchingScripts: readonly Script[] = [
createMatchingScript(filter),
createMatchingScript(filter),
];
@@ -165,7 +165,7 @@ describe('LinearFilterStrategy', () => {
interface CategoryMatchTestScenario {
readonly description: string;
readonly filter: string;
readonly matchingCategory: ICategory;
readonly matchingCategory: Category;
}
const testScenarios: readonly CategoryMatchTestScenario[] = [
{
@@ -200,7 +200,7 @@ describe('LinearFilterStrategy', () => {
it('returns multiple matching categories', () => {
// arrange
const filter = 'matching filter';
const matchingCategories: readonly ICategory[] = [
const matchingCategories: readonly Category[] = [
createMatchingCategory(filter),
createMatchingCategory(filter),
];
@@ -237,7 +237,7 @@ function createMatchingCategory(
function expectCategoryMatches(
actualFilter: FilterResult,
expectedMatches: readonly ICategory[],
expectedMatches: readonly Category[],
): void {
expect(actualFilter.hasAnyMatches()).be.equal(true);
expect(actualFilter.categoryMatches).to.have.lengthOf(expectedMatches.length);
@@ -246,7 +246,7 @@ function expectCategoryMatches(
function expectScriptMatches(
actualFilter: FilterResult,
expectedMatches: readonly IScript[],
expectedMatches: readonly Script[],
): void {
expect(actualFilter.hasAnyMatches()).be.equal(true);
expect(actualFilter.scriptMatches).to.have.lengthOf(expectedMatches.length);

View File

@@ -8,7 +8,8 @@ import { ScriptSelectionStub } from '@tests/unit/shared/Stubs/ScriptSelectionStu
import type { CategorySelectionChange } from '@/application/Context/State/Selection/Category/CategorySelectionChange';
import type { ScriptSelectionChange, ScriptSelectionChangeCommand } from '@/application/Context/State/Selection/Script/ScriptSelectionChange';
import { expectExists } from '@tests/shared/Assertions/ExpectExists';
import type { ICategory, IScript } from '@/domain/ICategory';
import type { Category } from '@/domain/Executables/Category/Category';
import type { Script } from '@/domain/Executables/Script/Script';
describe('ScriptToCategorySelectionMapper', () => {
describe('areAllScriptsSelected', () => {
@@ -64,8 +65,8 @@ describe('ScriptToCategorySelectionMapper', () => {
readonly description: string;
readonly changes: readonly CategorySelectionChange[];
readonly categories: ReadonlyArray<{
readonly categoryId: ICategory['id'],
readonly scriptIds: readonly IScript['id'][],
readonly categoryId: Category['id'],
readonly scriptIds: readonly Script['id'][],
}>;
readonly expected: readonly ScriptSelectionChange[],
}> = [

View File

@@ -9,7 +9,7 @@ import type { SelectedScript } from '@/application/Context/State/Selection/Scrip
import { BatchedDebounceStub } from '@tests/unit/shared/Stubs/BatchedDebounceStub';
import type { ScriptSelectionChange, ScriptSelectionChangeCommand } from '@/application/Context/State/Selection/Script/ScriptSelectionChange';
import { expectExists } from '@tests/shared/Assertions/ExpectExists';
import type { IScript } from '@/domain/IScript';
import type { Script } from '@/domain/Executables/Script/Script';
import { expectEqualSelectedScripts } from './ExpectEqualSelectedScripts';
type DebounceArg = ScriptSelectionChangeCommand;
@@ -538,7 +538,7 @@ describe('DebouncedScriptSelection', () => {
});
});
function createCollectionWithScripts(...scripts: IScript[]): CategoryCollectionStub {
function createCollectionWithScripts(...scripts: Script[]): CategoryCollectionStub {
const category = new CategoryStub(1).withScripts(...scripts);
const collection = new CategoryCollectionStub().withAction(category);
return collection;

View File

@@ -1,14 +1,14 @@
import { describe, it, expect } from 'vitest';
import type { IEntity } from '@/infrastructure/Entity/IEntity';
import { parseCategoryCollection } from '@/application/Parser/CategoryCollectionParser';
import { parseCategory } from '@/application/Parser/CategoryParser';
import { parseCategory } from '@/application/Parser/Executable/CategoryParser';
import { OperatingSystem } from '@/domain/OperatingSystem';
import { RecommendationLevel } from '@/domain/RecommendationLevel';
import { RecommendationLevel } from '@/domain/Executables/Script/RecommendationLevel';
import { ScriptingDefinitionParser } from '@/application/Parser/ScriptingDefinition/ScriptingDefinitionParser';
import { EnumParserStub } from '@tests/unit/shared/Stubs/EnumParserStub';
import { ProjectDetailsStub } from '@tests/unit/shared/Stubs/ProjectDetailsStub';
import { getCategoryStub, CollectionDataStub } from '@tests/unit/shared/Stubs/CollectionDataStub';
import { CategoryCollectionParseContextStub } from '@tests/unit/shared/Stubs/CategoryCollectionParseContextStub';
import { CategoryCollectionSpecificUtilitiesStub } from '@tests/unit/shared/Stubs/CategoryCollectionSpecificUtilitiesStub';
import { CategoryDataStub } from '@tests/unit/shared/Stubs/CategoryDataStub';
import { createScriptDataWithCall, createScriptDataWithCode } from '@tests/unit/shared/Stubs/ScriptDataStub';
import { createFunctionDataWithCode } from '@tests/unit/shared/Stubs/FunctionDataStub';
@@ -35,7 +35,7 @@ describe('CategoryCollectionParser', () => {
it('parses actions', () => {
// arrange
const actions = [getCategoryStub('test1'), getCategoryStub('test2')];
const context = new CategoryCollectionParseContextStub();
const context = new CategoryCollectionSpecificUtilitiesStub();
const expected = [parseCategory(actions[0], context), parseCategory(actions[1], context)];
const collection = new CollectionDataStub()
.withActions(actions);

View File

@@ -0,0 +1,100 @@
import { describe, it, expect } from 'vitest';
import type { ISyntaxFactory } from '@/application/Parser/Executable/Script/Validation/Syntax/ISyntaxFactory';
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
import { LanguageSyntaxStub } from '@tests/unit/shared/Stubs/LanguageSyntaxStub';
import { ScriptingDefinitionStub } from '@tests/unit/shared/Stubs/ScriptingDefinitionStub';
import type { FunctionData } from '@/application/collections/';
import { itEachAbsentCollectionValue } from '@tests/unit/shared/TestCases/AbsentTests';
import { createFunctionDataWithCode } from '@tests/unit/shared/Stubs/FunctionDataStub';
import { ScriptCompiler } from '@/application/Parser/Executable/Script/Compiler/ScriptCompiler';
import { createCollectionUtilities } from '@/application/Parser/Executable/CategoryCollectionSpecificUtilities';
import type { IScriptingDefinition } from '@/domain/IScriptingDefinition';
import { createSyntaxFactoryStub } from '@tests/unit/shared/Stubs/SyntaxFactoryStub';
describe('CategoryCollectionSpecificUtilities', () => {
describe('createCollectionUtilities', () => {
describe('functionsData', () => {
describe('can create with absent data', () => {
itEachAbsentCollectionValue<FunctionData>((absentValue) => {
// arrange
const context = new TextContext()
.withData(absentValue);
// act
const act = () => context.createCollectionUtilities();
// assert
expect(act).to.not.throw();
}, { excludeNull: true });
});
});
});
describe('compiler', () => {
it('constructed as expected', () => {
// arrange
const functionsData = [createFunctionDataWithCode()];
const syntax = new LanguageSyntaxStub();
const expected = new ScriptCompiler(functionsData, syntax);
const language = ScriptingLanguage.shellscript;
const factoryMock = createSyntaxFactoryStub(language, syntax);
const definition = new ScriptingDefinitionStub()
.withLanguage(language);
const context = new TextContext()
.withData(functionsData)
.withScripting(definition)
.withSyntaxFactory(factoryMock);
// act
const utilities = context.createCollectionUtilities();
// assert
const actual = utilities.compiler;
expect(actual).to.deep.equal(expected);
});
});
describe('syntax', () => {
it('set from syntax factory', () => {
// arrange
const language = ScriptingLanguage.shellscript;
const expected = new LanguageSyntaxStub();
const factoryMock = createSyntaxFactoryStub(language, expected);
const definition = new ScriptingDefinitionStub()
.withLanguage(language);
const context = new TextContext()
.withScripting(definition)
.withSyntaxFactory(factoryMock);
// act
const utilities = context.createCollectionUtilities();
// assert
const actual = utilities.syntax;
expect(actual).to.equal(expected);
});
});
});
class TextContext {
private functionsData: readonly FunctionData[] | undefined = [createFunctionDataWithCode()];
private scripting: IScriptingDefinition = new ScriptingDefinitionStub();
private syntaxFactory: ISyntaxFactory = createSyntaxFactoryStub();
public withScripting(scripting: IScriptingDefinition): this {
this.scripting = scripting;
return this;
}
public withData(data: readonly FunctionData[] | undefined): this {
this.functionsData = data;
return this;
}
public withSyntaxFactory(syntaxFactory: ISyntaxFactory): this {
this.syntaxFactory = syntaxFactory;
return this;
}
public createCollectionUtilities(): ReturnType<typeof createCollectionUtilities> {
return createCollectionUtilities(
this.functionsData,
this.scripting,
this.syntaxFactory,
);
}
}

View File

@@ -1,19 +1,18 @@
import { describe, it, expect } from 'vitest';
import type { CategoryData, CategoryOrScriptData } from '@/application/collections/';
import { type CategoryFactory, parseCategory } from '@/application/Parser/CategoryParser';
import { type ScriptParser } from '@/application/Parser/Script/ScriptParser';
import { type DocsParser } from '@/application/Parser/DocumentationParser';
import { CategoryCollectionParseContextStub } from '@tests/unit/shared/Stubs/CategoryCollectionParseContextStub';
import type { CategoryData, ExecutableData } from '@/application/collections/';
import { type CategoryFactory, parseCategory } from '@/application/Parser/Executable/CategoryParser';
import { type ScriptParser } from '@/application/Parser/Executable/Script/ScriptParser';
import { type DocsParser } from '@/application/Parser/Executable/DocumentationParser';
import { CategoryCollectionSpecificUtilitiesStub } from '@tests/unit/shared/Stubs/CategoryCollectionSpecificUtilitiesStub';
import { CategoryDataStub } from '@tests/unit/shared/Stubs/CategoryDataStub';
import { getAbsentCollectionTestCases } from '@tests/unit/shared/TestCases/AbsentTests';
import { NodeDataType } from '@/application/Parser/NodeValidation/NodeDataType';
import type { ICategoryCollectionParseContext } from '@/application/Parser/Script/ICategoryCollectionParseContext';
import { ExecutableType } from '@/application/Parser/Executable/Validation/ExecutableType';
import { createScriptDataWithCall, createScriptDataWithCode } from '@tests/unit/shared/Stubs/ScriptDataStub';
import type { ErrorWithContextWrapper } from '@/application/Parser/ContextualError';
import { ErrorWrapperStub } from '@tests/unit/shared/Stubs/ErrorWrapperStub';
import type { NodeDataValidatorFactory } from '@/application/Parser/NodeValidation/NodeDataValidator';
import { NodeDataValidatorStub, createNodeDataValidatorFactoryStub } from '@tests/unit/shared/Stubs/NodeDataValidatorStub';
import type { CategoryNodeErrorContext, UnknownNodeErrorContext } from '@/application/Parser/NodeValidation/NodeDataErrorContext';
import type { ExecutableValidatorFactory } from '@/application/Parser/Executable/Validation/ExecutableValidator';
import { ExecutableValidatorStub, createExecutableValidatorFactoryStub } from '@tests/unit/shared/Stubs/ExecutableValidatorStub';
import type { CategoryErrorContext, UnknownExecutableErrorContext } from '@/application/Parser/Executable/Validation/ExecutableErrorContext';
import { CategoryStub } from '@tests/unit/shared/Stubs/CategoryStub';
import { createCategoryFactorySpy } from '@tests/unit/shared/Stubs/CategoryFactoryStub';
import { expectExists } from '@tests/shared/Assertions/ExpectExists';
@@ -21,9 +20,9 @@ import { ScriptStub } from '@tests/unit/shared/Stubs/ScriptStub';
import { ScriptParserStub } from '@tests/unit/shared/Stubs/ScriptParserStub';
import { formatAssertionMessage } from '@tests/shared/FormatAssertionMessage';
import { indentText } from '@tests/shared/Text';
import { itThrowsContextualError } from './ContextualErrorTester';
import { itValidatesName, itValidatesDefinedData, itAsserts } from './NodeDataValidationTester';
import { generateDataValidationTestScenarios } from './DataValidationTestScenarioGenerator';
import { itThrowsContextualError } from '../ContextualErrorTester';
import { itValidatesName, itValidatesDefinedData, itAsserts } from './Validation/ExecutableValidationTester';
import { generateDataValidationTestScenarios } from './Validation/DataValidationTestScenarioGenerator';
describe('CategoryParser', () => {
describe('parseCategory', () => {
@@ -33,9 +32,9 @@ describe('CategoryParser', () => {
const expectedName = 'expected category name to be validated';
const category = new CategoryDataStub()
.withName(expectedName);
const expectedContext: CategoryNodeErrorContext = {
type: NodeDataType.Category,
selfNode: category,
const expectedContext: CategoryErrorContext = {
type: ExecutableType.Category,
self: category,
};
itValidatesName((validatorFactory) => {
// act
@@ -53,9 +52,9 @@ describe('CategoryParser', () => {
describe('validates for defined data', () => {
// arrange
const category = new CategoryDataStub();
const expectedContext: CategoryNodeErrorContext = {
type: NodeDataType.Category,
selfNode: category,
const expectedContext: CategoryErrorContext = {
type: ExecutableType.Category,
self: category,
};
itValidatesDefinedData(
(validatorFactory) => {
@@ -75,13 +74,13 @@ describe('CategoryParser', () => {
describe('validates that category has some children', () => {
const categoryName = 'test';
const testScenarios = generateDataValidationTestScenarios<CategoryData>({
expectFail: getAbsentCollectionTestCases<CategoryOrScriptData>().map(({
expectFail: getAbsentCollectionTestCases<ExecutableData>().map(({
valueName, absentValue: absentCollectionValue,
}) => ({
description: `with \`${valueName}\` value as children`,
data: new CategoryDataStub()
.withName(categoryName)
.withChildren(absentCollectionValue as unknown as CategoryOrScriptData[]),
.withChildren(absentCollectionValue as unknown as ExecutableData[]),
})),
expectPass: [{
description: 'has single children',
@@ -98,9 +97,9 @@ describe('CategoryParser', () => {
expectedConditionResult: expectedPass,
test: (validatorFactory) => {
const expectedMessage = `"${categoryName}" has no children.`;
const expectedContext: CategoryNodeErrorContext = {
type: NodeDataType.Category,
selfNode: categoryData,
const expectedContext: CategoryErrorContext = {
type: ExecutableType.Category,
self: categoryData,
};
// act
try {
@@ -121,10 +120,10 @@ describe('CategoryParser', () => {
});
describe('validates that a child is a category or a script', () => {
// arrange
const testScenarios = generateDataValidationTestScenarios<CategoryOrScriptData>({
const testScenarios = generateDataValidationTestScenarios<ExecutableData>({
expectFail: [{
description: 'child has incorrect properties',
data: { property: 'non-empty-value' } as unknown as CategoryOrScriptData,
data: { property: 'non-empty-value' } as unknown as ExecutableData,
}],
expectPass: [
{
@@ -148,13 +147,13 @@ describe('CategoryParser', () => {
itAsserts({
expectedConditionResult: expectedPass,
test: (validatorFactory) => {
const expectedError = 'Node is neither a category or a script.';
const expectedError = 'Executable is neither a category or a script.';
const parent = new CategoryDataStub()
.withName('parent')
.withChildren([new CategoryDataStub().withName('valid child'), childData]);
const expectedContext: UnknownNodeErrorContext = {
selfNode: childData,
parentNode: parent,
const expectedContext: UnknownExecutableErrorContext = {
self: childData,
parentCategory: parent,
};
// act
new TestBuilder()
@@ -180,9 +179,9 @@ describe('CategoryParser', () => {
const parent = new CategoryDataStub()
.withName('parent')
.withChildren([child]);
const expectedContext: UnknownNodeErrorContext = {
selfNode: child,
parentNode: parent,
const expectedContext: UnknownExecutableErrorContext = {
self: child,
parentCategory: parent,
};
itValidatesDefinedData(
(validatorFactory) => {
@@ -210,10 +209,10 @@ describe('CategoryParser', () => {
const parent = new CategoryDataStub()
.withName('parent')
.withChildren([child]);
const expectedContext: CategoryNodeErrorContext = {
type: NodeDataType.Category,
selfNode: grandChild,
parentNode: child,
const expectedContext: CategoryErrorContext = {
type: ExecutableType.Category,
self: grandChild,
parentCategory: child,
};
itValidatesName((validatorFactory) => {
// act
@@ -238,7 +237,7 @@ describe('CategoryParser', () => {
// act & assert
itThrowsContextualError({
throwingAction: (wrapError) => {
const validatorStub = new NodeDataValidatorStub();
const validatorStub = new ExecutableValidatorStub();
validatorStub.createContextualErrorMessage = (message) => message;
const factoryMock: CategoryFactory = () => {
throw expectedError;
@@ -328,9 +327,9 @@ describe('CategoryParser', () => {
expect(actualParsedScripts.length).to.equal(expectedScripts.length);
expect(actualParsedScripts).to.have.members(expectedScripts);
});
it('parses all scripts with correct context', () => {
it('parses all scripts with correct utilities', () => {
// arrange
const expectedParseContext = new CategoryCollectionParseContextStub();
const expected = new CategoryCollectionSpecificUtilitiesStub();
const scriptParser = new ScriptParserStub();
const childrenData = [
createScriptDataWithCode(),
@@ -343,24 +342,24 @@ describe('CategoryParser', () => {
// act
const actualCategory = new TestBuilder()
.withData(categoryData)
.withContext(expectedParseContext)
.withCollectionUtilities(expected)
.withScriptParser(scriptParser.get())
.withCategoryFactory(categoryFactorySpy)
.parseCategory();
// assert
const actualParsedScripts = getInitParameters(actualCategory)?.scripts;
expectExists(actualParsedScripts);
const actualParseContexts = actualParsedScripts.map(
const actualUtilities = actualParsedScripts.map(
(s) => scriptParser.getParseParameters(s)[1],
);
expect(
actualParseContexts.every(
(actualParseContext) => actualParseContext === expectedParseContext,
actualUtilities.every(
(actual) => actual === expected,
),
formatAssertionMessage([
`Expected all elements to be ${JSON.stringify(expectedParseContext)}`,
`Expected all elements to be ${JSON.stringify(expected)}`,
'All elements:',
indentText(JSON.stringify(actualParseContexts)),
indentText(JSON.stringify(actualUtilities)),
]),
).to.equal(true);
});
@@ -397,13 +396,14 @@ describe('CategoryParser', () => {
class TestBuilder {
private data: CategoryData = new CategoryDataStub();
private context: ICategoryCollectionParseContext = new CategoryCollectionParseContextStub();
private collectionUtilities:
CategoryCollectionSpecificUtilitiesStub = new CategoryCollectionSpecificUtilitiesStub();
private categoryFactory: CategoryFactory = () => new CategoryStub(33);
private errorWrapper: ErrorWithContextWrapper = new ErrorWrapperStub().get();
private validatorFactory: NodeDataValidatorFactory = createNodeDataValidatorFactoryStub;
private validatorFactory: ExecutableValidatorFactory = createExecutableValidatorFactoryStub;
private docsParser: DocsParser = () => ['docs'];
@@ -414,8 +414,10 @@ class TestBuilder {
return this;
}
public withContext(context: ICategoryCollectionParseContext): this {
this.context = context;
public withCollectionUtilities(
collectionUtilities: CategoryCollectionSpecificUtilitiesStub,
): this {
this.collectionUtilities = collectionUtilities;
return this;
}
@@ -424,7 +426,7 @@ class TestBuilder {
return this;
}
public withValidatorFactory(validatorFactory: NodeDataValidatorFactory): this {
public withValidatorFactory(validatorFactory: ExecutableValidatorFactory): this {
this.validatorFactory = validatorFactory;
return this;
}
@@ -447,7 +449,7 @@ class TestBuilder {
public parseCategory() {
return parseCategory(
this.data,
this.context,
this.collectionUtilities,
{
createCategory: this.categoryFactory,
wrapError: this.errorWrapper,

View File

@@ -1,6 +1,6 @@
import { describe, it, expect } from 'vitest';
import type { DocumentableData } from '@/application/collections/';
import { parseDocs } from '@/application/Parser/DocumentationParser';
import { parseDocs } from '@/application/Parser/Executable/DocumentationParser';
import { itEachAbsentStringValue } from '@tests/unit/shared/TestCases/AbsentTests';
describe('DocumentationParser', () => {
@@ -9,9 +9,9 @@ describe('DocumentationParser', () => {
itEachAbsentStringValue((absentValue) => {
// arrange
const expectedError = 'missing documentation';
const node: DocumentableData = { docs: ['non empty doc 1', absentValue] };
const data: DocumentableData = { docs: ['non empty doc 1', absentValue] };
// act
const act = () => parseDocs(node);
const act = () => parseDocs(data);
// assert
expect(act).to.throw(expectedError);
}, { excludeNull: true, excludeUndefined: true });
@@ -20,20 +20,23 @@ describe('DocumentationParser', () => {
// arrange
const expectedTypeError = 'docs field (documentation) must be an array of strings';
const wrongTypedValue = 22 as never;
const testCases: ReadonlyArray<{ name: string, node: DocumentableData }> = [
const testCases: ReadonlyArray<{
readonly name: string;
readonly data: DocumentableData;
}> = [
{
name: 'given docs',
node: { docs: wrongTypedValue },
data: { docs: wrongTypedValue },
},
{
name: 'single doc',
node: { docs: ['non empty doc 1', wrongTypedValue] },
data: { docs: ['non empty doc 1', wrongTypedValue] },
},
];
for (const testCase of testCases) {
it(testCase.name, () => {
// act
const act = () => parseDocs(testCase.node);
const act = () => parseDocs(testCase.data);
// assert
expect(act).to.throw(expectedTypeError);
});

View File

@@ -1,16 +1,16 @@
import { describe, it, expect } from 'vitest';
import { ExpressionPosition } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionPosition';
import { type ExpressionEvaluator, Expression } from '@/application/Parser/Script/Compiler/Expressions/Expression/Expression';
import type { IReadOnlyFunctionCallArgumentCollection } from '@/application/Parser/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
import { ExpressionPosition } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/ExpressionPosition';
import { type ExpressionEvaluator, Expression } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/Expression';
import type { IReadOnlyFunctionCallArgumentCollection } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
import { FunctionCallArgumentCollectionStub } from '@tests/unit/shared/Stubs/FunctionCallArgumentCollectionStub';
import { FunctionParameterCollectionStub } from '@tests/unit/shared/Stubs/FunctionParameterCollectionStub';
import { FunctionCallArgumentStub } from '@tests/unit/shared/Stubs/FunctionCallArgumentStub';
import { ExpressionEvaluationContextStub } from '@tests/unit/shared/Stubs/ExpressionEvaluationContextStub';
import type { IPipelineCompiler } from '@/application/Parser/Script/Compiler/Expressions/Pipes/IPipelineCompiler';
import type { IPipelineCompiler } from '@/application/Parser/Executable/Script/Compiler/Expressions/Pipes/IPipelineCompiler';
import { PipelineCompilerStub } from '@tests/unit/shared/Stubs/PipelineCompilerStub';
import type { IReadOnlyFunctionParameterCollection } from '@/application/Parser/Script/Compiler/Function/Parameter/IFunctionParameterCollection';
import type { IReadOnlyFunctionParameterCollection } from '@/application/Parser/Executable/Script/Compiler/Function/Parameter/IFunctionParameterCollection';
import { itEachAbsentObjectValue } from '@tests/unit/shared/TestCases/AbsentTests';
import type { IExpressionEvaluationContext } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionEvaluationContext';
import type { IExpressionEvaluationContext } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/ExpressionEvaluationContext';
import { expectExists } from '@tests/shared/Assertions/ExpectExists';
import { formatAssertionMessage } from '@tests/shared/FormatAssertionMessage';

View File

@@ -1,7 +1,7 @@
import { describe, it, expect } from 'vitest';
import { ExpressionEvaluationContext, type IExpressionEvaluationContext } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionEvaluationContext';
import type { IReadOnlyFunctionCallArgumentCollection } from '@/application/Parser/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
import type { IPipelineCompiler } from '@/application/Parser/Script/Compiler/Expressions/Pipes/IPipelineCompiler';
import { ExpressionEvaluationContext, type IExpressionEvaluationContext } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/ExpressionEvaluationContext';
import type { IReadOnlyFunctionCallArgumentCollection } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
import type { IPipelineCompiler } from '@/application/Parser/Executable/Script/Compiler/Expressions/Pipes/IPipelineCompiler';
import { FunctionCallArgumentCollectionStub } from '@tests/unit/shared/Stubs/FunctionCallArgumentCollectionStub';
import { PipelineCompilerStub } from '@tests/unit/shared/Stubs/PipelineCompilerStub';

View File

@@ -1,5 +1,5 @@
import { describe, it, expect } from 'vitest';
import { ExpressionPosition } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionPosition';
import { ExpressionPosition } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/ExpressionPosition';
describe('ExpressionPosition', () => {
describe('ctor', () => {

View File

@@ -1,6 +1,6 @@
import { describe, it, expect } from 'vitest';
import { createPositionFromRegexFullMatch } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionPositionFactory';
import { ExpressionPosition } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionPosition';
import { createPositionFromRegexFullMatch } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/ExpressionPositionFactory';
import { ExpressionPosition } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/ExpressionPosition';
import { itIsTransientFactory } from '@tests/unit/shared/TestCases/TransientFactoryTests';
describe('ExpressionPositionFactory', () => {

View File

@@ -1,11 +1,11 @@
import { describe, it, expect } from 'vitest';
import { ExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/ExpressionsCompiler';
import type { IExpressionParser } from '@/application/Parser/Script/Compiler/Expressions/Parser/IExpressionParser';
import { ExpressionsCompiler } from '@/application/Parser/Executable/Script/Compiler/Expressions/ExpressionsCompiler';
import type { IExpressionParser } from '@/application/Parser/Executable/Script/Compiler/Expressions/Parser/IExpressionParser';
import { ExpressionStub } from '@tests/unit/shared/Stubs/ExpressionStub';
import { ExpressionParserStub } from '@tests/unit/shared/Stubs/ExpressionParserStub';
import { FunctionCallArgumentCollectionStub } from '@tests/unit/shared/Stubs/FunctionCallArgumentCollectionStub';
import { itEachAbsentStringValue } from '@tests/unit/shared/TestCases/AbsentTests';
import type { IExpression } from '@/application/Parser/Script/Compiler/Expressions/Expression/IExpression';
import type { IExpression } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/IExpression';
describe('ExpressionsCompiler', () => {
describe('compileExpressions', () => {

View File

@@ -1,7 +1,7 @@
import { describe, it, expect } from 'vitest';
import type { IExpression } from '@/application/Parser/Script/Compiler/Expressions/Expression/IExpression';
import type { IExpressionParser } from '@/application/Parser/Script/Compiler/Expressions/Parser/IExpressionParser';
import { CompositeExpressionParser } from '@/application/Parser/Script/Compiler/Expressions/Parser/CompositeExpressionParser';
import type { IExpression } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/IExpression';
import type { IExpressionParser } from '@/application/Parser/Executable/Script/Compiler/Expressions/Parser/IExpressionParser';
import { CompositeExpressionParser } from '@/application/Parser/Executable/Script/Compiler/Expressions/Parser/CompositeExpressionParser';
import { ExpressionStub } from '@tests/unit/shared/Stubs/ExpressionStub';
import { itEachAbsentCollectionValue } from '@tests/unit/shared/TestCases/AbsentTests';

View File

@@ -1,5 +1,5 @@
import { describe, it, expect } from 'vitest';
import { ExpressionRegexBuilder } from '@/application/Parser/Script/Compiler/Expressions/Parser/Regex/ExpressionRegexBuilder';
import { ExpressionRegexBuilder } from '@/application/Parser/Executable/Script/Compiler/Expressions/Parser/Regex/ExpressionRegexBuilder';
const AllWhitespaceCharacters = ' \t\n\r\v\f\u00A0';

View File

@@ -1,23 +1,23 @@
import { describe, it, expect } from 'vitest';
import type {
ExpressionEvaluator, ExpressionInitParameters,
} from '@/application/Parser/Script/Compiler/Expressions/Expression/Expression';
} from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/Expression';
import {
type PrimitiveExpression, RegexParser, type ExpressionFactory, type RegexParserUtilities,
} from '@/application/Parser/Script/Compiler/Expressions/Parser/Regex/RegexParser';
import { ExpressionPosition } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionPosition';
} from '@/application/Parser/Executable/Script/Compiler/Expressions/Parser/Regex/RegexParser';
import { ExpressionPosition } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/ExpressionPosition';
import { itEachAbsentStringValue } from '@tests/unit/shared/TestCases/AbsentTests';
import { collectExceptionMessage } from '@tests/unit/shared/ExceptionCollector';
import { itThrowsContextualError } from '@tests/unit/application/Parser/ContextualErrorTester';
import { ExpressionStub } from '@tests/unit/shared/Stubs/ExpressionStub';
import { FunctionParameterCollectionStub } from '@tests/unit/shared/Stubs/FunctionParameterCollectionStub';
import type { IExpression } from '@/application/Parser/Script/Compiler/Expressions/Expression/IExpression';
import type { IExpression } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/IExpression';
import { FunctionParameterStub } from '@tests/unit/shared/Stubs/FunctionParameterStub';
import type { IReadOnlyFunctionParameterCollection } from '@/application/Parser/Script/Compiler/Function/Parameter/IFunctionParameterCollection';
import type { ExpressionPositionFactory } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionPositionFactory';
import type { IReadOnlyFunctionParameterCollection } from '@/application/Parser/Executable/Script/Compiler/Function/Parameter/IFunctionParameterCollection';
import type { ExpressionPositionFactory } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/ExpressionPositionFactory';
import { formatAssertionMessage } from '@tests/shared/FormatAssertionMessage';
import { indentText } from '@tests/shared/Text';
import type { FunctionParameterCollectionFactory } from '@/application/Parser/Script/Compiler/Function/Parameter/FunctionParameterCollectionFactory';
import type { FunctionParameterCollectionFactory } from '@/application/Parser/Executable/Script/Compiler/Function/Parameter/FunctionParameterCollectionFactory';
describe('RegexParser', () => {
describe('findExpressions', () => {

View File

@@ -1,5 +1,5 @@
import { describe } from 'vitest';
import { EscapeDoubleQuotes } from '@/application/Parser/Script/Compiler/Expressions/Pipes/PipeDefinitions/EscapeDoubleQuotes';
import { EscapeDoubleQuotes } from '@/application/Parser/Executable/Script/Compiler/Expressions/Pipes/PipeDefinitions/EscapeDoubleQuotes';
import { getAbsentStringTestCases } from '@tests/unit/shared/TestCases/AbsentTests';
import { runPipeTests } from './PipeTestRunner';

View File

@@ -1,5 +1,5 @@
import { describe } from 'vitest';
import { InlinePowerShell } from '@/application/Parser/Script/Compiler/Expressions/Pipes/PipeDefinitions/InlinePowerShell';
import { InlinePowerShell } from '@/application/Parser/Executable/Script/Compiler/Expressions/Pipes/PipeDefinitions/InlinePowerShell';
import { getAbsentStringTestCases } from '@tests/unit/shared/TestCases/AbsentTests';
import { type IPipeTestCase, runPipeTests } from './PipeTestRunner';

View File

@@ -1,5 +1,5 @@
import { it, expect } from 'vitest';
import type { IPipe } from '@/application/Parser/Script/Compiler/Expressions/Pipes/IPipe';
import type { IPipe } from '@/application/Parser/Executable/Script/Compiler/Expressions/Pipes/IPipe';
export interface IPipeTestCase {
readonly name: string;

View File

@@ -1,5 +1,5 @@
import { describe, it, expect } from 'vitest';
import { PipeFactory } from '@/application/Parser/Script/Compiler/Expressions/Pipes/PipeFactory';
import { PipeFactory } from '@/application/Parser/Executable/Script/Compiler/Expressions/Pipes/PipeFactory';
import { PipeStub } from '@tests/unit/shared/Stubs/PipeStub';
import { getAbsentStringTestCases } from '@tests/unit/shared/TestCases/AbsentTests';

View File

@@ -1,7 +1,7 @@
import { describe, it, expect } from 'vitest';
import { PipelineCompiler } from '@/application/Parser/Script/Compiler/Expressions/Pipes/PipelineCompiler';
import { type IPipelineCompiler } from '@/application/Parser/Script/Compiler/Expressions/Pipes/IPipelineCompiler';
import type { IPipeFactory } from '@/application/Parser/Script/Compiler/Expressions/Pipes/PipeFactory';
import { PipelineCompiler } from '@/application/Parser/Executable/Script/Compiler/Expressions/Pipes/PipelineCompiler';
import { type IPipelineCompiler } from '@/application/Parser/Executable/Script/Compiler/Expressions/Pipes/IPipelineCompiler';
import type { IPipeFactory } from '@/application/Parser/Executable/Script/Compiler/Expressions/Pipes/PipeFactory';
import { PipeStub } from '@tests/unit/shared/Stubs/PipeStub';
import { PipeFactoryStub } from '@tests/unit/shared/Stubs/PipeFactoryStub';
import { getAbsentStringTestCases } from '@tests/unit/shared/TestCases/AbsentTests';

View File

@@ -1,6 +1,6 @@
import { describe } from 'vitest';
import { ParameterSubstitutionParser } from '@/application/Parser/Script/Compiler/Expressions/SyntaxParsers/ParameterSubstitutionParser';
import { ExpressionPosition } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionPosition';
import { ParameterSubstitutionParser } from '@/application/Parser/Executable/Script/Compiler/Expressions/SyntaxParsers/ParameterSubstitutionParser';
import { ExpressionPosition } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/ExpressionPosition';
import { SyntaxParserTestsRunner } from './SyntaxParserTestsRunner';
describe('ParameterSubstitutionParser', () => {

View File

@@ -1,6 +1,6 @@
import { it, expect } from 'vitest';
import { ExpressionPosition } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionPosition';
import type { IExpressionParser } from '@/application/Parser/Script/Compiler/Expressions/Parser/IExpressionParser';
import { ExpressionPosition } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/ExpressionPosition';
import type { IExpressionParser } from '@/application/Parser/Executable/Script/Compiler/Expressions/Parser/IExpressionParser';
import { FunctionCallArgumentCollectionStub } from '@tests/unit/shared/Stubs/FunctionCallArgumentCollectionStub';
import { ExpressionEvaluationContextStub } from '@tests/unit/shared/Stubs/ExpressionEvaluationContextStub';
import { PipelineCompilerStub } from '@tests/unit/shared/Stubs/PipelineCompilerStub';

View File

@@ -1,6 +1,6 @@
import { describe } from 'vitest';
import { ExpressionPosition } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionPosition';
import { WithParser } from '@/application/Parser/Script/Compiler/Expressions/SyntaxParsers/WithParser';
import { ExpressionPosition } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/ExpressionPosition';
import { WithParser } from '@/application/Parser/Executable/Script/Compiler/Expressions/SyntaxParsers/WithParser';
import { getAbsentStringTestCases } from '@tests/unit/shared/TestCases/AbsentTests';
import { SyntaxParserTestsRunner } from './SyntaxParserTestsRunner';

View File

@@ -1,5 +1,5 @@
import { describe, expect } from 'vitest';
import { FunctionCallArgument } from '@/application/Parser/Script/Compiler/Function/Call/Argument/FunctionCallArgument';
import { FunctionCallArgument } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Argument/FunctionCallArgument';
import { itEachAbsentStringValue } from '@tests/unit/shared/TestCases/AbsentTests';
import { testParameterName } from '../../../ParameterNameTestRunner';

View File

@@ -1,8 +1,8 @@
import { describe, it, expect } from 'vitest';
import { FunctionCallArgumentCollection } from '@/application/Parser/Script/Compiler/Function/Call/Argument/FunctionCallArgumentCollection';
import { FunctionCallArgumentCollection } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Argument/FunctionCallArgumentCollection';
import { FunctionCallArgumentStub } from '@tests/unit/shared/Stubs/FunctionCallArgumentStub';
import { itEachAbsentStringValue } from '@tests/unit/shared/TestCases/AbsentTests';
import type { IFunctionCallArgument } from '@/application/Parser/Script/Compiler/Function/Call/Argument/IFunctionCallArgument';
import type { IFunctionCallArgument } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Argument/IFunctionCallArgument';
describe('FunctionCallArgumentCollection', () => {
describe('addArgument', () => {

View File

@@ -1,8 +1,8 @@
import { expect, describe, it } from 'vitest';
import { NewlineCodeSegmentMerger } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/CodeSegmentJoin/NewlineCodeSegmentMerger';
import { NewlineCodeSegmentMerger } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/CodeSegmentJoin/NewlineCodeSegmentMerger';
import { CompiledCodeStub } from '@tests/unit/shared/Stubs/CompiledCodeStub';
import { getAbsentStringTestCases, itEachAbsentCollectionValue } from '@tests/unit/shared/TestCases/AbsentTests';
import type { CompiledCode } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/CompiledCode';
import type { CompiledCode } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/CompiledCode';
describe('NewlineCodeSegmentMerger', () => {
describe('mergeCodeParts', () => {

View File

@@ -1,18 +1,18 @@
/* eslint-disable max-classes-per-file */
import { describe, it, expect } from 'vitest';
import { FunctionCallSequenceCompiler } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/FunctionCallSequenceCompiler';
import { FunctionCallSequenceCompiler } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/FunctionCallSequenceCompiler';
import { itIsSingletonFactory } from '@tests/unit/shared/TestCases/SingletonFactoryTests';
import { itEachAbsentCollectionValue } from '@tests/unit/shared/TestCases/AbsentTests';
import type { SingleCallCompiler } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/SingleCall/SingleCallCompiler';
import type { CodeSegmentMerger } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/CodeSegmentJoin/CodeSegmentMerger';
import type { ISharedFunctionCollection } from '@/application/Parser/Script/Compiler/Function/ISharedFunctionCollection';
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import type { SingleCallCompiler } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/SingleCall/SingleCallCompiler';
import type { CodeSegmentMerger } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/CodeSegmentJoin/CodeSegmentMerger';
import type { ISharedFunctionCollection } from '@/application/Parser/Executable/Script/Compiler/Function/ISharedFunctionCollection';
import type { FunctionCall } from '@/application/Parser/Executable/Script/Compiler/Function/Call/FunctionCall';
import { FunctionCallStub } from '@tests/unit/shared/Stubs/FunctionCallStub';
import { SharedFunctionCollectionStub } from '@tests/unit/shared/Stubs/SharedFunctionCollectionStub';
import { SingleCallCompilerStub } from '@tests/unit/shared/Stubs/SingleCallCompilerStub';
import { CodeSegmentMergerStub } from '@tests/unit/shared/Stubs/CodeSegmentMergerStub';
import { CompiledCodeStub } from '@tests/unit/shared/Stubs/CompiledCodeStub';
import type { CompiledCode } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/CompiledCode';
import type { CompiledCode } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/CompiledCode';
import { expectExists } from '@tests/shared/Assertions/ExpectExists';
describe('FunctionCallSequenceCompiler', () => {

View File

@@ -1,14 +1,14 @@
import { expect, describe, it } from 'vitest';
import { createSharedFunctionStubWithCalls, createSharedFunctionStubWithCode } from '@tests/unit/shared/Stubs/SharedFunctionStub';
import { NestedFunctionCallCompiler } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/SingleCall/Strategies/NestedFunctionCallCompiler';
import type { ArgumentCompiler } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/SingleCall/Strategies/Argument/ArgumentCompiler';
import { NestedFunctionCallCompiler } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/SingleCall/Strategies/NestedFunctionCallCompiler';
import type { ArgumentCompiler } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/SingleCall/Strategies/Argument/ArgumentCompiler';
import { ArgumentCompilerStub } from '@tests/unit/shared/Stubs/ArgumentCompilerStub';
import { FunctionCallStub } from '@tests/unit/shared/Stubs/FunctionCallStub';
import { FunctionCallCompilationContextStub } from '@tests/unit/shared/Stubs/FunctionCallCompilationContextStub';
import { SingleCallCompilerStub } from '@tests/unit/shared/Stubs/SingleCallCompilerStub';
import { CompiledCodeStub } from '@tests/unit/shared/Stubs/CompiledCodeStub';
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import type { CompiledCode } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/CompiledCode';
import type { FunctionCall } from '@/application/Parser/Executable/Script/Compiler/Function/Call/FunctionCall';
import type { CompiledCode } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/CompiledCode';
import { itThrowsContextualError } from '@tests/unit/application/Parser/ContextualErrorTester';
import type { ErrorWithContextWrapper } from '@/application/Parser/ContextualError';
import { errorWithContextWrapperStub } from '@tests/unit/shared/Stubs/ErrorWithContextWrapperStub';

View File

@@ -3,14 +3,14 @@ import { createSharedFunctionStubWithCode } from '@tests/unit/shared/Stubs/Share
import type { FunctionCallParametersData } from '@/application/collections/';
import { FunctionCallStub } from '@tests/unit/shared/Stubs/FunctionCallStub';
import { SharedFunctionCollectionStub } from '@tests/unit/shared/Stubs/SharedFunctionCollectionStub';
import { AdaptiveFunctionCallCompiler } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/SingleCall/AdaptiveFunctionCallCompiler';
import type { SingleCallCompilerStrategy } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/SingleCall/SingleCallCompilerStrategy';
import { AdaptiveFunctionCallCompiler } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/SingleCall/AdaptiveFunctionCallCompiler';
import type { SingleCallCompilerStrategy } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/SingleCall/SingleCallCompilerStrategy';
import { SingleCallCompilerStrategyStub } from '@tests/unit/shared/Stubs/SingleCallCompilerStrategyStub';
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import type { FunctionCallCompilationContext } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
import type { FunctionCall } from '@/application/Parser/Executable/Script/Compiler/Function/Call/FunctionCall';
import type { FunctionCallCompilationContext } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
import { FunctionCallCompilationContextStub } from '@tests/unit/shared/Stubs/FunctionCallCompilationContextStub';
import { CompiledCodeStub } from '@tests/unit/shared/Stubs/CompiledCodeStub';
import type { SingleCallCompiler } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/SingleCall/SingleCallCompiler';
import type { SingleCallCompiler } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/SingleCall/SingleCallCompiler';
import { collectExceptionMessage } from '@tests/unit/shared/ExceptionCollector';
describe('AdaptiveFunctionCallCompiler', () => {

View File

@@ -1,9 +1,9 @@
import { expect, describe, it } from 'vitest';
import type { ArgumentCompiler } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/SingleCall/Strategies/Argument/ArgumentCompiler';
import type { FunctionCallCompilationContext } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import { NestedFunctionArgumentCompiler } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/SingleCall/Strategies/Argument/NestedFunctionArgumentCompiler';
import type { IExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/IExpressionsCompiler';
import type { ArgumentCompiler } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/SingleCall/Strategies/Argument/ArgumentCompiler';
import type { FunctionCallCompilationContext } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
import type { FunctionCall } from '@/application/Parser/Executable/Script/Compiler/Function/Call/FunctionCall';
import { NestedFunctionArgumentCompiler } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/SingleCall/Strategies/Argument/NestedFunctionArgumentCompiler';
import type { IExpressionsCompiler } from '@/application/Parser/Executable/Script/Compiler/Expressions/IExpressionsCompiler';
import { ExpressionsCompilerStub } from '@tests/unit/shared/Stubs/ExpressionsCompilerStub';
import { FunctionCallCompilationContextStub } from '@tests/unit/shared/Stubs/FunctionCallCompilationContextStub';
import { FunctionCallStub } from '@tests/unit/shared/Stubs/FunctionCallStub';

View File

@@ -1,8 +1,8 @@
import { expect, describe, it } from 'vitest';
import { InlineFunctionCallCompiler } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/SingleCall/Strategies/InlineFunctionCallCompiler';
import { InlineFunctionCallCompiler } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/SingleCall/Strategies/InlineFunctionCallCompiler';
import { createSharedFunctionStubWithCode, createSharedFunctionStubWithCalls } from '@tests/unit/shared/Stubs/SharedFunctionStub';
import { ExpressionsCompilerStub } from '@tests/unit/shared/Stubs/ExpressionsCompilerStub';
import type { IExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/IExpressionsCompiler';
import type { IExpressionsCompiler } from '@/application/Parser/Executable/Script/Compiler/Expressions/IExpressionsCompiler';
import { FunctionCallStub } from '@tests/unit/shared/Stubs/FunctionCallStub';
import { FunctionCallArgumentCollectionStub } from '@tests/unit/shared/Stubs/FunctionCallArgumentCollectionStub';

View File

@@ -1,5 +1,5 @@
import { describe, it, expect } from 'vitest';
import { parseFunctionCalls } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCallParser';
import { parseFunctionCalls } from '@/application/Parser/Executable/Script/Compiler/Function/Call/FunctionCallParser';
import { FunctionCallDataStub } from '@tests/unit/shared/Stubs/FunctionCallDataStub';
import { itEachAbsentStringValue } from '@tests/unit/shared/TestCases/AbsentTests';

View File

@@ -1,6 +1,6 @@
import { describe, it, expect } from 'vitest';
import { ParsedFunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/ParsedFunctionCall';
import type { IReadOnlyFunctionCallArgumentCollection } from '@/application/Parser/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
import { ParsedFunctionCall } from '@/application/Parser/Executable/Script/Compiler/Function/Call/ParsedFunctionCall';
import type { IReadOnlyFunctionCallArgumentCollection } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
import { FunctionCallArgumentCollectionStub } from '@tests/unit/shared/Stubs/FunctionCallArgumentCollectionStub';
import { itEachAbsentStringValue } from '@tests/unit/shared/TestCases/AbsentTests';

View File

@@ -1,7 +1,7 @@
import type {
CallFunctionBody, CodeFunctionBody, SharedFunctionBody,
} from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
import { FunctionBodyType } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
} from '@/application/Parser/Executable/Script/Compiler/Function/ISharedFunction';
import { FunctionBodyType } from '@/application/Parser/Executable/Script/Compiler/Function/ISharedFunction';
import { formatAssertionMessage } from '@tests/shared/FormatAssertionMessage';
export function expectCodeFunctionBody(

View File

@@ -1,5 +1,5 @@
import { describe, it, expect } from 'vitest';
import { FunctionParameter } from '@/application/Parser/Script/Compiler/Function/Parameter/FunctionParameter';
import { FunctionParameter } from '@/application/Parser/Executable/Script/Compiler/Function/Parameter/FunctionParameter';
import { testParameterName } from '../../ParameterNameTestRunner';
describe('FunctionParameter', () => {

View File

@@ -1,5 +1,5 @@
import { describe, it, expect } from 'vitest';
import { FunctionParameterCollection } from '@/application/Parser/Script/Compiler/Function/Parameter/FunctionParameterCollection';
import { FunctionParameterCollection } from '@/application/Parser/Executable/Script/Compiler/Function/Parameter/FunctionParameterCollection';
import { FunctionParameterStub } from '@tests/unit/shared/Stubs/FunctionParameterStub';
describe('FunctionParameterCollection', () => {

View File

@@ -1,6 +1,6 @@
import { describe, it, expect } from 'vitest';
import { FunctionParameterCollection } from '@/application/Parser/Script/Compiler/Function/Parameter/FunctionParameterCollection';
import { createFunctionParameterCollection } from '@/application/Parser/Script/Compiler/Function/Parameter/FunctionParameterCollectionFactory';
import { FunctionParameterCollection } from '@/application/Parser/Executable/Script/Compiler/Function/Parameter/FunctionParameterCollection';
import { createFunctionParameterCollection } from '@/application/Parser/Executable/Script/Compiler/Function/Parameter/FunctionParameterCollectionFactory';
import { itIsTransientFactory } from '@tests/unit/shared/TestCases/TransientFactoryTests';
describe('FunctionParameterCollectionFactory', () => {

View File

@@ -1,10 +1,10 @@
import { describe, it, expect } from 'vitest';
import type { IReadOnlyFunctionParameterCollection } from '@/application/Parser/Script/Compiler/Function/Parameter/IFunctionParameterCollection';
import type { IReadOnlyFunctionParameterCollection } from '@/application/Parser/Executable/Script/Compiler/Function/Parameter/IFunctionParameterCollection';
import { FunctionParameterCollectionStub } from '@tests/unit/shared/Stubs/FunctionParameterCollectionStub';
import { createCallerFunction, createFunctionWithInlineCode } from '@/application/Parser/Script/Compiler/Function/SharedFunction';
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import { createCallerFunction, createFunctionWithInlineCode } from '@/application/Parser/Executable/Script/Compiler/Function/SharedFunction';
import type { FunctionCall } from '@/application/Parser/Executable/Script/Compiler/Function/Call/FunctionCall';
import { FunctionCallStub } from '@tests/unit/shared/Stubs/FunctionCallStub';
import { type CallFunctionBody, FunctionBodyType, type ISharedFunction } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
import { type CallFunctionBody, FunctionBodyType, type ISharedFunction } from '@/application/Parser/Executable/Script/Compiler/Function/ISharedFunction';
import {
getAbsentStringTestCases, itEachAbsentCollectionValue,
itEachAbsentStringValue,

View File

@@ -1,5 +1,5 @@
import { describe, it, expect } from 'vitest';
import { SharedFunctionCollection } from '@/application/Parser/Script/Compiler/Function/SharedFunctionCollection';
import { SharedFunctionCollection } from '@/application/Parser/Executable/Script/Compiler/Function/SharedFunctionCollection';
import { createSharedFunctionStubWithCode, createSharedFunctionStubWithCalls } from '@tests/unit/shared/Stubs/SharedFunctionStub';
import { FunctionCallStub } from '@tests/unit/shared/Stubs/FunctionCallStub';
import { itEachAbsentStringValue } from '@tests/unit/shared/TestCases/AbsentTests';

View File

@@ -1,23 +1,23 @@
import { describe, it, expect } from 'vitest';
import type { FunctionData, CodeInstruction } from '@/application/collections/';
import type { ISharedFunction } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
import { SharedFunctionsParser, type FunctionParameterFactory } from '@/application/Parser/Script/Compiler/Function/SharedFunctionsParser';
import type { ISharedFunction } from '@/application/Parser/Executable/Script/Compiler/Function/ISharedFunction';
import { SharedFunctionsParser, type FunctionParameterFactory } from '@/application/Parser/Executable/Script/Compiler/Function/SharedFunctionsParser';
import { createFunctionDataWithCode, createFunctionDataWithoutCallOrCode } from '@tests/unit/shared/Stubs/FunctionDataStub';
import { ParameterDefinitionDataStub } from '@tests/unit/shared/Stubs/ParameterDefinitionDataStub';
import { FunctionCallDataStub } from '@tests/unit/shared/Stubs/FunctionCallDataStub';
import { itEachAbsentCollectionValue } from '@tests/unit/shared/TestCases/AbsentTests';
import type { ILanguageSyntax } from '@/application/Parser/Script/Validation/Syntax/ILanguageSyntax';
import type { ILanguageSyntax } from '@/application/Parser/Executable/Script/Validation/Syntax/ILanguageSyntax';
import { LanguageSyntaxStub } from '@tests/unit/shared/Stubs/LanguageSyntaxStub';
import { itIsSingletonFactory } from '@tests/unit/shared/TestCases/SingletonFactoryTests';
import { CodeValidatorStub } from '@tests/unit/shared/Stubs/CodeValidatorStub';
import type { ICodeValidator } from '@/application/Parser/Script/Validation/ICodeValidator';
import { NoEmptyLines } from '@/application/Parser/Script/Validation/Rules/NoEmptyLines';
import { NoDuplicatedLines } from '@/application/Parser/Script/Validation/Rules/NoDuplicatedLines';
import type { ICodeValidator } from '@/application/Parser/Executable/Script/Validation/ICodeValidator';
import { NoEmptyLines } from '@/application/Parser/Executable/Script/Validation/Rules/NoEmptyLines';
import { NoDuplicatedLines } from '@/application/Parser/Executable/Script/Validation/Rules/NoDuplicatedLines';
import type { ErrorWithContextWrapper } from '@/application/Parser/ContextualError';
import { FunctionParameterStub } from '@tests/unit/shared/Stubs/FunctionParameterStub';
import { errorWithContextWrapperStub } from '@tests/unit/shared/Stubs/ErrorWithContextWrapperStub';
import { itThrowsContextualError } from '@tests/unit/application/Parser/ContextualErrorTester';
import type { FunctionParameterCollectionFactory } from '@/application/Parser/Script/Compiler/Function/Parameter/FunctionParameterCollectionFactory';
import type { FunctionParameterCollectionFactory } from '@/application/Parser/Executable/Script/Compiler/Function/Parameter/FunctionParameterCollectionFactory';
import { FunctionParameterCollectionStub } from '@tests/unit/shared/Stubs/FunctionParameterCollectionStub';
import { expectCallsFunctionBody, expectCodeFunctionBody } from './ExpectFunctionBodyType';

View File

@@ -1,27 +1,27 @@
import { describe, it, expect } from 'vitest';
import type { FunctionData } from '@/application/collections/';
import { ScriptCompiler } from '@/application/Parser/Script/Compiler/ScriptCompiler';
import type { ISharedFunctionsParser } from '@/application/Parser/Script/Compiler/Function/ISharedFunctionsParser';
import type { FunctionCallCompiler } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/FunctionCallCompiler';
import { ScriptCompiler } from '@/application/Parser/Executable/Script/Compiler/ScriptCompiler';
import type { ISharedFunctionsParser } from '@/application/Parser/Executable/Script/Compiler/Function/ISharedFunctionsParser';
import type { FunctionCallCompiler } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/FunctionCallCompiler';
import { LanguageSyntaxStub } from '@tests/unit/shared/Stubs/LanguageSyntaxStub';
import { createFunctionDataWithCode } from '@tests/unit/shared/Stubs/FunctionDataStub';
import { FunctionCallCompilerStub } from '@tests/unit/shared/Stubs/FunctionCallCompilerStub';
import { SharedFunctionsParserStub } from '@tests/unit/shared/Stubs/SharedFunctionsParserStub';
import { SharedFunctionCollectionStub } from '@tests/unit/shared/Stubs/SharedFunctionCollectionStub';
import { parseFunctionCalls } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCallParser';
import { parseFunctionCalls } from '@/application/Parser/Executable/Script/Compiler/Function/Call/FunctionCallParser';
import { FunctionCallDataStub } from '@tests/unit/shared/Stubs/FunctionCallDataStub';
import type { ILanguageSyntax } from '@/application/Parser/Script/Validation/Syntax/ILanguageSyntax';
import type { ICodeValidator } from '@/application/Parser/Script/Validation/ICodeValidator';
import type { ILanguageSyntax } from '@/application/Parser/Executable/Script/Validation/Syntax/ILanguageSyntax';
import type { ICodeValidator } from '@/application/Parser/Executable/Script/Validation/ICodeValidator';
import { CodeValidatorStub } from '@tests/unit/shared/Stubs/CodeValidatorStub';
import { NoEmptyLines } from '@/application/Parser/Script/Validation/Rules/NoEmptyLines';
import { NoEmptyLines } from '@/application/Parser/Executable/Script/Validation/Rules/NoEmptyLines';
import { CompiledCodeStub } from '@tests/unit/shared/Stubs/CompiledCodeStub';
import { createScriptDataWithCall, createScriptDataWithCode } from '@tests/unit/shared/Stubs/ScriptDataStub';
import type { ErrorWithContextWrapper } from '@/application/Parser/ContextualError';
import { errorWithContextWrapperStub } from '@tests/unit/shared/Stubs/ErrorWithContextWrapperStub';
import { ScriptCodeStub } from '@tests/unit/shared/Stubs/ScriptCodeStub';
import type { ScriptCodeFactory } from '@/domain/ScriptCodeFactory';
import type { ScriptCodeFactory } from '@/domain/Executables/Script/Code/ScriptCodeFactory';
import { createScriptCodeFactoryStub } from '@tests/unit/shared/Stubs/ScriptCodeFactoryStub';
import { itThrowsContextualError } from '../../ContextualErrorTester';
import { itThrowsContextualError } from '@tests/unit/application/Parser/ContextualErrorTester';
describe('ScriptCompiler', () => {
describe('canCompile', () => {

View File

@@ -1,36 +1,35 @@
import { describe, it, expect } from 'vitest';
import type { ScriptData } from '@/application/collections/';
import { parseScript, type ScriptFactory } from '@/application/Parser/Script/ScriptParser';
import { type DocsParser } from '@/application/Parser/DocumentationParser';
import { RecommendationLevel } from '@/domain/RecommendationLevel';
import type { ICategoryCollectionParseContext } from '@/application/Parser/Script/ICategoryCollectionParseContext';
import { parseScript, type ScriptFactory } from '@/application/Parser/Executable/Script/ScriptParser';
import { type DocsParser } from '@/application/Parser/Executable/DocumentationParser';
import { RecommendationLevel } from '@/domain/Executables/Script/RecommendationLevel';
import { itEachAbsentStringValue } from '@tests/unit/shared/TestCases/AbsentTests';
import { ScriptCompilerStub } from '@tests/unit/shared/Stubs/ScriptCompilerStub';
import { createScriptDataWithCall, createScriptDataWithCode, createScriptDataWithoutCallOrCodes } from '@tests/unit/shared/Stubs/ScriptDataStub';
import { EnumParserStub } from '@tests/unit/shared/Stubs/EnumParserStub';
import { ScriptCodeStub } from '@tests/unit/shared/Stubs/ScriptCodeStub';
import { CategoryCollectionParseContextStub } from '@tests/unit/shared/Stubs/CategoryCollectionParseContextStub';
import { CategoryCollectionSpecificUtilitiesStub } from '@tests/unit/shared/Stubs/CategoryCollectionSpecificUtilitiesStub';
import { LanguageSyntaxStub } from '@tests/unit/shared/Stubs/LanguageSyntaxStub';
import { Script } from '@/domain/Script';
import type { IEnumParser } from '@/application/Common/Enum';
import { NoEmptyLines } from '@/application/Parser/Script/Validation/Rules/NoEmptyLines';
import { NoDuplicatedLines } from '@/application/Parser/Script/Validation/Rules/NoDuplicatedLines';
import { NoEmptyLines } from '@/application/Parser/Executable/Script/Validation/Rules/NoEmptyLines';
import { NoDuplicatedLines } from '@/application/Parser/Executable/Script/Validation/Rules/NoDuplicatedLines';
import { CodeValidatorStub } from '@tests/unit/shared/Stubs/CodeValidatorStub';
import type { ICodeValidator } from '@/application/Parser/Script/Validation/ICodeValidator';
import type { ICodeValidator } from '@/application/Parser/Executable/Script/Validation/ICodeValidator';
import type { ErrorWithContextWrapper } from '@/application/Parser/ContextualError';
import { ErrorWrapperStub } from '@tests/unit/shared/Stubs/ErrorWrapperStub';
import type { NodeDataValidatorFactory } from '@/application/Parser/NodeValidation/NodeDataValidator';
import { NodeDataValidatorStub, createNodeDataValidatorFactoryStub } from '@tests/unit/shared/Stubs/NodeDataValidatorStub';
import { NodeDataType } from '@/application/Parser/NodeValidation/NodeDataType';
import type { ScriptNodeErrorContext } from '@/application/Parser/NodeValidation/NodeDataErrorContext';
import type { ScriptCodeFactory } from '@/domain/ScriptCodeFactory';
import type { ExecutableValidatorFactory } from '@/application/Parser/Executable/Validation/ExecutableValidator';
import { ExecutableValidatorStub, createExecutableValidatorFactoryStub } from '@tests/unit/shared/Stubs/ExecutableValidatorStub';
import { ExecutableType } from '@/application/Parser/Executable/Validation/ExecutableType';
import type { ScriptErrorContext } from '@/application/Parser/Executable/Validation/ExecutableErrorContext';
import type { ScriptCodeFactory } from '@/domain/Executables/Script/Code/ScriptCodeFactory';
import { createScriptCodeFactoryStub } from '@tests/unit/shared/Stubs/ScriptCodeFactoryStub';
import { ScriptStub } from '@tests/unit/shared/Stubs/ScriptStub';
import { createScriptFactorySpy } from '@tests/unit/shared/Stubs/ScriptFactoryStub';
import { expectExists } from '@tests/shared/Assertions/ExpectExists';
import { itThrowsContextualError } from '../ContextualErrorTester';
import { itAsserts, itValidatesDefinedData, itValidatesName } from '../NodeDataValidationTester';
import { generateDataValidationTestScenarios } from '../DataValidationTestScenarioGenerator';
import { itThrowsContextualError } from '@tests/unit/application/Parser/ContextualErrorTester';
import type { CategoryCollectionSpecificUtilities } from '@/application/Parser/Executable/CategoryCollectionSpecificUtilities';
import { itAsserts, itValidatesDefinedData, itValidatesName } from '../Validation/ExecutableValidationTester';
import { generateDataValidationTestScenarios } from '../Validation/DataValidationTestScenarioGenerator';
describe('ScriptParser', () => {
describe('parseScript', () => {
@@ -176,13 +175,13 @@ describe('ScriptParser', () => {
const script = createScriptDataWithCode();
const compiler = new ScriptCompilerStub()
.withCompileAbility(script, expectedCode);
const parseContext = new CategoryCollectionParseContextStub()
const collectionUtilities = new CategoryCollectionSpecificUtilitiesStub()
.withCompiler(compiler);
const { scriptFactorySpy, getInitParameters } = createScriptFactorySpy();
// act
const actualScript = new TestContext()
.withData(script)
.withContext(parseContext)
.withCollectionUtilities(collectionUtilities)
.withScriptFactory(scriptFactorySpy)
.parseScript();
// assert
@@ -195,14 +194,14 @@ describe('ScriptParser', () => {
// arrange
const commentDelimiter = 'should not throw';
const duplicatedCode = `${commentDelimiter} duplicate-line\n${commentDelimiter} duplicate-line`;
const parseContext = new CategoryCollectionParseContextStub()
const collectionUtilities = new CategoryCollectionSpecificUtilitiesStub()
.withSyntax(new LanguageSyntaxStub().withCommentDelimiters(commentDelimiter));
const script = createScriptDataWithoutCallOrCodes()
.withCode(duplicatedCode);
// act
const act = () => new TestContext()
.withData(script)
.withContext(parseContext);
.withCollectionUtilities(collectionUtilities);
// assert
expect(act).to.not.throw();
});
@@ -245,13 +244,13 @@ describe('ScriptParser', () => {
const script = createScriptDataWithCall();
const compiler = new ScriptCompilerStub()
.withCompileAbility(script, new ScriptCodeStub());
const parseContext = new CategoryCollectionParseContextStub()
const collectionUtilities = new CategoryCollectionSpecificUtilitiesStub()
.withCompiler(compiler);
// act
new TestContext()
.withData(script)
.withCodeValidator(validator)
.withContext(parseContext)
.withCollectionUtilities(collectionUtilities)
.parseScript();
// assert
validator.assertHistory({
@@ -267,9 +266,9 @@ describe('ScriptParser', () => {
const expectedName = 'expected script name to be validated';
const script = createScriptDataWithCall()
.withName(expectedName);
const expectedContext: ScriptNodeErrorContext = {
type: NodeDataType.Script,
selfNode: script,
const expectedContext: ScriptErrorContext = {
type: ExecutableType.Script,
self: script,
};
itValidatesName((validatorFactory) => {
// act
@@ -287,9 +286,9 @@ describe('ScriptParser', () => {
describe('validates for defined data', () => {
// arrange
const expectedScript = createScriptDataWithCall();
const expectedContext: ScriptNodeErrorContext = {
type: NodeDataType.Script,
selfNode: expectedScript,
const expectedContext: ScriptErrorContext = {
type: ExecutableType.Script,
self: expectedScript,
};
itValidatesDefinedData(
(validatorFactory) => {
@@ -374,9 +373,9 @@ describe('ScriptParser', () => {
itAsserts({
expectedConditionResult: expectedPass,
test: (validatorFactory) => {
const expectedContext: ScriptNodeErrorContext = {
type: NodeDataType.Script,
selfNode: scriptData,
const expectedContext: ScriptErrorContext = {
type: ExecutableType.Script,
self: scriptData,
};
// act
new TestContext()
@@ -400,8 +399,8 @@ describe('ScriptParser', () => {
const givenData = createScriptDataWithCode();
const expectedContextMessage = 'Failed to parse script.';
const expectedError = new Error();
const validatorFactory: NodeDataValidatorFactory = () => {
const validatorStub = new NodeDataValidatorStub();
const validatorFactory: ExecutableValidatorFactory = () => {
const validatorStub = new ExecutableValidatorStub();
validatorStub.createContextualErrorMessage = (message) => message;
return validatorStub;
};
@@ -428,7 +427,8 @@ describe('ScriptParser', () => {
class TestContext {
private data: ScriptData = createScriptDataWithCode();
private context: ICategoryCollectionParseContext = new CategoryCollectionParseContextStub();
private collectionUtilities
: CategoryCollectionSpecificUtilities = new CategoryCollectionSpecificUtilitiesStub();
private levelParser: IEnumParser<RecommendationLevel> = new EnumParserStub<RecommendationLevel>()
.setupDefaultValue(RecommendationLevel.Standard);
@@ -439,7 +439,7 @@ class TestContext {
private errorWrapper: ErrorWithContextWrapper = new ErrorWrapperStub().get();
private validatorFactory: NodeDataValidatorFactory = createNodeDataValidatorFactoryStub;
private validatorFactory: ExecutableValidatorFactory = createExecutableValidatorFactoryStub;
private docsParser: DocsParser = () => ['docs'];
@@ -457,8 +457,10 @@ class TestContext {
return this;
}
public withContext(context: ICategoryCollectionParseContext): this {
this.context = context;
public withCollectionUtilities(
collectionUtilities: CategoryCollectionSpecificUtilities,
): this {
this.collectionUtilities = collectionUtilities;
return this;
}
@@ -472,7 +474,7 @@ class TestContext {
return this;
}
public withValidatorFactory(validatorFactory: NodeDataValidatorFactory): this {
public withValidatorFactory(validatorFactory: ExecutableValidatorFactory): this {
this.validatorFactory = validatorFactory;
return this;
}
@@ -492,10 +494,10 @@ class TestContext {
return this;
}
public parseScript(): Script {
public parseScript(): ReturnType<typeof parseScript> {
return parseScript(
this.data,
this.context,
this.collectionUtilities,
{
levelParser: this.levelParser,
createScript: this.scriptFactory,

View File

@@ -1,10 +1,10 @@
import { describe, it, expect } from 'vitest';
import { CodeValidator } from '@/application/Parser/Script/Validation/CodeValidator';
import { CodeValidator } from '@/application/Parser/Executable/Script/Validation/CodeValidator';
import { CodeValidationRuleStub } from '@tests/unit/shared/Stubs/CodeValidationRuleStub';
import { itEachAbsentCollectionValue, itEachAbsentStringValue } from '@tests/unit/shared/TestCases/AbsentTests';
import { itIsSingletonFactory } from '@tests/unit/shared/TestCases/SingletonFactoryTests';
import type { ICodeLine } from '@/application/Parser/Script/Validation/ICodeLine';
import type { ICodeValidationRule, IInvalidCodeLine } from '@/application/Parser/Script/Validation/ICodeValidationRule';
import type { ICodeLine } from '@/application/Parser/Executable/Script/Validation/ICodeLine';
import type { ICodeValidationRule, IInvalidCodeLine } from '@/application/Parser/Executable/Script/Validation/ICodeValidationRule';
describe('CodeValidator', () => {
describe('instance', () => {

View File

@@ -1,6 +1,6 @@
import { it, expect } from 'vitest';
import type { ICodeValidationRule, IInvalidCodeLine } from '@/application/Parser/Script/Validation/ICodeValidationRule';
import type { ICodeLine } from '@/application/Parser/Script/Validation/ICodeLine';
import type { ICodeValidationRule, IInvalidCodeLine } from '@/application/Parser/Executable/Script/Validation/ICodeValidationRule';
import type { ICodeLine } from '@/application/Parser/Executable/Script/Validation/ICodeLine';
interface ICodeValidationRuleTestCase {
testName: string;

View File

@@ -1,7 +1,7 @@
import { describe } from 'vitest';
import { NoDuplicatedLines } from '@/application/Parser/Script/Validation/Rules/NoDuplicatedLines';
import { NoDuplicatedLines } from '@/application/Parser/Executable/Script/Validation/Rules/NoDuplicatedLines';
import { LanguageSyntaxStub } from '@tests/unit/shared/Stubs/LanguageSyntaxStub';
import type { IInvalidCodeLine } from '@/application/Parser/Script/Validation/ICodeValidationRule';
import type { IInvalidCodeLine } from '@/application/Parser/Executable/Script/Validation/ICodeValidationRule';
import { testCodeValidationRule } from './CodeValidationRuleTestRunner';
describe('NoDuplicatedLines', () => {

View File

@@ -1,5 +1,5 @@
import { describe } from 'vitest';
import { NoEmptyLines } from '@/application/Parser/Script/Validation/Rules/NoEmptyLines';
import { NoEmptyLines } from '@/application/Parser/Executable/Script/Validation/Rules/NoEmptyLines';
import { testCodeValidationRule } from './CodeValidationRuleTestRunner';
describe('NoEmptyLines', () => {

View File

@@ -1,7 +1,7 @@
import { describe, it, expect } from 'vitest';
import { ShellScriptSyntax } from '@/application/Parser/Script/Validation/Syntax/ShellScriptSyntax';
import type { ILanguageSyntax } from '@/application/Parser/Script/Validation/Syntax/ILanguageSyntax';
import { BatchFileSyntax } from '@/application/Parser/Script/Validation/Syntax/BatchFileSyntax';
import { ShellScriptSyntax } from '@/application/Parser/Executable/Script/Validation/Syntax/ShellScriptSyntax';
import type { ILanguageSyntax } from '@/application/Parser/Executable/Script/Validation/Syntax/ILanguageSyntax';
import { BatchFileSyntax } from '@/application/Parser/Executable/Script/Validation/Syntax/BatchFileSyntax';
function getSystemsUnderTest(): ILanguageSyntax[] {
return [new BatchFileSyntax(), new ShellScriptSyntax()];

View File

@@ -1,9 +1,9 @@
import { describe } from 'vitest';
import { SyntaxFactory } from '@/application/Parser/Script/Validation/Syntax/SyntaxFactory';
import { SyntaxFactory } from '@/application/Parser/Executable/Script/Validation/Syntax/SyntaxFactory';
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
import { ShellScriptSyntax } from '@/application/Parser/Script/Validation/Syntax/ShellScriptSyntax';
import { ShellScriptSyntax } from '@/application/Parser/Executable/Script/Validation/Syntax/ShellScriptSyntax';
import { ScriptingLanguageFactoryTestRunner } from '@tests/unit/application/Common/ScriptingLanguage/ScriptingLanguageFactoryTestRunner';
import { BatchFileSyntax } from '@/application/Parser/Script/Validation/Syntax/BatchFileSyntax';
import { BatchFileSyntax } from '@/application/Parser/Executable/Script/Validation/Syntax/BatchFileSyntax';
describe('SyntaxFactory', () => {
const sut = new SyntaxFactory();

View File

@@ -1,29 +1,29 @@
import { it } from 'vitest';
import type { NodeDataValidator, NodeDataValidatorFactory } from '@/application/Parser/NodeValidation/NodeDataValidator';
import type { NodeDataErrorContext } from '@/application/Parser/NodeValidation/NodeDataErrorContext';
import { NodeDataValidatorStub } from '@tests/unit/shared/Stubs/NodeDataValidatorStub';
import type { ExecutableValidator, ExecutableValidatorFactory } from '@/application/Parser/Executable/Validation/ExecutableValidator';
import type { ExecutableErrorContext } from '@/application/Parser/Executable/Validation/ExecutableErrorContext';
import { ExecutableValidatorStub } from '@tests/unit/shared/Stubs/ExecutableValidatorStub';
import { expectExists } from '@tests/shared/Assertions/ExpectExists';
import type { CategoryOrScriptData } from '@/application/collections/';
import type { ExecutableData } from '@/application/collections/';
import type { FunctionKeys } from '@/TypeHelpers';
import { formatAssertionMessage } from '@tests/shared/FormatAssertionMessage';
import { indentText } from '@tests/shared/Text';
type NodeValidationTestFunction<TExpectation> = (
factory: NodeDataValidatorFactory,
type ValidationTestFunction<TExpectation> = (
factory: ExecutableValidatorFactory,
) => TExpectation;
interface ValidNameExpectation {
readonly expectedNameToValidate: string;
readonly expectedErrorContext: NodeDataErrorContext;
readonly expectedErrorContext: ExecutableErrorContext;
}
export function itValidatesName(
test: NodeValidationTestFunction<ValidNameExpectation>,
test: ValidationTestFunction<ValidNameExpectation>,
) {
it('validates for name', () => {
// arrange
const validator = new NodeDataValidatorStub();
const factoryStub: NodeDataValidatorFactory = () => validator;
const validator = new ExecutableValidatorStub();
const factoryStub: ExecutableValidatorFactory = () => validator;
// act
test(factoryStub);
// assert
@@ -32,8 +32,8 @@ export function itValidatesName(
});
it('validates for name with correct name', () => {
// arrange
const validator = new NodeDataValidatorStub();
const factoryStub: NodeDataValidatorFactory = () => validator;
const validator = new ExecutableValidatorStub();
const factoryStub: ExecutableValidatorFactory = () => validator;
// act
const expectation = test(factoryStub);
// assert
@@ -53,17 +53,17 @@ export function itValidatesName(
}
interface ValidDataExpectation {
readonly expectedDataToValidate: CategoryOrScriptData;
readonly expectedErrorContext: NodeDataErrorContext;
readonly expectedDataToValidate: ExecutableData;
readonly expectedErrorContext: ExecutableErrorContext;
}
export function itValidatesDefinedData(
test: NodeValidationTestFunction<ValidDataExpectation>,
test: ValidationTestFunction<ValidDataExpectation>,
) {
it('validates data', () => {
// arrange
const validator = new NodeDataValidatorStub();
const factoryStub: NodeDataValidatorFactory = () => validator;
const validator = new ExecutableValidatorStub();
const factoryStub: ExecutableValidatorFactory = () => validator;
// act
test(factoryStub);
// assert
@@ -72,8 +72,8 @@ export function itValidatesDefinedData(
});
it('validates data with correct data', () => {
// arrange
const validator = new NodeDataValidatorStub();
const factoryStub: NodeDataValidatorFactory = () => validator;
const validator = new ExecutableValidatorStub();
const factoryStub: ExecutableValidatorFactory = () => validator;
// act
const expectation = test(factoryStub);
// assert
@@ -93,20 +93,20 @@ export function itValidatesDefinedData(
interface AssertionExpectation {
readonly expectedErrorMessage: string;
readonly expectedErrorContext: NodeDataErrorContext;
readonly expectedErrorContext: ExecutableErrorContext;
}
export function itAsserts(
testScenario: {
readonly test: NodeValidationTestFunction<AssertionExpectation>,
readonly test: ValidationTestFunction<AssertionExpectation>,
readonly expectedConditionResult: boolean;
},
) {
it('asserts with correct message', () => {
// arrange
const validator = new NodeDataValidatorStub()
const validator = new ExecutableValidatorStub()
.withAssertThrowsOnFalseCondition(false);
const factoryStub: NodeDataValidatorFactory = () => validator;
const factoryStub: ExecutableValidatorFactory = () => validator;
// act
const expectation = testScenario.test(factoryStub);
// assert
@@ -116,7 +116,12 @@ export function itAsserts(
const [, message] = call.args;
return message;
});
expect(actualMessages).to.include(expectedError);
expect(actualMessages).to.include(expectedError, formatAssertionMessage([
'Assertion failed: The expected error message was not triggered.',
`Expected: "${expectedError}"`,
'Actual messages (none match expected):',
indentText(actualMessages.map((message) => `- ${message}`).join('\n')),
]));
});
it('asserts with correct context', () => {
expectCorrectContextForFunctionCall({
@@ -128,9 +133,9 @@ export function itAsserts(
it('asserts with correct condition result', () => {
// arrange
const expectedEvaluationResult = testScenario.expectedConditionResult;
const validator = new NodeDataValidatorStub()
const validator = new ExecutableValidatorStub()
.withAssertThrowsOnFalseCondition(false);
const factoryStub: NodeDataValidatorFactory = () => validator;
const factoryStub: ExecutableValidatorFactory = () => validator;
// act
const expectation = testScenario.test(factoryStub);
// assert
@@ -154,18 +159,18 @@ export function itAsserts(
}
function expectCorrectContextForFunctionCall<T>(testScenario: {
methodName: FunctionKeys<NodeDataValidator>,
act: NodeValidationTestFunction<T>,
expectContext: (actionResult: T) => NodeDataErrorContext,
methodName: FunctionKeys<ExecutableValidator>,
act: ValidationTestFunction<T>,
expectContext: (actionResult: T) => ExecutableErrorContext,
}) {
// arrange
const { methodName } = testScenario;
const createdValidators = new Array<{
readonly validator: NodeDataValidatorStub;
readonly context: NodeDataErrorContext;
readonly validator: ExecutableValidatorStub;
readonly context: ExecutableErrorContext;
}>();
const factoryStub: NodeDataValidatorFactory = (context) => {
const validator = new NodeDataValidatorStub()
const factoryStub: ExecutableValidatorFactory = (context) => {
const validator = new ExecutableValidatorStub()
.withAssertThrowsOnFalseCondition(false);
createdValidators.push(({
validator,

View File

@@ -1,25 +1,25 @@
import { describe, it, expect } from 'vitest';
import { CategoryDataStub } from '@tests/unit/shared/Stubs/CategoryDataStub';
import type { NodeData } from '@/application/Parser/NodeValidation/NodeData';
import { createNodeDataErrorContextStub } from '@tests/unit/shared/Stubs/NodeDataErrorContextStub';
import type { NodeDataErrorContext } from '@/application/Parser/NodeValidation/NodeDataErrorContext';
import type { ExecutableData } from '@/application/collections/';
import { createExecutableErrorContextStub } from '@tests/unit/shared/Stubs/ExecutableErrorContextStub';
import type { ExecutableErrorContext } from '@/application/Parser/Executable/Validation/ExecutableErrorContext';
import { collectExceptionMessage } from '@tests/unit/shared/ExceptionCollector';
import { ContextualNodeDataValidator, createNodeDataValidator, type NodeDataValidator } from '@/application/Parser/NodeValidation/NodeDataValidator';
import type { NodeContextErrorMessageCreator } from '@/application/Parser/NodeValidation/NodeDataErrorContextMessage';
import { ContextualExecutableValidator, createExecutableDataValidator, type ExecutableValidator } from '@/application/Parser/Executable/Validation/ExecutableValidator';
import type { ExecutableContextErrorMessageCreator } from '@/application/Parser/Executable/Validation/ExecutableErrorContextMessage';
import { getAbsentObjectTestCases, getAbsentStringTestCases } from '@tests/unit/shared/TestCases/AbsentTests';
describe('createNodeDataValidator', () => {
it(`returns an instance of ${ContextualNodeDataValidator.name}`, () => {
describe('createExecutableDataValidator', () => {
it(`returns an instance of ${ContextualExecutableValidator.name}`, () => {
// arrange
const context = createNodeDataErrorContextStub();
const context = createExecutableErrorContextStub();
// act
const validator = createNodeDataValidator(context);
const validator = createExecutableDataValidator(context);
// assert
expect(validator).to.be.instanceOf(ContextualNodeDataValidator);
expect(validator).to.be.instanceOf(ContextualExecutableValidator);
});
});
describe('NodeDataValidator', () => {
describe('ContextualExecutableValidator', () => {
describe('assertValidName', () => {
describe('throws when name is invalid', () => {
// arrange
@@ -55,7 +55,7 @@ describe('NodeDataValidator', () => {
it('does not throw when name is valid', () => {
// arrange
const validName = 'validName';
const sut = new NodeValidatorBuilder()
const sut = new ValidatorBuilder()
.build();
// act
const act = () => sut.assertValidName(validName);
@@ -64,7 +64,7 @@ describe('NodeDataValidator', () => {
});
});
describe('assertDefined', () => {
describe('throws when node data is missing', () => {
describe('throws when data is missing', () => {
// arrange
const testScenarios: readonly {
readonly description: string;
@@ -81,11 +81,11 @@ describe('NodeDataValidator', () => {
];
testScenarios.forEach(({ description, invalidData }) => {
describe(`given "${description}"`, () => {
const expectedMessage = 'missing node data';
const expectedMessage = 'missing executable data';
itThrowsCorrectly({
// act
throwingAction: (sut: NodeDataValidator) => {
sut.assertDefined(invalidData as NodeData);
throwingAction: (sut: ExecutableValidator) => {
sut.assertDefined(invalidData as ExecutableData);
},
// assert
expectedMessage,
@@ -93,13 +93,13 @@ describe('NodeDataValidator', () => {
});
});
});
it('does not throw if node data is defined', () => {
it('does not throw if data is defined', () => {
// arrange
const definedNode = new CategoryDataStub();
const sut = new NodeValidatorBuilder()
const data = new CategoryDataStub();
const sut = new ValidatorBuilder()
.build();
// act
const act = () => sut.assertDefined(definedNode);
const act = () => sut.assertDefined(data);
// assert
expect(act).to.not.throw();
});
@@ -111,7 +111,7 @@ describe('NodeDataValidator', () => {
// assert
itThrowsCorrectly({
// act
throwingAction: (sut: NodeDataValidator) => {
throwingAction: (sut: ExecutableValidator) => {
sut.assert(falsePredicate, expectedErrorMessage);
},
// assert
@@ -121,7 +121,7 @@ describe('NodeDataValidator', () => {
it('does not throw if validation succeeds', () => {
// arrange
const truePredicate = () => true;
const sut = new NodeValidatorBuilder()
const sut = new ValidatorBuilder()
.build();
// act
const act = () => sut.assert(truePredicate, 'ignored error');
@@ -133,8 +133,8 @@ describe('NodeDataValidator', () => {
it('creates using the correct error message', () => {
// arrange
const expectedErrorMessage = 'expected error';
const errorMessageBuilder: NodeContextErrorMessageCreator = (message) => message;
const sut = new NodeValidatorBuilder()
const errorMessageBuilder: ExecutableContextErrorMessageCreator = (message) => message;
const sut = new ValidatorBuilder()
.withErrorMessageCreator(errorMessageBuilder)
.build();
// act
@@ -144,13 +144,13 @@ describe('NodeDataValidator', () => {
});
it('creates using the correct context', () => {
// arrange
const expectedContext = createNodeDataErrorContextStub();
let actualContext: NodeDataErrorContext | undefined;
const errorMessageBuilder: NodeContextErrorMessageCreator = (_, context) => {
const expectedContext = createExecutableErrorContextStub();
let actualContext: ExecutableErrorContext | undefined;
const errorMessageBuilder: ExecutableContextErrorMessageCreator = (_, context) => {
actualContext = context;
return '';
};
const sut = new NodeValidatorBuilder()
const sut = new ValidatorBuilder()
.withContext(expectedContext)
.withErrorMessageCreator(errorMessageBuilder)
.build();
@@ -163,7 +163,7 @@ describe('NodeDataValidator', () => {
});
type ValidationThrowingFunction = (
sut: ContextualNodeDataValidator,
sut: ContextualExecutableValidator,
) => void;
interface ValidationThrowingTestScenario {
@@ -177,8 +177,8 @@ function itThrowsCorrectly(
it('throws an error', () => {
// arrange
const expectedErrorMessage = 'Injected error message';
const errorMessageBuilder: NodeContextErrorMessageCreator = () => expectedErrorMessage;
const sut = new NodeValidatorBuilder()
const errorMessageBuilder: ExecutableContextErrorMessageCreator = () => expectedErrorMessage;
const sut = new ValidatorBuilder()
.withErrorMessageCreator(errorMessageBuilder)
.build();
// act
@@ -189,8 +189,8 @@ function itThrowsCorrectly(
it('throws with the correct error message', () => {
// arrange
const expectedErrorMessage = testScenario.expectedMessage;
const errorMessageBuilder: NodeContextErrorMessageCreator = (message) => message;
const sut = new NodeValidatorBuilder()
const errorMessageBuilder: ExecutableContextErrorMessageCreator = (message) => message;
const sut = new ValidatorBuilder()
.withErrorMessageCreator(errorMessageBuilder)
.build();
// act
@@ -201,11 +201,11 @@ function itThrowsCorrectly(
});
it('throws with the correct context', () => {
// arrange
const expectedContext = createNodeDataErrorContextStub();
const serializeContext = (context: NodeDataErrorContext) => JSON.stringify(context);
const expectedContext = createExecutableErrorContextStub();
const serializeContext = (context: ExecutableErrorContext) => JSON.stringify(context);
const errorMessageBuilder:
NodeContextErrorMessageCreator = (_, context) => serializeContext(context);
const sut = new NodeValidatorBuilder()
ExecutableContextErrorMessageCreator = (_, context) => serializeContext(context);
const sut = new ValidatorBuilder()
.withContext(expectedContext)
.withErrorMessageCreator(errorMessageBuilder)
.build();
@@ -218,23 +218,23 @@ function itThrowsCorrectly(
});
}
class NodeValidatorBuilder {
private errorContext: NodeDataErrorContext = createNodeDataErrorContextStub();
class ValidatorBuilder {
private errorContext: ExecutableErrorContext = createExecutableErrorContextStub();
private errorMessageCreator: NodeContextErrorMessageCreator = () => `[${NodeValidatorBuilder.name}] stub error message`;
private errorMessageCreator: ExecutableContextErrorMessageCreator = () => `[${ValidatorBuilder.name}] stub error message`;
public withErrorMessageCreator(errorMessageCreator: NodeContextErrorMessageCreator): this {
public withErrorMessageCreator(errorMessageCreator: ExecutableContextErrorMessageCreator): this {
this.errorMessageCreator = errorMessageCreator;
return this;
}
public withContext(errorContext: NodeDataErrorContext): this {
public withContext(errorContext: ExecutableErrorContext): this {
this.errorContext = errorContext;
return this;
}
public build(): ContextualNodeDataValidator {
return new ContextualNodeDataValidator(
public build(): ContextualExecutableValidator {
return new ContextualExecutableValidator(
this.errorContext,
this.errorMessageCreator,
);

View File

@@ -1,71 +0,0 @@
import { describe, it, expect } from 'vitest';
import type { ISyntaxFactory } from '@/application/Parser/Script/Validation/Syntax/ISyntaxFactory';
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
import { CategoryCollectionParseContext } from '@/application/Parser/Script/CategoryCollectionParseContext';
import { ScriptCompiler } from '@/application/Parser/Script/Compiler/ScriptCompiler';
import { LanguageSyntaxStub } from '@tests/unit/shared/Stubs/LanguageSyntaxStub';
import { ScriptingDefinitionStub } from '@tests/unit/shared/Stubs/ScriptingDefinitionStub';
import type { FunctionData } from '@/application/collections/';
import { itEachAbsentCollectionValue } from '@tests/unit/shared/TestCases/AbsentTests';
import type { ILanguageSyntax } from '@/application/Parser/Script/Validation/Syntax/ILanguageSyntax';
import { createFunctionDataWithCode } from '@tests/unit/shared/Stubs/FunctionDataStub';
describe('CategoryCollectionParseContext', () => {
describe('ctor', () => {
describe('functionsData', () => {
describe('can create with absent data', () => {
itEachAbsentCollectionValue<FunctionData>((absentValue) => {
// arrange
const scripting = new ScriptingDefinitionStub();
// act
const act = () => new CategoryCollectionParseContext(absentValue, scripting);
// assert
expect(act).to.not.throw();
}, { excludeNull: true });
});
});
});
describe('compiler', () => {
it('constructed as expected', () => {
// arrange
const functionsData = [createFunctionDataWithCode()];
const syntax = new LanguageSyntaxStub();
const expected = new ScriptCompiler(functionsData, syntax);
const language = ScriptingLanguage.shellscript;
const factoryMock = mockFactory(language, syntax);
const definition = new ScriptingDefinitionStub()
.withLanguage(language);
// act
const sut = new CategoryCollectionParseContext(functionsData, definition, factoryMock);
const actual = sut.compiler;
// assert
expect(actual).to.deep.equal(expected);
});
});
describe('syntax', () => {
it('set from syntax factory', () => {
// arrange
const language = ScriptingLanguage.shellscript;
const expected = new LanguageSyntaxStub();
const factoryMock = mockFactory(language, expected);
const definition = new ScriptingDefinitionStub()
.withLanguage(language);
// act
const sut = new CategoryCollectionParseContext([], definition, factoryMock);
const actual = sut.syntax;
// assert
expect(actual).to.equal(expected);
});
});
});
function mockFactory(expectedLanguage: ScriptingLanguage, result: ILanguageSyntax): ISyntaxFactory {
return {
create: (language: ScriptingLanguage) => {
if (language !== expectedLanguage) {
throw new Error('unexpected language');
}
return result;
},
};
}

View File

@@ -1,6 +1,6 @@
import { describe, it, expect } from 'vitest';
import { CodeSubstituter } from '@/application/Parser/ScriptingDefinition/CodeSubstituter';
import type { IExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/IExpressionsCompiler';
import type { IExpressionsCompiler } from '@/application/Parser/Executable/Script/Compiler/Expressions/IExpressionsCompiler';
import { ProjectDetailsStub } from '@tests/unit/shared/Stubs/ProjectDetailsStub';
import { ExpressionsCompilerStub } from '@tests/unit/shared/Stubs/ExpressionsCompilerStub';
import { itEachAbsentStringValue } from '@tests/unit/shared/TestCases/AbsentTests';

View File

@@ -1,9 +1,9 @@
import { describe, it, expect } from 'vitest';
import type { ICategory } from '@/domain/ICategory';
import type { Category } from '@/domain/Executables/Category/Category';
import { OperatingSystem } from '@/domain/OperatingSystem';
import type { IScriptingDefinition } from '@/domain/IScriptingDefinition';
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
import { RecommendationLevel } from '@/domain/RecommendationLevel';
import { RecommendationLevel } from '@/domain/Executables/Script/RecommendationLevel';
import { getEnumValues } from '@/application/Common/Enum';
import { CategoryCollection } from '@/domain/CategoryCollection';
import { ScriptStub } from '@tests/unit/shared/Stubs/ScriptStub';
@@ -296,7 +296,7 @@ function getValidScriptingDefinition(): IScriptingDefinition {
class CategoryCollectionBuilder {
private os = OperatingSystem.Windows;
private actions: readonly ICategory[] = [
private actions: readonly Category[] = [
new CategoryStub(1).withMandatoryScripts(),
];
@@ -307,7 +307,7 @@ class CategoryCollectionBuilder {
return this;
}
public withActions(actions: readonly ICategory[]): this {
public withActions(actions: readonly Category[]): this {
this.actions = actions;
return this;
}

View File

@@ -1,11 +1,12 @@
import { describe, it, expect } from 'vitest';
import { Category } from '@/domain/Category';
import { CollectionCategory } from '@/domain/Executables/Category/CollectionCategory';
import { CategoryStub } from '@tests/unit/shared/Stubs/CategoryStub';
import { ScriptStub } from '@tests/unit/shared/Stubs/ScriptStub';
import { itEachAbsentStringValue } from '@tests/unit/shared/TestCases/AbsentTests';
import type { ICategory, IScript } from '@/domain/ICategory';
import type { Category } from '@/domain/Executables/Category/Category';
import type { Script } from '@/domain/Executables/Script/Script';
describe('Category', () => {
describe('CollectionCategory', () => {
describe('ctor', () => {
describe('throws error if name is absent', () => {
itEachAbsentStringValue((absentValue) => {
@@ -23,8 +24,8 @@ describe('Category', () => {
it('throws error if no children are present', () => {
// arrange
const expectedError = 'A category must have at least one sub-category or script';
const scriptChildren: readonly IScript[] = [];
const categoryChildren: readonly ICategory[] = [];
const scriptChildren: readonly Script[] = [];
const categoryChildren: readonly Category[] = [];
// act
const construct = () => new CategoryBuilder()
.withSubcategories(categoryChildren)
@@ -173,9 +174,9 @@ class CategoryBuilder {
private docs: ReadonlyArray<string> = [];
private subcategories: ReadonlyArray<ICategory> = [];
private subcategories: ReadonlyArray<Category> = [];
private scripts: ReadonlyArray<IScript> = [
private scripts: ReadonlyArray<Script> = [
new ScriptStub(`[${CategoryBuilder.name}] script`),
];
@@ -194,18 +195,18 @@ class CategoryBuilder {
return this;
}
public withScripts(scripts: ReadonlyArray<IScript>): this {
public withScripts(scripts: ReadonlyArray<Script>): this {
this.scripts = scripts;
return this;
}
public withSubcategories(subcategories: ReadonlyArray<ICategory>): this {
public withSubcategories(subcategories: ReadonlyArray<Category>): this {
this.subcategories = subcategories;
return this;
}
public build(): Category {
return new Category({
public build(): CollectionCategory {
return new CollectionCategory({
id: this.id,
name: this.name,
docs: this.docs,

View File

@@ -1,8 +1,8 @@
import { describe, it, expect } from 'vitest';
import { ScriptCode } from '@/domain/ScriptCode';
import { DistinctReversibleScriptCode } from '@/domain/Executables/Script/Code/DistinctReversibleScriptCode';
import { getAbsentStringTestCases } from '@tests/unit/shared/TestCases/AbsentTests';
describe('ScriptCode', () => {
describe('DistinctReversibleScriptCode', () => {
describe('code', () => {
describe('throws with invalid code', () => {
// arrange
@@ -96,8 +96,8 @@ class ScriptCodeBuilder {
return this;
}
public build(): ScriptCode {
return new ScriptCode(
public build(): DistinctReversibleScriptCode {
return new DistinctReversibleScriptCode(
this.execute,
this.revert,
);

View File

@@ -1,11 +1,11 @@
import { describe, it, expect } from 'vitest';
import { getEnumValues } from '@/application/Common/Enum';
import { Script } from '@/domain/Script';
import { RecommendationLevel } from '@/domain/RecommendationLevel';
import type { IScriptCode } from '@/domain/IScriptCode';
import { CollectionScript } from '@/domain/Executables/Script/CollectionScript';
import { RecommendationLevel } from '@/domain/Executables/Script/RecommendationLevel';
import type { ScriptCode } from '@/domain/Executables/Script/Code/ScriptCode';
import { ScriptCodeStub } from '@tests/unit/shared/Stubs/ScriptCodeStub';
describe('Script', () => {
describe('CollectionScript', () => {
describe('ctor', () => {
describe('scriptCode', () => {
it('assigns code correctly', () => {
@@ -96,7 +96,7 @@ describe('Script', () => {
class ScriptBuilder {
private name = 'test-script';
private code: IScriptCode = new ScriptCodeStub();
private code: ScriptCode = new ScriptCodeStub();
private level? = RecommendationLevel.Standard;
@@ -109,7 +109,7 @@ class ScriptBuilder {
return this;
}
public withCode(code: IScriptCode): this {
public withCode(code: ScriptCode): this {
this.code = code;
return this;
}
@@ -129,8 +129,8 @@ class ScriptBuilder {
return this;
}
public build(): Script {
return new Script({
public build(): CollectionScript {
return new CollectionScript({
name: this.name,
code: this.code,
docs: this.docs,

View File

@@ -1,4 +1,4 @@
import { createScriptCode } from '@/domain/ScriptCodeFactory';
import { createScriptCode } from '@/domain/Executables/Script/Code/ScriptCodeFactory';
describe('ScriptCodeFactory', () => {
describe('createScriptCode', () => {

View File

@@ -3,14 +3,14 @@ import {
type SelectionCheckContext, type SelectionMutationContext,
getCurrentRecommendationStatus, setCurrentRecommendationStatus,
} from '@/presentation/components/Scripts/Menu/Recommendation/RecommendationStatusHandler';
import { RecommendationLevel } from '@/domain/RecommendationLevel';
import { RecommendationLevel } from '@/domain/Executables/Script/RecommendationLevel';
import type { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';
import { EnumRangeTestRunner } from '@tests/unit/application/Common/EnumRangeTestRunner';
import type { ScriptSelection } from '@/application/Context/State/Selection/Script/ScriptSelection';
import type { MethodCall } from '@tests/unit/shared/Stubs/StubWithObservableMethodCalls';
import { expectExists } from '@tests/shared/Assertions/ExpectExists';
import { scrambledEqual } from '@/application/Common/Array';
import type { IScript } from '@/domain/IScript';
import type { Script } from '@/domain/Executables/Script/Script';
import { RecommendationStatusType } from '@/presentation/components/Scripts/Menu/Recommendation/RecommendationStatusType';
import { RecommendationStatusTestScenario } from './RecommendationStatusTestScenario';
@@ -85,8 +85,8 @@ describe('RecommendationStatusHandler', () => {
expectExists(call);
if (expectedCall.args.length > 0) { /** {@link ScriptSelection.selectOnly}. */
expect(scrambledEqual(
call.args[0] as IScript[],
expectedCall.args[0] as IScript[],
call.args[0] as Script[],
expectedCall.args[0] as Script[],
)).to.equal(true);
}
});

View File

@@ -1,5 +1,5 @@
import type { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
import { RecommendationLevel } from '@/domain/RecommendationLevel';
import { RecommendationLevel } from '@/domain/Executables/Script/RecommendationLevel';
import { CategoryCollectionStateStub } from '@tests/unit/shared/Stubs/CategoryCollectionStateStub';
import { ScriptSelectionStub } from '@tests/unit/shared/Stubs/ScriptSelectionStub';
import { ScriptStub } from '@tests/unit/shared/Stubs/ScriptStub';

View File

@@ -8,15 +8,15 @@ import { UserSelectionStub } from '@tests/unit/shared/Stubs/UserSelectionStub';
import { SelectedScriptStub } from '@tests/unit/shared/Stubs/SelectedScriptStub';
import type { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
import { CategorySelectionStub } from '@tests/unit/shared/Stubs/CategorySelectionStub';
import type { IScript } from '@/domain/IScript';
import type { Script } from '@/domain/Executables/Script/Script';
describe('CategoryReverter', () => {
describe('getState', () => {
// arrange
const testScenarios: ReadonlyArray<{
readonly description: string;
readonly allScripts: readonly IScript[];
readonly selectScripts: (allScripts: readonly IScript[]) => readonly SelectedScript[];
readonly allScripts: readonly Script[];
readonly selectScripts: (allScripts: readonly Script[]) => readonly SelectedScript[];
readonly expectedState: boolean;
}> = [
{

View File

@@ -1,6 +1,6 @@
import { describe, it, expect } from 'vitest';
import type { IScript } from '@/domain/IScript';
import type { ICategory } from '@/domain/ICategory';
import type { Script } from '@/domain/Executables/Script/Script';
import type { Category } from '@/domain/Executables/Category/Category';
import { CategoryStub } from '@tests/unit/shared/Stubs/CategoryStub';
import { ScriptStub } from '@tests/unit/shared/Stubs/ScriptStub';
import { CategoryCollectionStub } from '@tests/unit/shared/Stubs/CategoryCollectionStub';
@@ -8,7 +8,7 @@ import {
getCategoryId, getCategoryNodeId, getScriptId,
getScriptNodeId, parseAllCategories, parseSingleCategory,
} from '@/presentation/components/Scripts/View/Tree/TreeViewAdapter/CategoryNodeMetadataConverter';
import { NodeDataType } from '@/application/Parser/NodeValidation/NodeDataType';
import { ExecutableType } from '@/application/Parser/Executable/Validation/ExecutableType';
import type { NodeMetadata } from '@/presentation/components/Scripts/View/Tree/NodeContent/NodeMetadata';
import { expectExists } from '@tests/shared/Assertions/ExpectExists';
@@ -94,7 +94,7 @@ describe('CategoryNodeMetadataConverter', () => {
});
});
function isReversible(category: ICategory): boolean {
function isReversible(category: Category): boolean {
if (category.scripts) {
if (category.scripts.some((s) => !s.canRevert())) {
return false;
@@ -108,8 +108,8 @@ function isReversible(category: ICategory): boolean {
return true;
}
function expectSameCategory(node: NodeMetadata, category: ICategory): void {
expect(node.type).to.equal(NodeDataType.Category, getErrorMessage('type'));
function expectSameCategory(node: NodeMetadata, category: Category): void {
expect(node.type).to.equal(ExecutableType.Category, getErrorMessage('type'));
expect(node.id).to.equal(getCategoryNodeId(category), getErrorMessage('id'));
expect(node.docs).to.equal(category.docs, getErrorMessage('docs'));
expect(node.text).to.equal(category.name, getErrorMessage('name'));
@@ -135,8 +135,8 @@ function expectSameCategory(node: NodeMetadata, category: ICategory): void {
}
}
function expectSameScript(node: NodeMetadata, script: IScript): void {
expect(node.type).to.equal(NodeDataType.Script, getErrorMessage('type'));
function expectSameScript(node: NodeMetadata, script: Script): void {
expect(node.type).to.equal(ExecutableType.Script, getErrorMessage('type'));
expect(node.id).to.equal(getScriptNodeId(script), getErrorMessage('id'));
expect(node.docs).to.equal(script.docs, getErrorMessage('docs'));
expect(node.text).to.equal(script.name, getErrorMessage('name'));

View File

@@ -2,7 +2,7 @@ import { describe, it, expect } from 'vitest';
import { useSelectedScriptNodeIds } from '@/presentation/components/Scripts/View/Tree/TreeViewAdapter/UseSelectedScriptNodeIds';
import { SelectedScriptStub } from '@tests/unit/shared/Stubs/SelectedScriptStub';
import { getScriptNodeId } from '@/presentation/components/Scripts/View/Tree/TreeViewAdapter/CategoryNodeMetadataConverter';
import type { IScript } from '@/domain/IScript';
import type { Script } from '@/domain/Executables/Script/Script';
import { UseUserSelectionStateStub } from '@tests/unit/shared/Stubs/UseUserSelectionStateStub';
import { ScriptStub } from '@tests/unit/shared/Stubs/ScriptStub';
@@ -23,7 +23,7 @@ describe('useSelectedScriptNodeIds', () => {
new SelectedScriptStub(new ScriptStub('id-1')),
new SelectedScriptStub(new ScriptStub('id-2')),
];
const parsedNodeIds = new Map<IScript, string>([
const parsedNodeIds = new Map<Script, string>([
[selectedScripts[0].script, 'expected-id-1'],
[selectedScripts[1].script, 'expected-id-2'],
]);
@@ -47,7 +47,7 @@ describe('useSelectedScriptNodeIds', () => {
new SelectedScriptStub(new ScriptStub('id-1')),
new SelectedScriptStub(new ScriptStub('id-2')),
];
const parsedNodeIds = new Map<IScript, string>([
const parsedNodeIds = new Map<Script, string>([
[changedScripts[0].script, 'expected-id-1'],
[changedScripts[1].script, 'expected-id-2'],
]);
@@ -70,7 +70,7 @@ describe('useSelectedScriptNodeIds', () => {
type ScriptNodeIdParser = typeof getScriptNodeId;
function createNodeIdParserFromMap(scriptToIdMap: Map<IScript, string>): ScriptNodeIdParser {
function createNodeIdParserFromMap(scriptToIdMap: Map<Script, string>): ScriptNodeIdParser {
return (script) => {
const expectedId = scriptToIdMap.get(script);
if (!expectedId) {

View File

@@ -11,8 +11,8 @@ import { ScriptStub } from '@tests/unit/shared/Stubs/ScriptStub';
import { CategoryStub } from '@tests/unit/shared/Stubs/CategoryStub';
import { TreeNodeStub } from '@tests/unit/shared/Stubs/TreeNodeStub';
import { HierarchyAccessStub } from '@tests/unit/shared/Stubs/HierarchyAccessStub';
import type { IScript } from '@/domain/IScript';
import type { ICategory } from '@/domain/ICategory';
import type { Script } from '@/domain/Executables/Script/Script';
import type { Category } from '@/domain/Executables/Category/Category';
import type { TreeNode } from '@/presentation/components/Scripts/View/Tree/TreeView/Node/TreeNode';
import { FilterChangeDetailsStub } from '@tests/unit/shared/Stubs/FilterChangeDetailsStub';
import type { FilterChangeDetails } from '@/application/Context/State/Filter/Event/FilterChangeDetails';
@@ -208,8 +208,8 @@ function itExpectedFilterTriggeredEvent(
) {
const testScenarios: ReadonlyArray<{
readonly description: string;
readonly scriptMatches: IScript[],
readonly categoryMatches: ICategory[],
readonly scriptMatches: Script[],
readonly categoryMatches: Category[],
readonly givenNode: TreeNode,
readonly expectedPredicateResult: boolean;
}> = [

View File

@@ -1,6 +1,6 @@
import type { FunctionCallCompilationContext } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
import type { ArgumentCompiler } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/SingleCall/Strategies/Argument/ArgumentCompiler';
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import type { FunctionCallCompilationContext } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
import type { ArgumentCompiler } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/SingleCall/Strategies/Argument/ArgumentCompiler';
import type { FunctionCall } from '@/application/Parser/Executable/Script/Compiler/Function/Call/FunctionCall';
import { FunctionCallStub } from './FunctionCallStub';
import { StubWithObservableMethodCalls } from './StubWithObservableMethodCalls';

View File

@@ -1,21 +0,0 @@
import type { ICategoryCollectionParseContext } from '@/application/Parser/Script/ICategoryCollectionParseContext';
import type { IScriptCompiler } from '@/application/Parser/Script/Compiler/IScriptCompiler';
import type { ILanguageSyntax } from '@/application/Parser/Script/Validation/Syntax/ILanguageSyntax';
import { ScriptCompilerStub } from './ScriptCompilerStub';
import { LanguageSyntaxStub } from './LanguageSyntaxStub';
export class CategoryCollectionParseContextStub implements ICategoryCollectionParseContext {
public compiler: IScriptCompiler = new ScriptCompilerStub();
public syntax: ILanguageSyntax = new LanguageSyntaxStub();
public withCompiler(compiler: IScriptCompiler) {
this.compiler = compiler;
return this;
}
public withSyntax(syntax: ILanguageSyntax) {
this.syntax = syntax;
return this;
}
}

View File

@@ -0,0 +1,22 @@
import type { IScriptCompiler } from '@/application/Parser/Executable/Script/Compiler/IScriptCompiler';
import type { ILanguageSyntax } from '@/application/Parser/Executable/Script/Validation/Syntax/ILanguageSyntax';
import type { CategoryCollectionSpecificUtilities } from '@/application/Parser/Executable/CategoryCollectionSpecificUtilities';
import { ScriptCompilerStub } from './ScriptCompilerStub';
import { LanguageSyntaxStub } from './LanguageSyntaxStub';
export class CategoryCollectionSpecificUtilitiesStub
implements CategoryCollectionSpecificUtilities {
public compiler: IScriptCompiler = new ScriptCompilerStub();
public syntax: ILanguageSyntax = new LanguageSyntaxStub();
public withCompiler(compiler: IScriptCompiler) {
this.compiler = compiler;
return this;
}
public withSyntax(syntax: ILanguageSyntax) {
this.syntax = syntax;
return this;
}
}

View File

@@ -1,7 +1,7 @@
import type { IApplicationCode } from '@/application/Context/State/Code/IApplicationCode';
import type { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';
import { OperatingSystem } from '@/domain/OperatingSystem';
import type { IScript } from '@/domain/IScript';
import type { Script } from '@/domain/Executables/Script/Script';
import { ScriptStub } from '@tests/unit/shared/Stubs/ScriptStub';
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
import type { UserSelection } from '@/application/Context/State/Selection/UserSelection';
@@ -27,7 +27,7 @@ export class CategoryCollectionStateStub implements ICategoryCollectionState {
public selection: UserSelection = new UserSelectionStub();
constructor(readonly allScripts: IScript[] = [new ScriptStub('script-id')]) {
constructor(readonly allScripts: Script[] = [new ScriptStub('script-id')]) {
this.selection = new UserSelectionStub()
.withScripts(new ScriptSelectionStub());
this.collection = new CategoryCollectionStub()

View File

@@ -1,9 +1,9 @@
import { OperatingSystem } from '@/domain/OperatingSystem';
import type { IScriptingDefinition } from '@/domain/IScriptingDefinition';
import type { IScript } from '@/domain/IScript';
import type { ICategory } from '@/domain/ICategory';
import type { Script } from '@/domain/Executables/Script/Script';
import type { Category } from '@/domain/Executables/Category/Category';
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
import { RecommendationLevel } from '@/domain/RecommendationLevel';
import { RecommendationLevel } from '@/domain/Executables/Script/RecommendationLevel';
import { ScriptStub } from './ScriptStub';
import { ScriptingDefinitionStub } from './ScriptingDefinitionStub';
import { CategoryStub } from './CategoryStub';
@@ -13,13 +13,13 @@ export class CategoryCollectionStub implements ICategoryCollection {
public os = OperatingSystem.Linux;
public initialScript: IScript = new ScriptStub('55');
public initialScript: Script = new ScriptStub('55');
public totalScripts = 0;
public totalCategories = 0;
public readonly actions = new Array<ICategory>();
public readonly actions = new Array<Category>();
public withSomeActions(): this {
this.withAction(new CategoryStub(1));
@@ -28,12 +28,12 @@ export class CategoryCollectionStub implements ICategoryCollection {
return this;
}
public withAction(category: ICategory): this {
public withAction(category: Category): this {
this.actions.push(category);
return this;
}
public withActions(...actions: readonly ICategory[]): this {
public withActions(...actions: readonly Category[]): this {
for (const action of actions) {
this.withAction(action);
}
@@ -50,7 +50,7 @@ export class CategoryCollectionStub implements ICategoryCollection {
return this;
}
public withInitialScript(script: IScript): this {
public withInitialScript(script: Script): this {
this.initialScript = script;
return this;
}
@@ -60,41 +60,41 @@ export class CategoryCollectionStub implements ICategoryCollection {
return this;
}
public getCategory(categoryId: number): ICategory {
public getCategory(categoryId: number): Category {
return this.getAllCategories()
.find((category) => category.id === categoryId)
?? new CategoryStub(categoryId);
}
public getScriptsByLevel(level: RecommendationLevel): readonly IScript[] {
public getScriptsByLevel(level: RecommendationLevel): readonly Script[] {
return this.getAllScripts()
.filter((script) => script.level !== undefined && script.level <= level);
}
public getScript(scriptId: string): IScript {
public getScript(scriptId: string): Script {
return this.getAllScripts()
.find((script) => scriptId === script.id)
?? new ScriptStub(scriptId);
}
public getAllScripts(): ReadonlyArray<IScript> {
public getAllScripts(): ReadonlyArray<Script> {
return this.actions.flatMap((category) => getScriptsRecursively(category));
}
public getAllCategories(): ReadonlyArray<ICategory> {
public getAllCategories(): ReadonlyArray<Category> {
return this.actions.flatMap(
(category) => [category, ...getSubCategoriesRecursively(category)],
);
}
}
function getSubCategoriesRecursively(category: ICategory): ReadonlyArray<ICategory> {
function getSubCategoriesRecursively(category: Category): ReadonlyArray<Category> {
return (category.subCategories || []).flatMap(
(subCategory) => [subCategory, ...getSubCategoriesRecursively(subCategory)],
);
}
function getScriptsRecursively(category: ICategory): ReadonlyArray<IScript> {
function getScriptsRecursively(category: Category): ReadonlyArray<Script> {
return [
...(category.scripts || []),
...(category.subCategories || []).flatMap(

View File

@@ -1,14 +1,14 @@
import type { CategoryData, CategoryOrScriptData, DocumentationData } from '@/application/collections/';
import type { CategoryData, ExecutableData, DocumentationData } from '@/application/collections/';
import { createScriptDataWithCode } from '@tests/unit/shared/Stubs/ScriptDataStub';
export class CategoryDataStub implements CategoryData {
public children: readonly CategoryOrScriptData[] = [createScriptDataWithCode()];
public children: readonly ExecutableData[] = [createScriptDataWithCode()];
public category = 'category name';
public docs?: DocumentationData;
public withChildren(children: readonly CategoryOrScriptData[]) {
public withChildren(children: readonly ExecutableData[]) {
this.children = children;
return this;
}

View File

@@ -1,13 +1,13 @@
import type { CategoryFactory } from '@/application/Parser/CategoryParser';
import type { CategoryInitParameters } from '@/domain/Category';
import type { ICategory } from '@/domain/ICategory';
import type { CategoryFactory } from '@/application/Parser/Executable/CategoryParser';
import type { CategoryInitParameters } from '@/domain/Executables/Category/CollectionCategory';
import type { Category } from '@/domain/Executables/Category/Category';
import { CategoryStub } from './CategoryStub';
export function createCategoryFactorySpy(): {
readonly categoryFactorySpy: CategoryFactory;
getInitParameters: (category: ICategory) => CategoryInitParameters | undefined;
getInitParameters: (category: Category) => CategoryInitParameters | undefined;
} {
const createdCategories = new Map<ICategory, CategoryInitParameters>();
const createdCategories = new Map<Category, CategoryInitParameters>();
return {
categoryFactorySpy: (parameters) => {
const category = new CategoryStub(55);

View File

@@ -1,28 +1,29 @@
import { BaseEntity } from '@/infrastructure/Entity/BaseEntity';
import type { ICategory, IScript } from '@/domain/ICategory';
import { RecommendationLevel } from '@/domain/RecommendationLevel';
import type { Category } from '@/domain/Executables/Category/Category';
import { RecommendationLevel } from '@/domain/Executables/Script/RecommendationLevel';
import type { Script } from '@/domain/Executables/Script/Script';
import { ScriptStub } from './ScriptStub';
export class CategoryStub extends BaseEntity<number> implements ICategory {
export class CategoryStub extends BaseEntity<number> implements Category {
public name = `category-with-id-${this.id}`;
public readonly subCategories = new Array<ICategory>();
public readonly subCategories = new Array<Category>();
public readonly scripts = new Array<IScript>();
public readonly scripts = new Array<Script>();
public docs: readonly string[] = new Array<string>();
private allScriptsRecursively: (readonly IScript[]) | undefined;
private allScriptsRecursively: (readonly Script[]) | undefined;
public constructor(id: number) {
super(id);
}
public includes(script: IScript): boolean {
public includes(script: Script): boolean {
return this.getAllScriptsRecursively().some((s) => s.id === script.id);
}
public getAllScriptsRecursively(): readonly IScript[] {
public getAllScriptsRecursively(): readonly Script[] {
if (this.allScriptsRecursively === undefined) {
return [
...this.scripts,
@@ -38,7 +39,7 @@ export class CategoryStub extends BaseEntity<number> implements ICategory {
);
}
public withScripts(...scripts: IScript[]): this {
public withScripts(...scripts: Script[]): this {
for (const script of scripts) {
this.withScript(script);
}
@@ -49,7 +50,7 @@ export class CategoryStub extends BaseEntity<number> implements ICategory {
return this.withAllScriptsRecursively(...scriptIds.map((id) => new ScriptStub(id)));
}
public withAllScriptsRecursively(...scripts: IScript[]): this {
public withAllScriptsRecursively(...scripts: Script[]): this {
this.allScriptsRecursively = [...scripts];
return this;
}
@@ -61,19 +62,19 @@ export class CategoryStub extends BaseEntity<number> implements ICategory {
.withScript(new ScriptStub(`[${CategoryStub.name}] script-3`).withLevel(undefined));
}
public withCategories(...categories: ICategory[]): this {
public withCategories(...categories: Category[]): this {
for (const category of categories) {
this.withCategory(category);
}
return this;
}
public withCategory(category: ICategory): this {
public withCategory(category: Category): this {
this.subCategories.push(category);
return this;
}
public withScript(script: IScript): this {
public withScript(script: Script): this {
this.scripts.push(script);
return this;
}

View File

@@ -1,15 +1,15 @@
import type { ICodeChangedEvent } from '@/application/Context/State/Code/Event/ICodeChangedEvent';
import type { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
import type { IScript } from '@/domain/IScript';
import type { Script } from '@/domain/Executables/Script/Script';
export class CodeChangedEventStub implements ICodeChangedEvent {
public code: string;
public addedScripts: readonly IScript[];
public addedScripts: readonly Script[];
public removedScripts: readonly IScript[];
public removedScripts: readonly Script[];
public changedScripts: readonly IScript[];
public changedScripts: readonly Script[];
public isEmpty(): boolean {
throw new Error('Method not implemented.');

View File

@@ -1,5 +1,5 @@
import type { CodeSegmentMerger } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/CodeSegmentJoin/CodeSegmentMerger';
import type { CompiledCode } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/CompiledCode';
import type { CodeSegmentMerger } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/CodeSegmentJoin/CodeSegmentMerger';
import type { CompiledCode } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/CompiledCode';
import { CompiledCodeStub } from './CompiledCodeStub';
import { StubWithObservableMethodCalls } from './StubWithObservableMethodCalls';

View File

@@ -1,5 +1,5 @@
import type { ICodeLine } from '@/application/Parser/Script/Validation/ICodeLine';
import type { ICodeValidationRule, IInvalidCodeLine } from '@/application/Parser/Script/Validation/ICodeValidationRule';
import type { ICodeLine } from '@/application/Parser/Executable/Script/Validation/ICodeLine';
import type { ICodeValidationRule, IInvalidCodeLine } from '@/application/Parser/Executable/Script/Validation/ICodeValidationRule';
export class CodeValidationRuleStub implements ICodeValidationRule {
public readonly receivedLines = new Array<readonly ICodeLine[]>();

View File

@@ -1,7 +1,7 @@
import { expect } from 'vitest';
import type { Constructible } from '@/TypeHelpers';
import type { ICodeValidationRule } from '@/application/Parser/Script/Validation/ICodeValidationRule';
import type { ICodeValidator } from '@/application/Parser/Script/Validation/ICodeValidator';
import type { ICodeValidationRule } from '@/application/Parser/Executable/Script/Validation/ICodeValidationRule';
import type { ICodeValidator } from '@/application/Parser/Executable/Script/Validation/ICodeValidator';
export class CodeValidatorStub implements ICodeValidator {
public callHistory = new Array<{

View File

@@ -1,7 +1,7 @@
import type {
CategoryData, ScriptData, CollectionData, ScriptingDefinitionData, FunctionData,
} from '@/application/collections/';
import { RecommendationLevel } from '@/domain/RecommendationLevel';
import { RecommendationLevel } from '@/domain/Executables/Script/RecommendationLevel';
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
import { createScriptDataWithCode } from './ScriptDataStub';

View File

@@ -1,4 +1,4 @@
import type { CompiledCode } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/CompiledCode';
import type { CompiledCode } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/CompiledCode';
export class CompiledCodeStub implements CompiledCode {
public code = `${CompiledCodeStub.name}: code`;

View File

@@ -0,0 +1,11 @@
import type { ExecutableErrorContext } from '@/application/Parser/Executable/Validation/ExecutableErrorContext';
import { ExecutableType } from '@/application/Parser/Executable/Validation/ExecutableType';
import { CategoryDataStub } from './CategoryDataStub';
export function createExecutableErrorContextStub(): ExecutableErrorContext {
return {
type: ExecutableType.Category,
self: new CategoryDataStub(),
parentCategory: new CategoryDataStub(),
};
}

View File

@@ -1,13 +1,13 @@
import type { NodeData } from '@/application/Parser/NodeValidation/NodeData';
import type { NodeDataValidator, NodeDataValidatorFactory } from '@/application/Parser/NodeValidation/NodeDataValidator';
import type { ExecutableData } from '@/application/collections/';
import type { ExecutableValidator, ExecutableValidatorFactory } from '@/application/Parser/Executable/Validation/ExecutableValidator';
import { StubWithObservableMethodCalls } from './StubWithObservableMethodCalls';
export const createNodeDataValidatorFactoryStub
: NodeDataValidatorFactory = () => new NodeDataValidatorStub();
export const createExecutableValidatorFactoryStub
: ExecutableValidatorFactory = () => new ExecutableValidatorStub();
export class NodeDataValidatorStub
extends StubWithObservableMethodCalls<NodeDataValidator>
implements NodeDataValidator {
export class ExecutableValidatorStub
extends StubWithObservableMethodCalls<ExecutableValidator>
implements ExecutableValidator {
private assertThrowsOnFalseCondition = true;
public withAssertThrowsOnFalseCondition(enableAssertThrows: boolean): this {
@@ -23,10 +23,10 @@ export class NodeDataValidatorStub
return this;
}
public assertDefined(node: NodeData): this {
public assertDefined(data: ExecutableData): this {
this.registerMethodCall({
methodName: 'assertDefined',
args: [node],
args: [data],
});
return this;
}
@@ -41,7 +41,7 @@ export class NodeDataValidatorStub
});
if (this.assertThrowsOnFalseCondition) {
if (!validationPredicate()) {
throw new Error(`[${NodeDataValidatorStub.name}] Assert validation failed: ${errorMessage}`);
throw new Error(`[${ExecutableValidatorStub.name}] Assert validation failed: ${errorMessage}`);
}
}
return this;
@@ -52,6 +52,6 @@ export class NodeDataValidatorStub
methodName: 'createContextualErrorMessage',
args: [errorMessage],
});
return `${NodeDataValidatorStub.name}: ${errorMessage}`;
return `${ExecutableValidatorStub.name}: ${errorMessage}`;
}
}

View File

@@ -1,6 +1,6 @@
import type { IExpressionEvaluationContext } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionEvaluationContext';
import type { IPipelineCompiler } from '@/application/Parser/Script/Compiler/Expressions/Pipes/IPipelineCompiler';
import type { IReadOnlyFunctionCallArgumentCollection } from '@/application/Parser/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
import type { IExpressionEvaluationContext } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/ExpressionEvaluationContext';
import type { IPipelineCompiler } from '@/application/Parser/Executable/Script/Compiler/Expressions/Pipes/IPipelineCompiler';
import type { IReadOnlyFunctionCallArgumentCollection } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
import { FunctionCallArgumentCollectionStub } from './FunctionCallArgumentCollectionStub';
import { PipelineCompilerStub } from './PipelineCompilerStub';

View File

@@ -1,5 +1,5 @@
import type { IExpression } from '@/application/Parser/Script/Compiler/Expressions/Expression/IExpression';
import type { IExpressionParser } from '@/application/Parser/Script/Compiler/Expressions/Parser/IExpressionParser';
import type { IExpression } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/IExpression';
import type { IExpressionParser } from '@/application/Parser/Executable/Script/Compiler/Expressions/Parser/IExpressionParser';
export class ExpressionParserStub implements IExpressionParser {
public callHistory = new Array<string>();

View File

@@ -1,7 +1,7 @@
import { ExpressionPosition } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionPosition';
import type { IExpression } from '@/application/Parser/Script/Compiler/Expressions/Expression/IExpression';
import type { IReadOnlyFunctionParameterCollection } from '@/application/Parser/Script/Compiler/Function/Parameter/IFunctionParameterCollection';
import type { IExpressionEvaluationContext } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionEvaluationContext';
import { ExpressionPosition } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/ExpressionPosition';
import type { IExpression } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/IExpression';
import type { IReadOnlyFunctionParameterCollection } from '@/application/Parser/Executable/Script/Compiler/Function/Parameter/IFunctionParameterCollection';
import type { IExpressionEvaluationContext } from '@/application/Parser/Executable/Script/Compiler/Expressions/Expression/ExpressionEvaluationContext';
import { FunctionParameterCollectionStub } from './FunctionParameterCollectionStub';
export class ExpressionStub implements IExpression {

View File

@@ -1,7 +1,7 @@
import type { IExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/IExpressionsCompiler';
import type { IReadOnlyFunctionCallArgumentCollection } from '@/application/Parser/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
import type { IExpressionsCompiler } from '@/application/Parser/Executable/Script/Compiler/Expressions/IExpressionsCompiler';
import type { IReadOnlyFunctionCallArgumentCollection } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
import { scrambledEqual } from '@/application/Common/Array';
import { FunctionBodyType, type ISharedFunction } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
import { FunctionBodyType, type ISharedFunction } from '@/application/Parser/Executable/Script/Compiler/Function/ISharedFunction';
import { FunctionCallArgumentCollectionStub } from '@tests/unit/shared/Stubs/FunctionCallArgumentCollectionStub';
import { StubWithObservableMethodCalls } from './StubWithObservableMethodCalls';

View File

@@ -1,13 +1,13 @@
import type { ICategory } from '@/domain/ICategory';
import type { IScript } from '@/domain/IScript';
import type { Category } from '@/domain/Executables/Category/Category';
import type { Script } from '@/domain/Executables/Script/Script';
import type { FilterResult } from '@/application/Context/State/Filter/Result/FilterResult';
import { CategoryStub } from './CategoryStub';
import { ScriptStub } from './ScriptStub';
export class FilterResultStub implements FilterResult {
public categoryMatches: readonly ICategory[] = [];
public categoryMatches: readonly Category[] = [];
public scriptMatches: readonly IScript[] = [];
public scriptMatches: readonly Script[] = [];
public query = '';
@@ -23,12 +23,12 @@ export class FilterResultStub implements FilterResult {
.withScriptMatches([new ScriptStub('script-2')]);
}
public withCategoryMatches(matches: readonly ICategory[]) {
public withCategoryMatches(matches: readonly Category[]) {
this.categoryMatches = matches;
return this;
}
public withScriptMatches(matches: readonly IScript[]) {
public withScriptMatches(matches: readonly Script[]) {
this.scriptMatches = matches;
return this;
}

View File

@@ -1,5 +1,5 @@
import type { IFunctionCallArgument } from '@/application/Parser/Script/Compiler/Function/Call/Argument/IFunctionCallArgument';
import type { IFunctionCallArgumentCollection } from '@/application/Parser/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
import type { IFunctionCallArgument } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Argument/IFunctionCallArgument';
import type { IFunctionCallArgumentCollection } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
import { FunctionCallArgumentStub } from './FunctionCallArgumentStub';
export class FunctionCallArgumentCollectionStub implements IFunctionCallArgumentCollection {

View File

@@ -1,4 +1,4 @@
import type { IFunctionCallArgument } from '@/application/Parser/Script/Compiler/Function/Call/Argument/IFunctionCallArgument';
import type { IFunctionCallArgument } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Argument/IFunctionCallArgument';
export class FunctionCallArgumentStub implements IFunctionCallArgument {
public parameterName = 'stub-parameter-name';

View File

@@ -1,7 +1,7 @@
import type { FunctionCallCompilationContext } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
import type { SingleCallCompiler } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/SingleCall/SingleCallCompiler';
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import type { ISharedFunctionCollection } from '@/application/Parser/Script/Compiler/Function/ISharedFunctionCollection';
import type { FunctionCallCompilationContext } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
import type { SingleCallCompiler } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/SingleCall/SingleCallCompiler';
import type { FunctionCall } from '@/application/Parser/Executable/Script/Compiler/Function/Call/FunctionCall';
import type { ISharedFunctionCollection } from '@/application/Parser/Executable/Script/Compiler/Function/ISharedFunctionCollection';
import { SingleCallCompilerStub } from './SingleCallCompilerStub';
import { FunctionCallStub } from './FunctionCallStub';
import { SharedFunctionCollectionStub } from './SharedFunctionCollectionStub';

View File

@@ -1,7 +1,7 @@
import type { CompiledCode } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/CompiledCode';
import type { FunctionCallCompiler } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/FunctionCallCompiler';
import type { ISharedFunctionCollection } from '@/application/Parser/Script/Compiler/Function/ISharedFunctionCollection';
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import type { CompiledCode } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/CompiledCode';
import type { FunctionCallCompiler } from '@/application/Parser/Executable/Script/Compiler/Function/Call/Compiler/FunctionCallCompiler';
import type { ISharedFunctionCollection } from '@/application/Parser/Executable/Script/Compiler/Function/ISharedFunctionCollection';
import type { FunctionCall } from '@/application/Parser/Executable/Script/Compiler/Function/Call/FunctionCall';
import { CompiledCodeStub } from './CompiledCodeStub';
interface FunctionCallCompilationTestScenario {

View File

@@ -1,4 +1,4 @@
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import type { FunctionCall } from '@/application/Parser/Executable/Script/Compiler/Function/Call/FunctionCall';
import { FunctionCallArgumentCollectionStub } from './FunctionCallArgumentCollectionStub';
export class FunctionCallStub implements FunctionCall {

View File

@@ -1,4 +1,4 @@
import type { IFunctionCode } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
import type { IFunctionCode } from '@/application/Parser/Executable/Script/Compiler/Function/ISharedFunction';
export class FunctionCodeStub implements IFunctionCode {
public execute = 'execute code (function-code-stub)';

View File

@@ -1,5 +1,5 @@
import type { IFunctionParameter } from '@/application/Parser/Script/Compiler/Function/Parameter/IFunctionParameter';
import type { IFunctionParameterCollection } from '@/application/Parser/Script/Compiler/Function/Parameter/IFunctionParameterCollection';
import type { IFunctionParameter } from '@/application/Parser/Executable/Script/Compiler/Function/Parameter/IFunctionParameter';
import type { IFunctionParameterCollection } from '@/application/Parser/Executable/Script/Compiler/Function/Parameter/IFunctionParameterCollection';
import { FunctionParameterStub } from './FunctionParameterStub';
export class FunctionParameterCollectionStub implements IFunctionParameterCollection {

View File

@@ -1,4 +1,4 @@
import type { IFunctionParameter } from '@/application/Parser/Script/Compiler/Function/Parameter/IFunctionParameter';
import type { IFunctionParameter } from '@/application/Parser/Executable/Script/Compiler/Function/Parameter/IFunctionParameter';
export class FunctionParameterStub implements IFunctionParameter {
public name = 'function-parameter-stub';

View File

@@ -1,4 +1,4 @@
import type { ILanguageSyntax } from '@/application/Parser/Script/Validation/Syntax/ILanguageSyntax';
import type { ILanguageSyntax } from '@/application/Parser/Executable/Script/Validation/Syntax/ILanguageSyntax';
export class LanguageSyntaxStub implements ILanguageSyntax {
public commentDelimiters: string[] = [];

View File

@@ -1,11 +0,0 @@
import type { NodeDataErrorContext } from '@/application/Parser/NodeValidation/NodeDataErrorContext';
import { NodeDataType } from '@/application/Parser/NodeValidation/NodeDataType';
import { CategoryDataStub } from './CategoryDataStub';
export function createNodeDataErrorContextStub(): NodeDataErrorContext {
return {
type: NodeDataType.Category,
selfNode: new CategoryDataStub(),
parentNode: new CategoryDataStub(),
};
}

View File

@@ -1,5 +1,5 @@
import type { IPipe } from '@/application/Parser/Script/Compiler/Expressions/Pipes/IPipe';
import type { IPipeFactory } from '@/application/Parser/Script/Compiler/Expressions/Pipes/PipeFactory';
import type { IPipe } from '@/application/Parser/Executable/Script/Compiler/Expressions/Pipes/IPipe';
import type { IPipeFactory } from '@/application/Parser/Executable/Script/Compiler/Expressions/Pipes/PipeFactory';
export class PipeFactoryStub implements IPipeFactory {
private readonly pipes = new Array<IPipe>();

View File

@@ -1,4 +1,4 @@
import type { IPipe } from '@/application/Parser/Script/Compiler/Expressions/Pipes/IPipe';
import type { IPipe } from '@/application/Parser/Executable/Script/Compiler/Expressions/Pipes/IPipe';
export class PipeStub implements IPipe {
public name = 'pipeStub';

View File

@@ -1,4 +1,4 @@
import type { IPipelineCompiler } from '@/application/Parser/Script/Compiler/Expressions/Pipes/IPipelineCompiler';
import type { IPipelineCompiler } from '@/application/Parser/Executable/Script/Compiler/Expressions/Pipes/IPipelineCompiler';
export class PipelineCompilerStub implements IPipelineCompiler {
public compileHistory: Array<{ value: string, pipeline: string }> = [];

Some files were not shown because too many files have changed in this diff Show More