This commit refactors existing text utility functions into the application layer for broad reuse and integrates them across the codebase. Initially, these utilities were confined to test code, which limited their application. Changes: - Move text utilities to the application layer. - Centralize text utilities into dedicated files for better maintainability. - Improve robustness of utility functions with added type checks. - Replace duplicated logic with centralized utility functions throughout the codebase. - Expand unit tests to cover refactored code parts.
198 lines
6.2 KiB
TypeScript
198 lines
6.2 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { CodeBuilder } from '@/application/Context/State/Code/Generation/CodeBuilder';
|
|
import { splitTextIntoLines } from '@/application/Common/Text/SplitTextIntoLines';
|
|
|
|
describe('CodeBuilder', () => {
|
|
class CodeBuilderConcrete extends CodeBuilder {
|
|
private commentDelimiter = '//';
|
|
|
|
private newLineTerminator = '\n';
|
|
|
|
public withCommentDelimiter(delimiter: string): CodeBuilderConcrete {
|
|
this.commentDelimiter = delimiter;
|
|
return this;
|
|
}
|
|
|
|
public withNewLineTerminator(terminator: string): CodeBuilderConcrete {
|
|
this.newLineTerminator = terminator;
|
|
return this;
|
|
}
|
|
|
|
protected getCommentDelimiter(): string {
|
|
return this.commentDelimiter;
|
|
}
|
|
|
|
protected writeStandardOut(text: string): string {
|
|
return text;
|
|
}
|
|
|
|
protected getNewLineTerminator(): string {
|
|
return this.newLineTerminator;
|
|
}
|
|
}
|
|
describe('appendLine', () => {
|
|
it('when empty appends empty line', () => {
|
|
// arrange
|
|
const sut = new CodeBuilderConcrete();
|
|
// act
|
|
sut.appendLine().appendLine().appendLine();
|
|
// assert
|
|
expect(sut.toString()).to.equal('\n\n');
|
|
});
|
|
it('when not empty append string in new line', () => {
|
|
// arrange
|
|
const sut = new CodeBuilderConcrete();
|
|
const expected = 'str';
|
|
// act
|
|
sut.appendLine()
|
|
.appendLine(expected);
|
|
// assert
|
|
const result = sut.toString();
|
|
const lines = splitTextIntoLines(result);
|
|
expect(lines[1]).to.equal('str');
|
|
});
|
|
describe('append multi-line string correctly', () => {
|
|
it('appends multi-line string with empty lines preserved', () => {
|
|
// arrange
|
|
const sut = new CodeBuilderConcrete();
|
|
const expectedLines: string[] = ['', 'line1', '', 'line2', '', '', 'line3', '', ''];
|
|
const multilineInput = expectedLines.join('\n');
|
|
|
|
// act
|
|
sut.appendLine(multilineInput);
|
|
const actual = sut.toString();
|
|
|
|
// assert
|
|
const actualLines = splitTextIntoLines(actual);
|
|
expect(actualLines).to.deep.equal(expectedLines);
|
|
});
|
|
describe('recognizes different line terminators', () => {
|
|
const delimiters = ['\n', '\r\n', '\r'];
|
|
for (const delimiter of delimiters) {
|
|
it(`using "${JSON.stringify(delimiter)}"`, () => {
|
|
// arrange
|
|
const line1 = 'line1';
|
|
const line2 = 'line2';
|
|
const code = `${line1}${delimiter}${line2}`;
|
|
const sut = new CodeBuilderConcrete();
|
|
// act
|
|
sut.appendLine(code);
|
|
// assert
|
|
const result = sut.toString();
|
|
const lines = splitTextIntoLines(result);
|
|
expect(lines).to.have.lengthOf(2);
|
|
expect(lines[0]).to.equal(line1);
|
|
expect(lines[1]).to.equal(line2);
|
|
});
|
|
}
|
|
});
|
|
it('normalizes different line terminators', () => {
|
|
// arrange
|
|
const lineTerminator = 'ðŸ’';
|
|
const lines = ['line1', 'line2', 'line3', 'line4'];
|
|
const code = `${lines[0]}\n${lines[1]}\r\n${lines[2]}\r${lines[3]}`;
|
|
const expected = `${lines[0]}${lineTerminator}${lines[1]}${lineTerminator}${lines[2]}${lineTerminator}${lines[3]}`;
|
|
const sut = new CodeBuilderConcrete()
|
|
.withNewLineTerminator(lineTerminator);
|
|
// act
|
|
const actual = sut
|
|
.appendLine(code)
|
|
.toString();
|
|
// assert
|
|
expect(actual).to.equal(expected);
|
|
});
|
|
});
|
|
});
|
|
it('appendFunction', () => {
|
|
// arrange
|
|
const sut = new CodeBuilderConcrete();
|
|
const functionName = 'expected-function-name';
|
|
const code = 'expected-code';
|
|
// act
|
|
sut.appendFunction(functionName, code);
|
|
// assert
|
|
const result = sut.toString();
|
|
expect(result).to.include(functionName);
|
|
expect(result).to.include(code);
|
|
});
|
|
it('appendTrailingHyphensCommentLine', () => {
|
|
// arrange
|
|
const commentDelimiter = '//';
|
|
const sut = new CodeBuilderConcrete()
|
|
.withCommentDelimiter(commentDelimiter);
|
|
const totalHyphens = 5;
|
|
const expected = `${commentDelimiter} ${'-'.repeat(totalHyphens)}`;
|
|
// act
|
|
sut.appendTrailingHyphensCommentLine(totalHyphens);
|
|
// assert
|
|
const result = sut.toString();
|
|
const lines = splitTextIntoLines(result);
|
|
expect(lines[0]).to.equal(expected);
|
|
});
|
|
it('appendCommentLine', () => {
|
|
// arrange
|
|
const commentDelimiter = '//';
|
|
const sut = new CodeBuilderConcrete()
|
|
.withCommentDelimiter(commentDelimiter);
|
|
const comment = 'comment';
|
|
const expected = `${commentDelimiter} comment`;
|
|
// act
|
|
const result = sut
|
|
.appendCommentLine(comment)
|
|
.toString();
|
|
// assert
|
|
const lines = splitTextIntoLines(result);
|
|
expect(lines[0]).to.equal(expected);
|
|
});
|
|
it('appendCommentLineWithHyphensAround', () => {
|
|
// arrange
|
|
const commentDelimiter = '//';
|
|
const sut = new CodeBuilderConcrete()
|
|
.withCommentDelimiter(commentDelimiter);
|
|
const sectionName = 'section';
|
|
const totalHyphens = sectionName.length + 3 * 2;
|
|
const expected = `${commentDelimiter} ---section---`;
|
|
// act
|
|
const result = sut
|
|
.appendCommentLineWithHyphensAround(sectionName, totalHyphens)
|
|
.toString();
|
|
// assert
|
|
const lines = splitTextIntoLines(result);
|
|
expect(lines[1]).to.equal(expected);
|
|
});
|
|
describe('currentLine', () => {
|
|
it('no lines returns zero', () => {
|
|
// arrange & act
|
|
const sut = new CodeBuilderConcrete();
|
|
// assert
|
|
expect(sut.currentLine).to.equal(0);
|
|
});
|
|
it('single line returns one', () => {
|
|
// arrange
|
|
const sut = new CodeBuilderConcrete();
|
|
// act
|
|
sut.appendLine();
|
|
// assert
|
|
expect(sut.currentLine).to.equal(1);
|
|
});
|
|
it('multiple lines returns as expected', () => {
|
|
// arrange
|
|
const sut = new CodeBuilderConcrete();
|
|
// act
|
|
sut.appendLine('1')
|
|
.appendCommentLine('2')
|
|
.appendLine();
|
|
// assert
|
|
expect(sut.currentLine).to.equal(3);
|
|
});
|
|
it('multiple lines in code', () => {
|
|
// arrange
|
|
const sut = new CodeBuilderConcrete();
|
|
// act
|
|
sut.appendLine('hello\ncode-here\nwith-3-lines');
|
|
// assert
|
|
expect(sut.currentLine).to.equal(3);
|
|
});
|
|
});
|
|
});
|