Skip to content

Commit

Permalink
Adding unit tests for ini/config.
Browse files Browse the repository at this point in the history
  • Loading branch information
Neloreck committed Jun 25, 2023
1 parent 1085f5a commit abd6e94
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 23 deletions.
114 changes: 109 additions & 5 deletions src/engine/core/utils/ini/config.test.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,123 @@
import { describe, expect, it } from "@jest/globals";

import { registerStoryLink } from "@/engine/core/database";
import { registerActor, registerObject, registerStoryLink } from "@/engine/core/database";
import { IBaseSchemeLogic } from "@/engine/core/schemes";
import { giveInfo } from "@/engine/core/utils/info_portion";
import {
addConditionToList,
getConfigObjectAndZone,
getConfigSwitchConditions,
getParametersString,
getObjectConfigOverrides,
getSectionsFromConditionLists,
parseConditionsList,
} from "@/engine/core/utils/ini";
import { LuaArray, ServerObject, TIndex } from "@/engine/lib/types";
import { NIL } from "@/engine/lib/constants/words";
import { ClientObject, LuaArray, ServerObject, TIndex } from "@/engine/lib/types";
import { mockBaseSchemeLogic } from "@/fixtures/engine";
import { mockIniFile, mockServerAlifeObject } from "@/fixtures/xray";
import { mockActorClientGameObject, mockClientGameObject, mockIniFile, mockServerAlifeObject } from "@/fixtures/xray";

