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';