Create new Gamesystem
Some checks failed
E2E Testing / test (push) Failing after 1m30s

This commit is contained in:
Sebastian Böckelmann 2024-02-10 10:11:07 +01:00
parent b09e9351e0
commit 8411d69bce
10 changed files with 221 additions and 52 deletions

View File

@ -57,7 +57,7 @@ function createWindow(): BrowserWindow {
{ {
label: "Gamesystem", label: "Gamesystem",
click: () => { click: () => {
win!.webContents.send('context-menu', "new-location"); win!.webContents.send('context-menu', "new-gamesystem");
} }
}, },
{ {

View File

@ -0,0 +1,53 @@
import { BrowserContext, ElectronApplication, Page, _electron as electron } from 'playwright';
import { test, expect } from '@playwright/test';
import * as PATH from 'path';
import {GameModel} from "../../../src/app/game-model/GameModel";
import {Gamesystem} from "../../src/app/game-model/gamesystems/Gamesystem";
import {ScriptAccount} from "../../../src/app/game-model/scriptAccounts/ScriptAccount";
import {ModelComponentType} from "../../../src/app/game-model/ModelComponentType";
import {SimpleGamesystem} from "../../../src/app/game-model/gamesystems/SimpleGamesystem";
import exp = require("node:constants");
import {end} from "electron-debug";
import {GamesystemTrainer} from "./GamesystemTrainer";
import {ProductGamesystem} from "../../../src/app/game-model/gamesystems/ProductGamesystem";
test.describe('Test Create Gamesystems', () => {
test('Test creating gamesystem with invalid name', async => {
const gameModel = GamesystemTrainer.givenEmptyGameModel();
let result = gameModel.createGamesystem(undefined, undefined);
expect(result).toBeUndefined();
result = gameModel.createGamesystem(null, undefined);
expect(result).toBeUndefined();
})
test("Test creating gamesystem with valid name but without parent", async => {
const gameModel = GamesystemTrainer.givenEmptyGameModel();
let result = gameModel.createGamesystem(GamesystemTrainer.SIMPLEGAMESYSTEMNAME, undefined);
expect(result).toBeDefined();
expect(gameModel.gamesystems.length).toEqual(1);
expect(gameModel.findGamesystem(GamesystemTrainer.SIMPLEGAMESYSTEMNAME)).toBeDefined();
})
test("Test creating Gamesystem with valid name but with Product Parent", async => {
const gameModel = GamesystemTrainer.givenGameModelWithProductGamesytemOnTopLayer();
let result = gameModel.createGamesystem(GamesystemTrainer.SIMPLEGAMESYSTEM_LEAF_LEFT, GamesystemTrainer.TOP_PRODUCT_GAMESYSTEM_NAME);
expect(result).toBeDefined();
expect(result.parentGamesystem!.componentName).toEqual(GamesystemTrainer.TOP_PRODUCT_GAMESYSTEM_NAME);
expect(result.parentGamesystem!.innerGamesystems.length).toEqual(3);
expect(result.parentGamesystem!.innerGamesystems.includes(result)).toBeTruthy();
})
test("Test creating Gamesystem with valid name but with Simple Parent", async() => {
const gameModel = GamesystemTrainer.givenGameModelWithSimpleGamesystemOnTopLayer();
let result = gameModel.createGamesystem(GamesystemTrainer.SIMPLEGAMESYSTEM_LEAF_LEFT, GamesystemTrainer.SIMPLEGAMESYSTEMNAME);
expect(result).toBeDefined();
expect(gameModel.gamesystems.length).toEqual(1);
expect(gameModel.gamesystems[0]).toBeInstanceOf(ProductGamesystem);
expect(gameModel.gamesystems[0]).toEqual(result.parentGamesystem);
expect((gameModel.gamesystems[0] as ProductGamesystem).innerGamesystems.length).toEqual(1);
expect((gameModel.gamesystems[0] as ProductGamesystem).innerGamesystems.includes(result)).toBeTruthy();
})
});

View File

@ -9,6 +9,9 @@ export class GamesystemTrainer {
static TOP_PRODUCT_GAMESYSTEM_NAME: string = "Top Product Gamesystem" static TOP_PRODUCT_GAMESYSTEM_NAME: string = "Top Product Gamesystem"
static SIMPLEGAMESYSTEM2: string = "Simple Gamesystem Leaf 2"; static SIMPLEGAMESYSTEM2: string = "Simple Gamesystem Leaf 2";
static SIMPLEGAMESYSTEM_LEAF_LEFT: string = "Leaf Gamesystem Left"
static SIMPLEGAMESYSTEM_LEAF_RIGHT: string = "Leaf Gamesystem Right";
static givenEmptyGameModel() { static givenEmptyGameModel() {
return new GameModel(GamesystemTrainer.GAMEMODELNAME); return new GameModel(GamesystemTrainer.GAMEMODELNAME);
} }
@ -33,5 +36,20 @@ export class GamesystemTrainer {
return gameModel; return gameModel;
} }
static givenGameModelWithProductGamesystemOnLowerLayer() {
const gameModel = new GameModel(GamesystemTrainer.GAMEMODELNAME);
const top_productGamesystem = new ProductGamesystem(this.TOP_PRODUCT_GAMESYSTEM_NAME);
const leaf1 = new ProductGamesystem(this.SIMPLEGAMESYSTEMNAME);
const leaf2 = new SimpleGamesystem(this.SIMPLEGAMESYSTEM2);
top_productGamesystem.innerGamesystems.push(leaf1);
top_productGamesystem.innerGamesystems.push(leaf2);
gameModel.addGamesystem(top_productGamesystem);
const leaf_1_1 = new SimpleGamesystem(this.SIMPLEGAMESYSTEM_LEAF_LEFT);
leaf1.addChildGamesystem(leaf_1_1);
const leaf_1_2 = new SimpleGamesystem(this.SIMPLEGAMESYSTEM_LEAF_RIGHT);
leaf1.addChildGamesystem(leaf_1_2);
}
} }

View File

@ -21,24 +21,24 @@ test.describe('Test ScriptAccounts', () => {
test("Test Adding ScriptAccounts", async () => { test("Test Adding ScriptAccounts", async () => {
const gameModel: GameModel = new GameModel("GameModel"); const gameModel: GameModel = new GameModel("GameModel");
let scriptAccount =gameModel.addScriptAccount("ScriptAccount"); let scriptAccount =gameModel.createScriptAccount("ScriptAccount");
expect(scriptAccount).toBeDefined(); expect(scriptAccount).toBeDefined();
expect(gameModel.scriptAccounts.length).toEqual(1); expect(gameModel.scriptAccounts.length).toEqual(1);
expect(gameModel.scriptAccounts.includes(scriptAccount)).toBeTruthy(); expect(gameModel.scriptAccounts.includes(scriptAccount)).toBeTruthy();
//Test adding scriptAccount with already existing name //Test adding scriptAccount with already existing name
const scriptAccount2 = gameModel.addScriptAccount("ScriptAccount") const scriptAccount2 = gameModel.createScriptAccount("ScriptAccount")
expect(scriptAccount2).toBeUndefined(); expect(scriptAccount2).toBeUndefined();
expect(gameModel.scriptAccounts.length).toEqual(1); expect(gameModel.scriptAccounts.length).toEqual(1);
//Test for adding invalid names as scriptaccount names (null/undefined/empty) //Test for adding invalid names as scriptaccount names (null/undefined/empty)
let result = gameModel.addScriptAccount(null); let result = gameModel.createScriptAccount(null);
expect(result).toBeUndefined(); expect(result).toBeUndefined();
expect(gameModel.scriptAccounts.length).toEqual(1); expect(gameModel.scriptAccounts.length).toEqual(1);
result = gameModel.addScriptAccount(undefined); result = gameModel.createScriptAccount(undefined);
expect(result).toBeUndefined(); expect(result).toBeUndefined();
expect(gameModel.scriptAccounts.length).toEqual(1); expect(gameModel.scriptAccounts.length).toEqual(1);
result = gameModel.addScriptAccount(""); result = gameModel.createScriptAccount("");
expect(result).toBeUndefined(); expect(result).toBeUndefined();
expect(gameModel.scriptAccounts.length).toEqual(1); expect(gameModel.scriptAccounts.length).toEqual(1);
}) })
@ -50,7 +50,7 @@ test.describe('Test ScriptAccounts', () => {
gameModel.removeScriptAccount(scriptAccount); gameModel.removeScriptAccount(scriptAccount);
expect(gameModel.scriptAccounts.length).toEqual(0); expect(gameModel.scriptAccounts.length).toEqual(0);
scriptAccount = gameModel.addScriptAccount("ScriptAccount"); scriptAccount = gameModel.createScriptAccount("ScriptAccount");
gameModel.removeScriptAccount(scriptAccount); gameModel.removeScriptAccount(scriptAccount);
expect(gameModel.scriptAccounts.length).toEqual(0); expect(gameModel.scriptAccounts.length).toEqual(0);
@ -60,8 +60,8 @@ test.describe('Test ScriptAccounts', () => {
gameModel.removeScriptAccount(null); gameModel.removeScriptAccount(null);
expect(gameModel.scriptAccounts.length).toEqual(0); expect(gameModel.scriptAccounts.length).toEqual(0);
scriptAccount = gameModel.addScriptAccount(scriptAccount); scriptAccount = gameModel.createScriptAccount(scriptAccount);
let scriptAccount2 = gameModel.addScriptAccount("ScriptAccount 2"); let scriptAccount2 = gameModel.createScriptAccount("ScriptAccount 2");
gameModel.removeScriptAccount(scriptAccount); gameModel.removeScriptAccount(scriptAccount);
expect(gameModel.scriptAccounts.length).toEqual(1); expect(gameModel.scriptAccounts.length).toEqual(1);

View File

@ -45,11 +45,39 @@ export class AppComponent implements OnInit{
electronService.ipcRenderer.on('context-menu', (event: any, message: string) => { electronService.ipcRenderer.on('context-menu', (event: any, message: string) => {
this.zone.run(() => { this.zone.run(() => {
this.onContextMenuMessageRecieved(message);
});
})
} else {
console.log('Run in browser');
}
}
onContextMenuMessageRecieved(message: string) {
if(message == "edit") { if(message == "edit") {
this.onEditModelComponent();
} else if(message == "delete") {
this.onDeleteModelComponent();
} else if(message.startsWith("new")) {
const splittedMessage = message.split("-");
const modelComponentType = ModelComponentTypeUtillities.fromString(splittedMessage[1]);
if(modelComponentType != undefined) {
this.onCreateModelComponent(modelComponentType);
} else {
console.log("[ERROR] [App-Component] Unknown Context-Menu Command!")
}
}
}
private onEditModelComponent() {
if(this.openContent == ModelComponentType.SCRIPTACCOUNT && this.scriptAccountOverview != undefined && this.scriptAccountOverview.selectedScriptAccount != undefined) { if(this.openContent == ModelComponentType.SCRIPTACCOUNT && this.scriptAccountOverview != undefined && this.scriptAccountOverview.selectedScriptAccount != undefined) {
this.editor!.openGameModelComponent(this.scriptAccountOverview.selectedScriptAccount!); this.editor!.openGameModelComponent(this.scriptAccountOverview.selectedScriptAccount!);
} else {
//Erweitere to Gamesystems
} }
} else if(message == "delete") { }
private onDeleteModelComponent() {
const affectedModelComponent = this.getSelectedModelComponent(); const affectedModelComponent = this.getSelectedModelComponent();
const dialogRef = this.dialog.open(DeleteConfirmationDialogComponent, {data: affectedModelComponent, minWidth: "400px"}); const dialogRef = this.dialog.open(DeleteConfirmationDialogComponent, {data: affectedModelComponent, minWidth: "400px"});
@ -61,13 +89,34 @@ export class AppComponent implements OnInit{
} }
}) })
} }
})
}) private onCreateModelComponent(modelComponentType: ModelComponentType) {
} else { switch (modelComponentType) {
console.log('Run in browser'); case ModelComponentType.SCRIPTACCOUNT: this.onCreateNewScriptAccount(); break
case ModelComponentType.GAMESYTEM: this.onCreateNewGamesystem(); break
} }
} }
private onCreateNewScriptAccount() {
const createdScriptAccount = this.gameModel!.createScriptAccount("New ScriptAccount");
if(createdScriptAccount != undefined) {
this.editor?.openGameModelComponent(createdScriptAccount);
} else {
console.log("[DEBUG] [App-Component] ScriptAccount could not be created (Name not unique)");
}
}
private onCreateNewGamesystem() {
let parentGamesystemName = undefined
if(this.openContent != ModelComponentType.GAMESYTEM) {
this.openGamesystemsOverview();
} else {
parentGamesystemName = this.gamesystemOverview!.selectedGamesystemName;
}
this.gameModel!.createGamesystem("New Gamesystem", parentGamesystemName);
this.gamesystemOverview!.refresh();
}
private getSelectedModelComponent(): ModelComponent | undefined { private getSelectedModelComponent(): ModelComponent | undefined {
if(this.openContent == ModelComponentType.SCRIPTACCOUNT) { if(this.openContent == ModelComponentType.SCRIPTACCOUNT) {
if(this.scriptAccountOverview != undefined) { if(this.scriptAccountOverview != undefined) {
@ -81,8 +130,8 @@ export class AppComponent implements OnInit{
ngOnInit() { ngOnInit() {
this.gameModel = new GameModel("No More"); this.gameModel = new GameModel("No More");
this.gameModel.addScriptAccount("Temperature"); this.gameModel.createScriptAccount("Temperature");
this.gameModel.addScriptAccount("Luftfeuchtigkeit"); this.gameModel.createScriptAccount("Luftfeuchtigkeit");
const weather = new SimpleGamesystem("Weather"); const weather = new SimpleGamesystem("Weather");
const season = new SimpleGamesystem("Season"); const season = new SimpleGamesystem("Season");
@ -120,7 +169,7 @@ export class AppComponent implements OnInit{
onModelNameUpdate() { onModelNameUpdate() {
if(this.openContent == ModelComponentType.GAMESYTEM) { if(this.openContent == ModelComponentType.GAMESYTEM) {
this.gamesystemOverview!.onUpdateModelName(); this.gamesystemOverview!.refresh();
} }
} }
} }

View File

@ -3,6 +3,7 @@ import {ScriptAccount} from "./scriptAccounts/ScriptAccount";
import {Transition} from "./gamesystems/Transition"; import {Transition} from "./gamesystems/Transition";
import {State} from "./gamesystems/State"; import {State} from "./gamesystems/State";
import {ProductGamesystem} from "./gamesystems/ProductGamesystem"; import {ProductGamesystem} from "./gamesystems/ProductGamesystem";
import {SimpleGamesystem} from "./gamesystems/SimpleGamesystem";
export class GameModel { export class GameModel {
private readonly _gameModelName: string private readonly _gameModelName: string
@ -24,16 +25,14 @@ export class GameModel {
} }
addGamesystem(gamesystem: Gamesystem<any, any>) { addGamesystem(gamesystem: Gamesystem<any, any>) {
if(!this.gamesystems.includes(gamesystem)) {
this._gamesystems.push(gamesystem); this._gamesystems.push(gamesystem);
} }
}
removeGamesystem(gamesystem : Gamesystem<any, any>) { removeGamesystem(gamesystem : Gamesystem<any, any>) {
this._gamesystems = this._gamesystems.filter(g => g !== gamesystem); this._gamesystems = this._gamesystems.filter(g => g !== gamesystem);
} }
addScriptAccount(scriptAccountName: string) { createScriptAccount(scriptAccountName: string) {
if(scriptAccountName != undefined && scriptAccountName.length > 0) { if(scriptAccountName != undefined && scriptAccountName.length > 0) {
const scriptAccount = new ScriptAccount(scriptAccountName, ""); const scriptAccount = new ScriptAccount(scriptAccountName, "");
const searchedScriptAccount = this.scriptAccounts.find(s => s.componentName === scriptAccount.componentName); const searchedScriptAccount = this.scriptAccounts.find(s => s.componentName === scriptAccount.componentName);
@ -45,6 +44,28 @@ export class GameModel {
return undefined; return undefined;
} }
createGamesystem(gamesystemName: string, parentGamesystemName: string | undefined) {
if(gamesystemName != undefined && this.findGamesystem(gamesystemName) == undefined) {
const simpleGamesystem = new SimpleGamesystem(gamesystemName);
if(parentGamesystemName != undefined) {
const parentGamesystem = this.findGamesystem(parentGamesystemName);
if(parentGamesystem instanceof SimpleGamesystem) {
const parentProductGamesystem = ProductGamesystem.constructFromSimpleGamesystem(parentGamesystem, this);
parentProductGamesystem.addChildGamesystem(simpleGamesystem);
simpleGamesystem.parentGamesystem = parentProductGamesystem;
} else {
const productParentGamesystem = parentGamesystem as ProductGamesystem;
productParentGamesystem.addChildGamesystem(simpleGamesystem);
simpleGamesystem.parentGamesystem = productParentGamesystem;
}
} else {
this.gamesystems.push(simpleGamesystem);
}
return simpleGamesystem;
}
}
removeScriptAccount(scriptAccount: ScriptAccount) { removeScriptAccount(scriptAccount: ScriptAccount) {
if(scriptAccount != undefined) { if(scriptAccount != undefined) {
this._scriptAccounts = this.scriptAccounts.filter(s => s != scriptAccount); this._scriptAccounts = this.scriptAccounts.filter(s => s != scriptAccount);

View File

@ -16,4 +16,12 @@ export class ModelComponentTypeUtillities {
default: return "Undefined"; default: return "Undefined";
} }
} }
static fromString(string: string) : ModelComponentType | undefined {
console.log(string)
switch (string) {
case "gamesystem": return ModelComponentType.GAMESYTEM;
case "scriptaccount": return ModelComponentType.SCRIPTACCOUNT;
}
}
} }

View File

@ -5,12 +5,34 @@ import {State} from "./State";
import {Transition} from "./Transition"; import {Transition} from "./Transition";
import {SimpleState} from "./SimpleState"; import {SimpleState} from "./SimpleState";
import {SimpleGamesystem} from "./SimpleGamesystem"; import {SimpleGamesystem} from "./SimpleGamesystem";
import {GameModel} from "../GameModel";
export class ProductGamesystem extends Gamesystem<ProductState, ProductTransition> { export class ProductGamesystem extends Gamesystem<ProductState, ProductTransition> {
innerGamesystems: SimpleGamesystem[] = []; innerGamesystems: Gamesystem<State<any>, Transition<any>>[] = [];
parentGamesystem: ProductGamesystem | undefined parentGamesystem: ProductGamesystem | undefined
static constructFromSimpleGamesystem(simpleGamesystem: SimpleGamesystem, gameModel: GameModel) {
const productGamesystem = new ProductGamesystem(simpleGamesystem.componentName);
const parentGamesystem = simpleGamesystem.parentGamesystem;
if(simpleGamesystem.states.length > 0) {
simpleGamesystem.componentName += "(Child)";
productGamesystem.addChildGamesystem(simpleGamesystem);
}
if(parentGamesystem != undefined) {
parentGamesystem.removeChildGamesystem(simpleGamesystem);
parentGamesystem.addChildGamesystem(productGamesystem);
} else {
gameModel.removeGamesystem(simpleGamesystem);
gameModel.addGamesystem(productGamesystem);
}
return productGamesystem;
}
createState(label: string, description: string): ProductState | undefined { createState(label: string, description: string): ProductState | undefined {
return undefined; return undefined;
} }
@ -28,5 +50,11 @@ export class ProductGamesystem extends Gamesystem<ProductState, ProductTransitio
} }
addChildGamesystem(gamesystem: Gamesystem<State<any>, Transition<any>>) {
this.innerGamesystems.push(gamesystem);
}
private removeChildGamesystem(gamesystem: Gamesystem<State<any>, Transition<any>>) {
this.innerGamesystems = this.innerGamesystems.filter(childSystem => childSystem != gamesystem);
}
} }

View File

@ -92,7 +92,15 @@ export class GamescriptOverviewComponent implements OnInit {
} }
} }
onUpdateModelName() { get selectedGamesystemName() {
if(this.selectedGamesystem == undefined) {
return undefined
} else {
return this.selectedGamesystem!.name
}
}
refresh() {
this.dataSource.data = this.gameModel!.gamesystems; this.dataSource.data = this.gameModel!.gamesystems;
} }
} }

View File

@ -14,17 +14,7 @@ export class ScriptAccountOverviewComponent {
selectedScriptAccount: ScriptAccount | undefined selectedScriptAccount: ScriptAccount | undefined
constructor(private electronService: ElectronService, constructor() {
private zone: NgZone) {
if(electronService.isElectron) {
this.electronService.ipcRenderer.on('context-menu', (event: any, message: string) => {
this.zone.run(() => {
if(message == "new-scriptaccount") {
this.onCreateNewScriptAccount()
}
})
})
}
} }
onOpenScriptAccount(scriptAccount: ScriptAccount) { onOpenScriptAccount(scriptAccount: ScriptAccount) {
@ -32,12 +22,6 @@ export class ScriptAccountOverviewComponent {
this.openScriptAccountEmitter.emit(scriptAccount); this.openScriptAccountEmitter.emit(scriptAccount);
} }
onCreateNewScriptAccount() {
const scriptAccount = this.gameModel!.addScriptAccount("New ScriptAccount");
if(scriptAccount != undefined) {
this.openScriptAccountEmitter.emit(scriptAccount);
}
}
selectScriptAccount(scriptAccount: ScriptAccount) { selectScriptAccount(scriptAccount: ScriptAccount) {