poe-i18n
Version:
i18n utility for Path of Exile
314 lines (281 loc) • 8.98 kB
text/typescript
import { StatLocaleData } from '../../types/StatDescription';
import datas from '../../__fixtures__/english';
import formatStats, { Fallback, Stat } from '../stats';
it('should throw if the values dont match', () => {
expect(() =>
formatStats([{ id: 'weapon_physical_damage_+%', value: -1 }], { datas })
).toThrowError(
"matching translation not found for 'weapon_physical_damage_+%'"
);
});
it('should translate single stat line', () => {
expect(
formatStats([{ id: 'weapon_physical_damage_+%', value: 25 }], { datas })
).toEqual(['25% increased Physical Damage with Weapons']);
});
it('should fallback to deep search', () => {
const stats = [
{ id: 'attack_minimum_added_physical_damage', value: 5 },
{ id: 'attack_maximum_added_physical_damage', value: 13 }
];
const aliased_locale: StatLocaleData = {
meta: {},
data: {
aliased: {
stats: [
'attack_minimum_added_physical_damage',
'attack_maximum_added_physical_damage'
],
translations: [
{
matchers: ['#', '#'],
text: 'Adds %1% to %2% Physical Damage to Attacks',
formatters: []
}
]
}
}
};
expect(
formatStats(stats, { datas: { stat_descriptions: aliased_locale } })
).toEqual(['Adds 5 to 13 Physical Damage to Attacks']);
});
it('should throw if something was not translated', () => {
const stats = [
{ id: 'weapon_physical_damage_+%', value: 25 },
{ id: 'attack_minimum_added_physical_damage', value: 5 },
{ id: 'attack_maximum_added_physical_damage', value: 13 }
];
const aliased_locale: StatLocaleData = {
meta: {},
data: {
aliased: {
stats: [
'attack_minimum_added_physical_damage',
'attack_maximum_added_physical_damage'
],
translations: [
{
matchers: ['#', '#'],
text: 'Adds %1% to %2% Physical Damage to Attacks',
formatters: []
}
]
}
}
};
expect(() =>
formatStats(stats, { datas: { stat_descriptions: aliased_locale } })
).toThrowError('no descriptions found for weapon_physical_damage_+%');
});
it('should translate douple stat lines', () => {
expect(
formatStats(
[
{ id: 'attack_minimum_added_physical_damage', value: 1 },
{ id: 'attack_maximum_added_physical_damage', value: 56 }
],
{ datas }
)
).toEqual(['Adds 1 to 56 Physical Damage to Attacks']);
});
it('should translate collections of stats', () => {
const translated = formatStats(
[
{ id: 'attack_minimum_added_physical_damage', value: 20 },
{ id: 'attack_maximum_added_physical_damage', value: 300 },
{ id: 'item_generation_cannot_change_suffixes', value: -3 },
{ id: 'attack_speed_+%_while_leeching', value: -5 },
{ id: 'weapon_physical_damage_+%', value: 25 }
],
{ datas }
);
expect(translated).toContain('5% reduced Attack Speed while Leeching');
expect(translated).toContain('Adds 20 to 300 Physical Damage to Attacks');
expect(translated).toContain('Suffixes Cannot Be Changed');
expect(translated).toContain('25% increased Physical Damage with Weapons');
});
// they are save in the .txt with `no_description id`
it('should return the id with a hint for no_desc stats', () => {
expect(formatStats([{ id: 'item_drop_slots', value: 3 }], { datas })).toEqual(
['item_drop_slots (hidden)']
);
});
it('should translate production bug 1', () => {
// this one only threw because the translation was not provided which was
// fixed in 8d1cd8f8a1433a843e36250f893e64c72e98a005
expect(
formatStats(
[
{ id: 'additional_strength', value: 51 },
{ id: 'base_life_regeneration_rate_per_minute', value: 241 },
{ id: 'base_maximum_life', value: 24 },
{ id: 'local_base_physical_damage_reduction_rating', value: 24 }
],
{ datas }
).sort()
).toEqual([
'+24 to Armour',
'+24 to maximum Life',
'+51 to Strength',
'4 Life Regenerated per second'
]);
});
it('should translate if not enough stats are provided by defaulting to 0', () => {
// this is not a behavior that I like but to which I have to conform since
// the descriptions are provided that way in the .txt
// adding exception rules to every stat for which we default to 0 is just
// not a viable option
expect(
formatStats([{ id: 'attack_minimum_added_physical_damage', value: 1 }], {
datas
})
).toEqual(['Adds 1 to 0 Physical Damage to Attacks']);
expect(
formatStats([{ id: 'always_freeze', value: 1 }], { datas }).sort()
).toEqual(['Always Freezes Enemies on Hit']);
expect(
formatStats([{ id: 'base_chance_to_freeze_%', value: 12 }], {
datas
}).sort()
).toEqual(['12% chance to Freeze']);
});
it('should support id fallback', () => {
expect(
formatStats([{ id: 'from_armour_movement_speed_+%', value: -3 }], {
datas,
fallback: Fallback.id
})
).toEqual(['from_armour_movement_speed_+%']);
});
it('should support skipping fallback', () => {
expect(
formatStats([{ id: 'from_armour_movement_speed_+%', value: -3 }], {
datas,
fallback: Fallback.skip
})
).toEqual([]);
});
describe('zero stats', () => {
it('ignores stats with 0 value', () => {
const stats = [{ id: 'weapon_physical_damage_+%', value: 0 }];
expect(
formatStats(stats, {
datas,
fallback: Fallback.throw
})
).toEqual([]);
});
it('still throws for stats which are not 0 and no matching translation was found', () => {
expect(() =>
formatStats(
[
{ id: 'weapon_physical_damage_+%', value: 0 },
{ id: 'local_energy_shield_+%', value: [0, 1] }
],
{
datas,
fallback: Fallback.throw
}
)
).toThrow("matching translation not found for 'local_energy_shield_+%'");
});
it('ignores 0 stats for which no description was found', () => {
expect(
formatStats([{ id: 'non_existing_zero', value: 0 }], {
datas,
fallback: Fallback.throw
})
).toEqual([]);
});
it('still throws if stats are non zero and have no description', () => {
expect(() =>
formatStats([{ id: 'non_existing_zero', value: [0, 1] }], {
datas,
fallback: Fallback.throw
})
).toThrow('no descriptions found for non_existing_zero');
});
});
it('should throw if we provide an unrecognize fallback', () => {
expect(() =>
formatStats([{ id: 'from_armour_movement_speed_+%', value: -3 }], {
datas,
fallback: 345678
})
).toThrowError("unrecognized fallback type '345678'");
});
it('should support custom fallback methods', () => {
expect(
formatStats(
[
{ id: 'from_armour_movement_speed_+%', value: -3 },
{ id: 'dummy_stat_display_nothing', value: -3 }
],
{
datas,
fallback: (id: string, stat: Stat) =>
id === 'dummy_stat_display_nothing' ? null : id
}
)
).toEqual(['from_armour_movement_speed_+%']);
});
it('should support ranges for given stats', () => {
expect(
formatStats(
[
{ id: 'base_chance_to_freeze_%', value: [12, 15] },
{ id: 'attack_minimum_added_physical_damage', value: [1, 3] },
{ id: 'attack_maximum_added_physical_damage', value: [13, 18] }
],
{ datas }
).sort()
).toEqual([
'(12–15)% chance to Freeze',
'Adds (1–3) to (13–18) Physical Damage to Attacks'
]);
});
it('should have an option for which file to use', () => {
expect(
formatStats([{ id: 'weapon_physical_damage_+%', value: 25 }], {
datas,
start_file: 'active_skill_gem_stat_descriptions'
})
).toEqual(['25% increased Physical Damage with Weapons on Active Skills']);
});
it('should try each included file', () => {
expect(
formatStats([{ id: 'item_generation_cannot_change_suffixes', value: 1 }], {
datas,
start_file: 'active_skill_gem_stat_descriptions'
})
).toEqual(['Suffixes Cannot Be Changed']);
});
describe('expensive test cases', () => {
const full_datas = {
stat_descriptions: require('../../../locale-data/en/stat_descriptions.json') as StatLocaleData
};
it('translates ChanceToFreezeAddedDamageUber2', () => {
expect(
formatStats(
[
{ id: 'base_chance_to_freeze_%', value: [10, 7] },
{
id: 'global_minimum_added_cold_damage_vs_chilled_or_frozen_enemies',
value: [16, 13]
},
{
id: 'global_maximum_added_cold_damage_vs_chilled_or_frozen_enemies',
value: [36, 33]
}
],
{
datas: full_datas
}
)
).toEqual([
'(7–10)% chance to Freeze',
'Adds (13–16) to (33–36) Cold Damage against Chilled or Frozen Enemies'
]);
});
});