This commit adds validation logic in compiler to check for max allowed characters per line for scripts. This allows preventing bugs caused by limitation of terminal emulators. Other supporting changes: - Rename/refactor related code for clarity and better maintainability. - Drop `I` prefix from interfaces to align with latest convention. - Refactor CodeValidator to be functional rather than object-oriented for simplicity. - Refactor syntax definition construction to be functional and be part of rule for better separation of concerns. - Refactored validation logic to use an enum-based factory pattern for improved maintainability and scalability.
103 lines
3.9 KiB
TypeScript
103 lines
3.9 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
|
import type { FunctionData } from '@/application/collections/';
|
|
import { itEachAbsentCollectionValue } from '@tests/unit/shared/TestCases/AbsentTests';
|
|
import { createFunctionDataWithCode } from '@tests/unit/shared/Stubs/FunctionDataStub';
|
|
import type { ScriptCompilerFactory } from '@/application/Parser/Executable/Script/Compiler/ScriptCompilerFactory';
|
|
import { createCategoryCollectionContext } from '@/application/Parser/Executable/CategoryCollectionContext';
|
|
import { createScriptCompilerFactorySpy } from '@tests/unit/shared/Stubs/ScriptCompilerFactoryStub';
|
|
|
|
describe('CategoryCollectionContext', () => {
|
|
describe('createCategoryCollectionContext', () => {
|
|
describe('functionsData', () => {
|
|
describe('can create with absent data', () => {
|
|
itEachAbsentCollectionValue<FunctionData>((absentValue) => {
|
|
// arrange
|
|
const context = new TextContext()
|
|
.withData(absentValue);
|
|
// act
|
|
const act = () => context.create();
|
|
// assert
|
|
expect(act).to.not.throw();
|
|
}, { excludeNull: true });
|
|
});
|
|
});
|
|
});
|
|
describe('compiler', () => {
|
|
it('constructed with correct functions', () => {
|
|
// arrange
|
|
const expectedFunctions = [createFunctionDataWithCode()];
|
|
const compilerSpy = createScriptCompilerFactorySpy();
|
|
const context = new TextContext()
|
|
.withData(expectedFunctions)
|
|
.withScriptCompilerFactory(compilerSpy.instance);
|
|
// act
|
|
const actualContext = context.create();
|
|
// assert
|
|
const actualCompiler = actualContext.compiler;
|
|
const compilerParameters = compilerSpy.getInitParameters(actualCompiler);
|
|
const actualFunctions = compilerParameters?.categoryContext.functions;
|
|
expect(actualFunctions).to.equal(expectedFunctions);
|
|
});
|
|
it('constructed with correct language', () => {
|
|
// arrange
|
|
const expectedLanguage = ScriptingLanguage.batchfile;
|
|
const compilerSpy = createScriptCompilerFactorySpy();
|
|
const context = new TextContext()
|
|
.withLanguage(expectedLanguage)
|
|
.withScriptCompilerFactory(compilerSpy.instance);
|
|
// act
|
|
const actualContext = context.create();
|
|
// assert
|
|
const actualCompiler = actualContext.compiler;
|
|
const compilerParameters = compilerSpy.getInitParameters(actualCompiler);
|
|
const actualLanguage = compilerParameters?.categoryContext.language;
|
|
expect(actualLanguage).to.equal(expectedLanguage);
|
|
});
|
|
});
|
|
describe('language', () => {
|
|
it('set from syntax factory', () => {
|
|
// arrange
|
|
const expectedLanguage = ScriptingLanguage.shellscript;
|
|
const context = new TextContext()
|
|
.withLanguage(expectedLanguage);
|
|
// act
|
|
const actualContext = context.create();
|
|
// assert
|
|
const actualLanguage = actualContext.language;
|
|
expect(actualLanguage).to.equal(expectedLanguage);
|
|
});
|
|
});
|
|
});
|
|
|
|
class TextContext {
|
|
private functionsData: readonly FunctionData[] | undefined = [createFunctionDataWithCode()];
|
|
|
|
private language: ScriptingLanguage = ScriptingLanguage.shellscript;
|
|
|
|
private scriptCompilerFactory: ScriptCompilerFactory = createScriptCompilerFactorySpy().instance;
|
|
|
|
public withScriptCompilerFactory(scriptCompilerFactory: ScriptCompilerFactory): this {
|
|
this.scriptCompilerFactory = scriptCompilerFactory;
|
|
return this;
|
|
}
|
|
|
|
public withData(data: readonly FunctionData[] | undefined): this {
|
|
this.functionsData = data;
|
|
return this;
|
|
}
|
|
|
|
public withLanguage(language: ScriptingLanguage): this {
|
|
this.language = language;
|
|
return this;
|
|
}
|
|
|
|
public create(): ReturnType<typeof createCategoryCollectionContext> {
|
|
return createCategoryCollectionContext(
|
|
this.functionsData,
|
|
this.language,
|
|
this.scriptCompilerFactory,
|
|
);
|
|
}
|
|
}
|