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

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

View File

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

View File

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

View File

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

View File

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