describe("'config' utils for ini file", () => {
it("'addCondition' util should fill table and return new index", () => {
it("getInfosFromData should correctly parse data list of condition lists", () => {
registerActor(mockActorClientGameObject());
giveInfo("test");

expect(getSectionsFromConditionLists(mockClientGameObject(), "a|b|c")).toEqualLuaArrays(["a", "b", "c"]);
expect(getSectionsFromConditionLists(mockClientGameObject(), "a|{+not_existing}b,c|{+test}d,e")).toEqualLuaArrays([
"a",
"c",
"d",
]);
});

it("getConfigObjectAndZone should correctly parse story id and zone pair", () => {
const serverObject: ServerObject = mockServerAlifeObject();

registerStoryLink(serverObject.id, "zat_cop_id");

expect(
getConfigObjectAndZone(
mockIniFile("test.ltx", {
test: {
key: "zat_cop_id|zat_b38_actor_jump_down|{+a -b}walker@get_out",
},
}),
"test",
"key"
)
).toEqualLuaTables({
condlist: parseConditionsList("{+a -b} walker@get_out"),
name: "key",
npc_id: 100000,
v1: "zat_cop_id",
v2: "zat_b38_actor_jump_down",
});
});

it("getObjectConfigOverrides should correctly parse overrides", () => {
const object: ClientObject = mockClientGameObject();

registerObject(object);

expect(getObjectConfigOverrides(mockIniFile("test.ltx", { empty: {} }), "empty", object)).toEqualLuaTables({
combat_ignore: null,
combat_ignore_keep_when_attacked: false,
combat_type: null,
max_post_combat_time: 10,
min_post_combat_time: 5,
on_combat: null,
on_offline_condlist: parseConditionsList(NIL),
soundgroup: null,
});

expect(
getObjectConfigOverrides(
mockIniFile("test.ltx", {
empty: {
heli_hunter: "first",
combat_ignore_cond: "second",
combat_ignore_keep_when_attacked: "third",
combat_type: "fourth",
on_combat: "fifth",
post_combat_time: "10, 50",
on_offline: "sixth",
soundgroup: "seventh",
},
}),
"empty",
object
)
).toEqualLuaTables({
combat_ignore: {
condlist: parseConditionsList("second"),
name: "combat_ignore_cond",
npc_id: null,
v1: null,
v2: null,
},
combat_ignore_keep_when_attacked: "third",
combat_type: {
condlist: parseConditionsList("fourth"),
name: "combat_type",
npc_id: null,
v1: null,
v2: null,
},
heli_hunter: parseConditionsList("first"),
max_post_combat_time: 50,
min_post_combat_time: 10,
on_combat: {
condlist: parseConditionsList("fifth"),
name: "on_combat",
npc_id: null,
v1: null,
v2: null,
},
on_offline_condlist: parseConditionsList("sixth"),
soundgroup: "seventh",
});
});

it("addCondition util should fill table and return new index", () => {
const list: LuaArray<IBaseSchemeLogic> = new LuaTable();

expect(addConditionToList(list, 1, null)).toBe(1);
Expand Down
35 changes: 21 additions & 14 deletions src/engine/core/utils/ini/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,21 @@ import {
TIndex,
TName,
TProbability,
TRate,
TSection,
TStringId,
} from "@/engine/lib/types";

const logger: LuaLogger = new LuaLogger($filename);

/**
* todo;
* todo: Probably not used anywhere, check. Original regexp - "(%|*[^%|]+%|*)%p*".
*
* Parse array of `|` separated condition lists.
* Original regexp - "(%|*[^%|]+%|*)%p*".
*
* @param object - target client object
* @param data - target data list string to parse
* @returns parsed list of sections from processed condition lists
*/
export function getInfosFromData(object: ClientObject, data: Optional<string>): LuaArray<TInfoPortion> {
export function getSectionsFromConditionLists(object: ClientObject, data: Optional<string>): LuaArray<TInfoPortion> {
const infos: LuaArray<TInfoPortion> = new LuaTable();
const actor: ClientObject = registry.actor;

Expand Down Expand Up @@ -175,17 +176,21 @@ export function pickSectionFromCondList<T extends TSection>(
}

/**
* todo;
* todo;
* todo;
* Parse config field containing zone name, story ID and condlist.
* Example: `zat_cop_id|zat_b38_actor_jump_down|walker@get_out`.
*
* @param ini - target ini file to read
* @param section - target section to read
* @param field - section field name to read
* @returns parse scheme logic descriptor
*/
export function getConfigObjectAndZone(ini: IniFile, section: TSection, field: TName): Optional<IBaseSchemeLogic> {
const target: Optional<IBaseSchemeLogic> = readIniTwoStringsAndConditionsList(ini, section, field);

if (target !== null) {
if (target) {
const simulator: Optional<AlifeSimulator> = alife();

if (simulator !== null) {
if (simulator) {
const serverObject: Optional<ServerObject> = simulator.object(getObjectIdByStoryId(target.v1 as string)!);

if (serverObject) {
Expand All @@ -202,10 +207,12 @@ export function getConfigObjectAndZone(ini: IniFile, section: TSection, field: T
}

/**
* todo;
* todo;
* todo;
* todo;
* Get config overrides from object logics section.
*
* @param ini - target ini file
* @param section - section name to read from ini file
* @param object - target client object
* @returns overrides object
*/
export function getObjectConfigOverrides(ini: IniFile, section: TSection, object: ClientObject): AnyObject {
const overrides: AnyObject = {};
Expand Down
14 changes: 10 additions & 4 deletions src/engine/core/utils/object/object_general.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { IRegistryObjectState, registry } from "@/engine/core/database";
import { AnomalyZoneBinder, SmartTerrain } from "@/engine/core/objects";
import { Squad } from "@/engine/core/objects/server/squad/Squad";
import { EStalkerState } from "@/engine/core/objects/state";
import { assert, assertDefined } from "@/engine/core/utils/assertion";
import { assertDefined } from "@/engine/core/utils/assertion";
import { isCseAlifeObject, isStalker } from "@/engine/core/utils/check/is";
import { getInfosFromData, pickSectionFromCondList } from "@/engine/core/utils/ini/config";
import { getSectionsFromConditionLists, pickSectionFromCondList } from "@/engine/core/utils/ini/config";
import { parseConditionsList } from "@/engine/core/utils/ini/parse";
import { readIniBoolean, readIniNumber, readIniString } from "@/engine/core/utils/ini/read";
import { TConditionList } from "@/engine/core/utils/ini/types";
Expand Down Expand Up @@ -281,8 +281,14 @@ export function areObjectsOnSameLevel(first: ServerObject, second: ServerObject)
* todo;
*/
export function setObjectInfo(object: ClientObject, ini: IniFile, section: TSection): void {
const inInfosList: LuaArray<TInfoPortion> = getInfosFromData(object, readIniString(ini, section, "in", false, ""));
const outInfosList: LuaArray<TInfoPortion> = getInfosFromData(object, readIniString(ini, section, "out", false, ""));
const inInfosList: LuaArray<TInfoPortion> = getSectionsFromConditionLists(
object,
readIniString(ini, section, "in", false, "")
);
const outInfosList: LuaArray<TInfoPortion> = getSectionsFromConditionLists(
object,
readIniString(ini, section, "out", false, "")
);

for (const [index, infoPortion] of inInfosList) {
object.give_info_portion(infoPortion);
Expand Down

0 comments on commit abd6e94

Please sign in to comment.