-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add exclusive jobs tests. Splitting jobs utils.
- Loading branch information
Showing
5 changed files
with
306 additions
and
130 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
import { describe, expect, it, jest } from "@jest/globals"; | ||
import { getFS } from "xray16"; | ||
|
||
import { loadExclusiveJob } from "@/engine/core/utils/job/job_exclusive"; | ||
import { TJobDescriptor } from "@/engine/core/utils/job/types"; | ||
import { IniFile, LuaArray } from "@/engine/lib/types"; | ||
import { mockIniFile, registerIniFileMock } from "@/fixtures/xray"; | ||
|
||
describe("'job_exclusive' utils", () => { | ||
it("'loadExclusiveJob' should correctly handle empty ini", () => { | ||
const list: LuaArray<TJobDescriptor> = new LuaTable(); | ||
|
||
loadExclusiveJob(mockIniFile("text.ltx", {}), "a", "b", list); | ||
expect(list).toEqualLuaArrays([]); | ||
}); | ||
|
||
it("'loadExclusiveJob' should correctly throw if script does not exist", () => { | ||
const list: LuaArray<TJobDescriptor> = new LuaTable(); | ||
const ini: IniFile = mockIniFile("text.ltx", { | ||
smart_terrain: { | ||
work1: "some_file.ltx", | ||
}, | ||
}); | ||
|
||
jest.spyOn(getFS(), "exist").mockImplementation(() => 0); | ||
expect(() => loadExclusiveJob(ini, "smart_terrain", "work1", list)).toThrow(); | ||
}); | ||
|
||
it("'loadExclusiveJob' should correctly read if script does exist", () => { | ||
const list: LuaArray<TJobDescriptor> = new LuaTable(); | ||
const ini: IniFile = mockIniFile("text.ltx", { | ||
smart_terrain: { | ||
work1: "some_file2.ltx", | ||
}, | ||
}); | ||
const jobIni: IniFile = mockIniFile("scripts\\some_file2.ltx", {}); | ||
|
||
registerIniFileMock(jobIni); | ||
|
||
jest.spyOn(getFS(), "exist").mockImplementation(() => 1); | ||
|
||
expect(() => loadExclusiveJob(ini, "smart_terrain", "work1", list)).not.toThrow(); | ||
expect(list).toEqualLuaArrays([ | ||
{ | ||
_precondition_is_monster: false, | ||
job_id: { | ||
ini_file: expect.any(Object), | ||
ini_path: "scripts\\some_file2.ltx", | ||
job_type: null, | ||
online: null, | ||
section: "logic@work1", | ||
}, | ||
priority: 45, | ||
}, | ||
]); | ||
}); | ||
|
||
it("'loadExclusiveJob' should correctly read configured jobs without condlist", () => { | ||
const list: LuaArray<TJobDescriptor> = new LuaTable(); | ||
const ini: IniFile = mockIniFile("text.ltx", { | ||
smart_terrain: { | ||
work2: "some_file3.ltx", | ||
}, | ||
}); | ||
const jobIni: IniFile = mockIniFile("scripts\\some_file3.ltx", { | ||
"logic@work2": { | ||
prior: 101, | ||
monster_job: true, | ||
job_online: true, | ||
active: "animpoint@test1", | ||
}, | ||
}); | ||
|
||
registerIniFileMock(jobIni); | ||
|
||
jest.spyOn(getFS(), "exist").mockImplementation(() => 1); | ||
loadExclusiveJob(ini, "smart_terrain", "work2", list); | ||
|
||
expect(list).toEqualLuaArrays([ | ||
{ | ||
_precondition_is_monster: true, | ||
job_id: { | ||
ini_file: expect.any(Object), | ||
ini_path: "scripts\\some_file3.ltx", | ||
job_type: "smartcover_job", | ||
online: true, | ||
section: "logic@work2", | ||
}, | ||
priority: 101, | ||
}, | ||
]); | ||
}); | ||
|
||
it("'loadExclusiveJob' should correctly read configured jobs with condlist", () => { | ||
const list: LuaArray<TJobDescriptor> = new LuaTable(); | ||
const ini: IniFile = mockIniFile("text.ltx", { | ||
smart_terrain: { | ||
work2: "some_file3.ltx", | ||
}, | ||
}); | ||
const jobIni: IniFile = mockIniFile("scripts\\some_file3.ltx", { | ||
"logic@work2": { | ||
prior: 105, | ||
monster_job: false, | ||
suitable: "{+test_info} true, false", | ||
job_online: false, | ||
active: "patrol@test1", | ||
}, | ||
}); | ||
|
||
registerIniFileMock(jobIni); | ||
|
||
jest.spyOn(getFS(), "exist").mockImplementation(() => 1); | ||
loadExclusiveJob(ini, "smart_terrain", "work2", list); | ||
|
||
expect(list).toEqualLuaArrays([ | ||
{ | ||
_precondition_function: expect.any(Function), | ||
_precondition_is_monster: false, | ||
_precondition_params: { | ||
condlist: { | ||
"1": { | ||
infop_check: { | ||
"1": { | ||
name: "test_info", | ||
required: true, | ||
}, | ||
}, | ||
infop_set: {}, | ||
section: "true", | ||
}, | ||
"2": { | ||
infop_check: {}, | ||
infop_set: {}, | ||
section: "false", | ||
}, | ||
}, | ||
}, | ||
job_id: { | ||
ini_file: expect.any(Object), | ||
ini_path: "scripts\\some_file3.ltx", | ||
job_type: "path_job", | ||
online: false, | ||
section: "logic@work2", | ||
}, | ||
priority: 105, | ||
}, | ||
{ | ||
_precondition_is_monster: false, | ||
job_id: { | ||
ini_file: expect.any(Object), | ||
job_type: "path_job", | ||
section: "logic@work2", | ||
}, | ||
priority: -1, | ||
}, | ||
]); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import { getFS, ini_file } from "xray16"; | ||
|
||
import { registry } from "@/engine/core/database"; | ||
import { SmartTerrain } from "@/engine/core/objects"; | ||
import { assert } from "@/engine/core/utils/assertion"; | ||
import { | ||
getSchemeFromSection, | ||
parseConditionsList, | ||
pickSectionFromCondList, | ||
readIniBoolean, | ||
readIniNumber, | ||
readIniString, | ||
TConditionList, | ||
} from "@/engine/core/utils/ini"; | ||
import { IJobDescriptor, TJobDescriptor } from "@/engine/core/utils/job/types"; | ||
import { roots } from "@/engine/lib/constants/roots"; | ||
import { FALSE } from "@/engine/lib/constants/words"; | ||
import { | ||
AnyObject, | ||
EJobType, | ||
EScheme, | ||
IniFile, | ||
JobTypeByScheme, | ||
LuaArray, | ||
Optional, | ||
ServerHumanObject, | ||
TName, | ||
TPath, | ||
TRate, | ||
TSection, | ||
} from "@/engine/lib/types"; | ||
|
||
/** | ||
* Add jobs unique to terrain instance. | ||
*/ | ||
export function loadExclusiveJob( | ||
ini: IniFile, | ||
section: TSection, | ||
field: TSection, | ||
jobsList: LuaArray<TJobDescriptor> | ||
): void { | ||
const workScriptPath: Optional<TPath> = readIniString(ini, section, field, false, "", null); | ||
|
||
// Field with work path does not exist, nothing to load. | ||
if (workScriptPath === null) { | ||
return; | ||
} | ||
|
||
const iniPath: TPath = "scripts\\" + workScriptPath; | ||
|
||
assert(getFS().exist(roots.gameConfig, iniPath), "There is no job configuration file '%s'.", iniPath); | ||
|
||
const jobIniFile: Optional<IniFile> = new ini_file(iniPath); | ||
const jobOnline: Optional<string> = readIniString(jobIniFile, "logic@" + field, "job_online", false, "", null); | ||
const newPrior: TRate = readIniNumber(jobIniFile, "logic@" + field, "prior", false, 45); | ||
const jobSuitableCondlist: Optional<string> = readIniString(jobIniFile, "logic@" + field, "suitable", false, ""); | ||
const isMonster: boolean = readIniBoolean(jobIniFile, "logic@" + field, "monster_job", false, false); | ||
const activeSection: TSection = readIniString(jobIniFile, "logic@" + field, "active", false, ""); | ||
const scheme: Optional<EScheme> = getSchemeFromSection(activeSection) as EScheme; | ||
|
||
let jobType: Optional<EJobType> = (JobTypeByScheme[scheme] as EJobType) || null; | ||
|
||
if (scheme === EScheme.MOB_HOME && readIniBoolean(jobIniFile, activeSection, "gulag_point", false, false)) { | ||
jobType = EJobType.POINT_JOB; | ||
} | ||
|
||
// Add generic job placeholder if condlist is not defined, just combine ini parameters. | ||
if (jobSuitableCondlist === null) { | ||
const jobDescriptor: IJobDescriptor = { | ||
priority: newPrior, | ||
_precondition_is_monster: isMonster, | ||
job_id: { | ||
section: "logic@" + field, | ||
ini_path: iniPath, | ||
online: jobOnline, | ||
ini_file: jobIniFile, | ||
job_type: jobType as TName, | ||
}, | ||
}; | ||
|
||
table.insert(jobsList, jobDescriptor); | ||
} else { | ||
const conditionsList: TConditionList = parseConditionsList(jobSuitableCondlist); | ||
|
||
table.insert(jobsList, { | ||
priority: newPrior, | ||
_precondition_is_monster: isMonster, | ||
job_id: { | ||
section: "logic@" + field, | ||
ini_path: iniPath, | ||
ini_file: jobIniFile, | ||
online: jobOnline, | ||
job_type: jobType, | ||
}, | ||
_precondition_params: { condlist: conditionsList }, | ||
_precondition_function: ( | ||
serverObject: ServerHumanObject, | ||
smartTerrain: SmartTerrain, | ||
precondParams: AnyObject | ||
): boolean => { | ||
const result: Optional<string> = pickSectionFromCondList(registry.actor, serverObject, precondParams.condlist); | ||
|
||
return result !== FALSE && result !== null; | ||
}, | ||
}); | ||
|
||
// todo: Why is it needed with -1? | ||
table.insert(jobsList, { | ||
priority: -1, | ||
_precondition_is_monster: isMonster, | ||
job_id: { | ||
section: "logic@" + field, | ||
ini_file: jobIniFile, | ||
job_type: jobType, | ||
}, | ||
}); | ||
} | ||
} |
Oops, something went wrong.