mirror of
https://github.com/Kvan7/Exiled-Exchange-2.git
synced 2025-12-14 20:15:51 +00:00
@@ -3,6 +3,8 @@ import { __testExports } from "@/parser/Parser";
|
|||||||
import { beforeEach, describe, expect, test } from "vitest";
|
import { beforeEach, describe, expect, test } from "vitest";
|
||||||
import { setupTests } from "@specs/vitest.setup";
|
import { setupTests } from "@specs/vitest.setup";
|
||||||
import {
|
import {
|
||||||
|
ArmourHighValueRareItem,
|
||||||
|
HighDamageRareItem,
|
||||||
MagicItem,
|
MagicItem,
|
||||||
NormalItem,
|
NormalItem,
|
||||||
RareItem,
|
RareItem,
|
||||||
@@ -10,6 +12,7 @@ import {
|
|||||||
UniqueItem,
|
UniqueItem,
|
||||||
} from "./items";
|
} from "./items";
|
||||||
import { loadForLang } from "@/assets/data";
|
import { loadForLang } from "@/assets/data";
|
||||||
|
import { ParsedItem } from "@/parser";
|
||||||
|
|
||||||
describe("itemTextToSections", () => {
|
describe("itemTextToSections", () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@@ -39,4 +42,100 @@ describe("itemTextToSections", () => {
|
|||||||
const sections = __testExports.itemTextToSections(RareWithImplicit.rawText);
|
const sections = __testExports.itemTextToSections(RareWithImplicit.rawText);
|
||||||
expect(sections.length).toBe(RareWithImplicit.sectionCount);
|
expect(sections.length).toBe(RareWithImplicit.sectionCount);
|
||||||
});
|
});
|
||||||
|
test("high damage rare item", () => {
|
||||||
|
const sections = __testExports.itemTextToSections(
|
||||||
|
HighDamageRareItem.rawText,
|
||||||
|
);
|
||||||
|
expect(sections.length).toBe(HighDamageRareItem.sectionCount);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("parseWeapon", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
setupTests();
|
||||||
|
await loadForLang("en");
|
||||||
|
});
|
||||||
|
test("Magic Weapon", () => {
|
||||||
|
const sections = __testExports.itemTextToSections(MagicItem.rawText);
|
||||||
|
const parsedItem = {} as ParsedItem;
|
||||||
|
|
||||||
|
const res = __testExports.parseWeapon(sections[1], parsedItem);
|
||||||
|
|
||||||
|
expect(res).toBe("SECTION_PARSED");
|
||||||
|
expect(parsedItem.weaponPHYSICAL).toBe(MagicItem.weaponPHYSICAL);
|
||||||
|
expect(parsedItem.weaponELEMENTAL).toBe(MagicItem.weaponELEMENTAL);
|
||||||
|
expect(parsedItem.weaponAS).toBe(MagicItem.weaponAS);
|
||||||
|
expect(parsedItem.weaponCRIT).toBe(MagicItem.weaponCRIT);
|
||||||
|
expect(parsedItem.weaponReload).toBe(MagicItem.weaponReload);
|
||||||
|
});
|
||||||
|
test("Rare Weapon", () => {
|
||||||
|
const sections = __testExports.itemTextToSections(RareItem.rawText);
|
||||||
|
const parsedItem = {} as ParsedItem;
|
||||||
|
|
||||||
|
const res = __testExports.parseWeapon(sections[1], parsedItem);
|
||||||
|
|
||||||
|
expect(res).toBe("SECTION_PARSED");
|
||||||
|
expect(parsedItem.weaponPHYSICAL).toBe(RareItem.weaponPHYSICAL);
|
||||||
|
expect(parsedItem.weaponELEMENTAL).toBe(RareItem.weaponELEMENTAL);
|
||||||
|
expect(parsedItem.weaponAS).toBe(RareItem.weaponAS);
|
||||||
|
expect(parsedItem.weaponCRIT).toBe(RareItem.weaponCRIT);
|
||||||
|
expect(parsedItem.weaponReload).toBe(RareItem.weaponReload);
|
||||||
|
});
|
||||||
|
test("High Damage Rare Weapon", () => {
|
||||||
|
const sections = __testExports.itemTextToSections(
|
||||||
|
HighDamageRareItem.rawText,
|
||||||
|
);
|
||||||
|
const parsedItem = {} as ParsedItem;
|
||||||
|
|
||||||
|
const res = __testExports.parseWeapon(sections[1], parsedItem);
|
||||||
|
|
||||||
|
expect(res).toBe("SECTION_PARSED");
|
||||||
|
expect(parsedItem.weaponPHYSICAL).toBe(HighDamageRareItem.weaponPHYSICAL);
|
||||||
|
expect(parsedItem.weaponELEMENTAL).toBe(HighDamageRareItem.weaponELEMENTAL);
|
||||||
|
expect(parsedItem.weaponAS).toBe(HighDamageRareItem.weaponAS);
|
||||||
|
expect(parsedItem.weaponCRIT).toBe(HighDamageRareItem.weaponCRIT);
|
||||||
|
expect(parsedItem.weaponReload).toBe(HighDamageRareItem.weaponReload);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("parseArmour", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
setupTests();
|
||||||
|
await loadForLang("en");
|
||||||
|
});
|
||||||
|
test("Normal Armour", () => {
|
||||||
|
const sections = __testExports.itemTextToSections(NormalItem.rawText);
|
||||||
|
const parsedItem = {} as ParsedItem;
|
||||||
|
|
||||||
|
const res = __testExports.parseArmour(sections[1], parsedItem);
|
||||||
|
|
||||||
|
expect(res).toBe("SECTION_PARSED");
|
||||||
|
expect(parsedItem.armourAR).toBe(NormalItem.armourAR);
|
||||||
|
expect(parsedItem.armourEV).toBe(NormalItem.armourEV);
|
||||||
|
expect(parsedItem.armourES).toBe(NormalItem.armourES);
|
||||||
|
});
|
||||||
|
test("Unique Armour", () => {
|
||||||
|
const sections = __testExports.itemTextToSections(UniqueItem.rawText);
|
||||||
|
const parsedItem = {} as ParsedItem;
|
||||||
|
|
||||||
|
const res = __testExports.parseArmour(sections[1], parsedItem);
|
||||||
|
|
||||||
|
expect(res).toBe("SECTION_PARSED");
|
||||||
|
expect(parsedItem.armourAR).toBe(UniqueItem.armourAR);
|
||||||
|
expect(parsedItem.armourEV).toBe(UniqueItem.armourEV);
|
||||||
|
expect(parsedItem.armourES).toBe(UniqueItem.armourES);
|
||||||
|
});
|
||||||
|
test("High Armour Rare", () => {
|
||||||
|
const sections = __testExports.itemTextToSections(
|
||||||
|
ArmourHighValueRareItem.rawText,
|
||||||
|
);
|
||||||
|
const parsedItem = {} as ParsedItem;
|
||||||
|
|
||||||
|
const res = __testExports.parseArmour(sections[1], parsedItem);
|
||||||
|
|
||||||
|
expect(res).toBe("SECTION_PARSED");
|
||||||
|
expect(parsedItem.armourAR).toBe(ArmourHighValueRareItem.armourAR);
|
||||||
|
expect(parsedItem.armourEV).toBe(ArmourHighValueRareItem.armourEV);
|
||||||
|
expect(parsedItem.armourES).toBe(ArmourHighValueRareItem.armourES);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ class TestItem implements ParsedItem {
|
|||||||
}
|
}
|
||||||
| undefined;
|
| undefined;
|
||||||
|
|
||||||
|
note?: string;
|
||||||
category?: ItemCategory | undefined;
|
category?: ItemCategory | undefined;
|
||||||
info: BaseType = {
|
info: BaseType = {
|
||||||
name: "test",
|
name: "test",
|
||||||
@@ -145,6 +146,7 @@ MagicItem.category = ItemCategory.TwoHandedMace;
|
|||||||
MagicItem.rarity = ItemRarity.Magic;
|
MagicItem.rarity = ItemRarity.Magic;
|
||||||
MagicItem.weaponPHYSICAL = 53.5;
|
MagicItem.weaponPHYSICAL = 53.5;
|
||||||
MagicItem.weaponLIGHTNING = 25.5;
|
MagicItem.weaponLIGHTNING = 25.5;
|
||||||
|
MagicItem.weaponELEMENTAL = MagicItem.weaponLIGHTNING;
|
||||||
MagicItem.weaponCRIT = 5;
|
MagicItem.weaponCRIT = 5;
|
||||||
MagicItem.weaponAS = 1.2;
|
MagicItem.weaponAS = 1.2;
|
||||||
MagicItem.itemLevel = 32;
|
MagicItem.itemLevel = 32;
|
||||||
@@ -187,6 +189,8 @@ RareItem.weaponCOLD = 11;
|
|||||||
RareItem.weaponLIGHTNING = 43.5;
|
RareItem.weaponLIGHTNING = 43.5;
|
||||||
RareItem.weaponELEMENTAL =
|
RareItem.weaponELEMENTAL =
|
||||||
RareItem.weaponFIRE + RareItem.weaponCOLD + RareItem.weaponLIGHTNING;
|
RareItem.weaponFIRE + RareItem.weaponCOLD + RareItem.weaponLIGHTNING;
|
||||||
|
RareItem.weaponAS = 1.2;
|
||||||
|
RareItem.weaponCRIT = 5;
|
||||||
RareItem.itemLevel = 80;
|
RareItem.itemLevel = 80;
|
||||||
|
|
||||||
RareItem.sectionCount = 5;
|
RareItem.sectionCount = 5;
|
||||||
@@ -340,3 +344,113 @@ UncutSupportGem.info = {
|
|||||||
|
|
||||||
UncutSupportGem.sectionCount = 5;
|
UncutSupportGem.sectionCount = 5;
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
|
// #region HighDamageRareItem
|
||||||
|
export const HighDamageRareItem = new TestItem(`Item Class: Crossbows
|
||||||
|
Rarity: Rare
|
||||||
|
Dragon Core
|
||||||
|
Siege Crossbow
|
||||||
|
--------
|
||||||
|
Quality: +29% (augmented)
|
||||||
|
Physical Damage: 414-1,043 (augmented)
|
||||||
|
Critical Hit Chance: 5.00%
|
||||||
|
Attacks per Second: 2.07 (augmented)
|
||||||
|
Reload Time: 0.60 (augmented)
|
||||||
|
--------
|
||||||
|
Requires: Level 79, 89 (unmet) Str, 89 Dex
|
||||||
|
--------
|
||||||
|
Sockets: S S
|
||||||
|
--------
|
||||||
|
Item Level: 82
|
||||||
|
--------
|
||||||
|
36% increased Physical Damage (rune)
|
||||||
|
--------
|
||||||
|
{ Implicit Modifier }
|
||||||
|
Grenade Skills Fire an additional Projectile (implicit)
|
||||||
|
--------
|
||||||
|
{ Prefix Modifier "Merciless" (Tier: 1) — Damage, Physical, Attack }
|
||||||
|
173(170-179)% increased Physical Damage
|
||||||
|
{ Prefix Modifier "Dictator's" (Tier: 1) — Damage, Physical, Attack }
|
||||||
|
78(75-79)% increased Physical Damage
|
||||||
|
+175(175-200) to Accuracy Rating
|
||||||
|
{ Prefix Modifier "Flaring" (Tier: 1) — Damage, Physical, Attack }
|
||||||
|
Adds 54(37-55) to 94(63-94) Physical Damage (desecrated)
|
||||||
|
{ Suffix Modifier "of Infamy" — Attack, Speed }
|
||||||
|
25(23-25)% increased Attack Speed (fractured)
|
||||||
|
{ Suffix Modifier "of the Sniper" (Tier: 1) }
|
||||||
|
+7 to Level of all Projectile Skills
|
||||||
|
{ Suffix Modifier "of Bursting" (Tier: 1) — Attack }
|
||||||
|
Loads 2 additional bolts
|
||||||
|
--------
|
||||||
|
Fractured Item
|
||||||
|
`);
|
||||||
|
HighDamageRareItem.category = ItemCategory.Crossbow;
|
||||||
|
HighDamageRareItem.rarity = ItemRarity.Rare;
|
||||||
|
HighDamageRareItem.weaponPHYSICAL = 728.5;
|
||||||
|
HighDamageRareItem.weaponAS = 2.07;
|
||||||
|
HighDamageRareItem.weaponCRIT = 5;
|
||||||
|
HighDamageRareItem.weaponReload = 0.6;
|
||||||
|
HighDamageRareItem.itemLevel = 82;
|
||||||
|
|
||||||
|
HighDamageRareItem.sectionCount = 9;
|
||||||
|
HighDamageRareItem.prefixCount = 3;
|
||||||
|
HighDamageRareItem.suffixCount = 3;
|
||||||
|
HighDamageRareItem.implicitCount = 1;
|
||||||
|
|
||||||
|
HighDamageRareItem.runeSockets = {
|
||||||
|
empty: 0,
|
||||||
|
current: 2,
|
||||||
|
normal: 2,
|
||||||
|
};
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region ArmourHighValueRareItem
|
||||||
|
export const ArmourHighValueRareItem = new TestItem(`Item Class: Body Armours
|
||||||
|
Rarity: Rare
|
||||||
|
Hate Pelt
|
||||||
|
Soldier Cuirass
|
||||||
|
--------
|
||||||
|
Quality: +20% (augmented)
|
||||||
|
Armour: 3075 (augmented)
|
||||||
|
--------
|
||||||
|
Requires: Level 65, 121 (unmet) Str
|
||||||
|
--------
|
||||||
|
Sockets: S S S
|
||||||
|
--------
|
||||||
|
Item Level: 80
|
||||||
|
--------
|
||||||
|
54% increased Armour, Evasion and Energy Shield (rune)
|
||||||
|
--------
|
||||||
|
{ Prefix Modifier "Impenetrable" (Tier: 1) — Defences }
|
||||||
|
103(101-110)% increased Armour
|
||||||
|
{ Prefix Modifier "Hardened" (Tier: 1) — Defences }
|
||||||
|
+70(70-86) to Armour
|
||||||
|
41(39-42)% increased Armour
|
||||||
|
{ Prefix Modifier "Unmoving" (Tier: 2) — Defences }
|
||||||
|
+256(226-256) to Armour (desecrated)
|
||||||
|
{ Suffix Modifier "of the Titan" (Tier: 1) — Attribute }
|
||||||
|
+32(31-33) to Strength
|
||||||
|
{ Suffix Modifier "of Allaying" (Tier: 3) — Physical, Ailment }
|
||||||
|
48(50-46)% reduced Duration of Bleeding on You
|
||||||
|
{ Suffix Modifier "of the Essence" (Tier: 1) }
|
||||||
|
Hits against you have 44(40-50)% reduced Critical Damage Bonus
|
||||||
|
--------
|
||||||
|
Note: ~b/o 10 divine
|
||||||
|
`);
|
||||||
|
ArmourHighValueRareItem.category = ItemCategory.BodyArmour;
|
||||||
|
ArmourHighValueRareItem.rarity = ItemRarity.Rare;
|
||||||
|
ArmourHighValueRareItem.armourAR = 3075;
|
||||||
|
ArmourHighValueRareItem.itemLevel = 80;
|
||||||
|
|
||||||
|
ArmourHighValueRareItem.sectionCount = 8;
|
||||||
|
ArmourHighValueRareItem.prefixCount = 3;
|
||||||
|
ArmourHighValueRareItem.suffixCount = 3;
|
||||||
|
ArmourHighValueRareItem.implicitCount = 1;
|
||||||
|
|
||||||
|
ArmourHighValueRareItem.runeSockets = {
|
||||||
|
empty: 0,
|
||||||
|
current: 3,
|
||||||
|
normal: 2,
|
||||||
|
};
|
||||||
|
ArmourHighValueRareItem.note = "~b/o 10 divine";
|
||||||
|
// #endregion
|
||||||
|
|||||||
@@ -729,11 +729,13 @@ function parseWeapon(section: string[], item: ParsedItem) {
|
|||||||
|
|
||||||
for (const line of section) {
|
for (const line of section) {
|
||||||
if (line.startsWith(_$.CRIT_CHANCE)) {
|
if (line.startsWith(_$.CRIT_CHANCE)) {
|
||||||
|
// No regex since it can have decimals
|
||||||
item.weaponCRIT = parseFloat(line.slice(_$.CRIT_CHANCE.length));
|
item.weaponCRIT = parseFloat(line.slice(_$.CRIT_CHANCE.length));
|
||||||
isParsed = "SECTION_PARSED";
|
isParsed = "SECTION_PARSED";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (line.startsWith(_$.ATTACK_SPEED)) {
|
if (line.startsWith(_$.ATTACK_SPEED)) {
|
||||||
|
// No regex since it can have decimals
|
||||||
item.weaponAS = parseFloat(line.slice(_$.ATTACK_SPEED.length));
|
item.weaponAS = parseFloat(line.slice(_$.ATTACK_SPEED.length));
|
||||||
isParsed = "SECTION_PARSED";
|
isParsed = "SECTION_PARSED";
|
||||||
continue;
|
continue;
|
||||||
@@ -743,7 +745,7 @@ function parseWeapon(section: string[], item: ParsedItem) {
|
|||||||
line
|
line
|
||||||
.slice(_$.PHYSICAL_DAMAGE.length)
|
.slice(_$.PHYSICAL_DAMAGE.length)
|
||||||
.split(_$.HYPHEN)
|
.split(_$.HYPHEN)
|
||||||
.map((str) => parseInt(str, 10)),
|
.map((str) => parseInt(str.replace(/[^\d]/g, ""), 10)),
|
||||||
);
|
);
|
||||||
isParsed = "SECTION_PARSED";
|
isParsed = "SECTION_PARSED";
|
||||||
continue;
|
continue;
|
||||||
@@ -754,7 +756,9 @@ function parseWeapon(section: string[], item: ParsedItem) {
|
|||||||
.split(", ")
|
.split(", ")
|
||||||
.map((element) =>
|
.map((element) =>
|
||||||
getRollOrMinmaxAvg(
|
getRollOrMinmaxAvg(
|
||||||
element.split(_$.HYPHEN).map((str) => parseInt(str, 10)),
|
element
|
||||||
|
.split(_$.HYPHEN)
|
||||||
|
.map((str) => parseInt(str.replace(/[^\d]/g, ""), 10)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.reduce((sum, x) => sum + x, 0);
|
.reduce((sum, x) => sum + x, 0);
|
||||||
@@ -768,7 +772,9 @@ function parseWeapon(section: string[], item: ParsedItem) {
|
|||||||
.split(", ")
|
.split(", ")
|
||||||
.map((element) =>
|
.map((element) =>
|
||||||
getRollOrMinmaxAvg(
|
getRollOrMinmaxAvg(
|
||||||
element.split(_$.HYPHEN).map((str) => parseInt(str, 10)),
|
element
|
||||||
|
.split(_$.HYPHEN)
|
||||||
|
.map((str) => parseInt(str.replace(/[^\d]/g, ""), 10)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.reduce((sum, x) => sum + x, 0);
|
.reduce((sum, x) => sum + x, 0);
|
||||||
@@ -786,7 +792,9 @@ function parseWeapon(section: string[], item: ParsedItem) {
|
|||||||
.split(", ")
|
.split(", ")
|
||||||
.map((element) =>
|
.map((element) =>
|
||||||
getRollOrMinmaxAvg(
|
getRollOrMinmaxAvg(
|
||||||
element.split(_$.HYPHEN).map((str) => parseInt(str, 10)),
|
element
|
||||||
|
.split(_$.HYPHEN)
|
||||||
|
.map((str) => parseInt(str.replace(/[^\d]/g, ""), 10)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.reduce((sum, x) => sum + x, 0);
|
.reduce((sum, x) => sum + x, 0);
|
||||||
@@ -804,7 +812,9 @@ function parseWeapon(section: string[], item: ParsedItem) {
|
|||||||
.split(", ")
|
.split(", ")
|
||||||
.map((element) =>
|
.map((element) =>
|
||||||
getRollOrMinmaxAvg(
|
getRollOrMinmaxAvg(
|
||||||
element.split(_$.HYPHEN).map((str) => parseInt(str, 10)),
|
element
|
||||||
|
.split(_$.HYPHEN)
|
||||||
|
.map((str) => parseInt(str.replace(/[^\d]/g, ""), 10)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.reduce((sum, x) => sum + x, 0);
|
.reduce((sum, x) => sum + x, 0);
|
||||||
@@ -817,6 +827,7 @@ function parseWeapon(section: string[], item: ParsedItem) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (line.startsWith(_$.RELOAD_SPEED)) {
|
if (line.startsWith(_$.RELOAD_SPEED)) {
|
||||||
|
// No regex since it can have decimals
|
||||||
item.weaponReload = parseFloat(line.slice(_$.RELOAD_SPEED.length));
|
item.weaponReload = parseFloat(line.slice(_$.RELOAD_SPEED.length));
|
||||||
isParsed = "SECTION_PARSED";
|
isParsed = "SECTION_PARSED";
|
||||||
continue;
|
continue;
|
||||||
@@ -1688,4 +1699,6 @@ export const __testExports = {
|
|||||||
itemTextToSections,
|
itemTextToSections,
|
||||||
parseNamePlate,
|
parseNamePlate,
|
||||||
isUncutSkillGem,
|
isUncutSkillGem,
|
||||||
|
parseWeapon,
|
||||||
|
parseArmour,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user