fix: fix parsing of mercurial in dragon-item-parser
All checks were successful
Dragon Item Parser CI / build-and-test (push) Successful in 13s
pipeline / lint-and-format (push) Successful in 4m46s
pipeline / build-and-push-images (push) Successful in 2m19s

This commit is contained in:
2026-04-27 13:31:18 +02:00
parent af51d61e0c
commit 7712abe3f0
2 changed files with 57 additions and 4 deletions

View File

@@ -544,11 +544,15 @@ function parseEffects(description: string): ItemEffect[] {
const activeMatch = line.match(/^<active>([^<]*)<\/active>(.*)$/i)
if (activeMatch) {
const remainingContent = activeMatch[2].trim()
// Skip lines that are just "ACTIVE" labels (like "(0s)" cooldown indicators)
const effectName = activeMatch[1].trim()
if (effectName.toUpperCase() === 'ACTIVE' && remainingContent.match(/^\([^)]*\)\s*$/)) {
// This is just a cooldown label, skip it
continue
// Skip lines that are just "ACTIVE" labels
// This includes: standalone "ACTIVE", or "ACTIVE" followed by cooldown like "(0s)"
if (effectName.toUpperCase() === 'ACTIVE') {
// Skip if it's just "ACTIVE" with no other content, or just a cooldown indicator
if (!remainingContent || remainingContent.match(/^\([^)]*\)\s*$/)) {
continue
}
}
if (!remainingContent) {

View File

@@ -441,3 +441,52 @@ describe('parseItemFull', () => {
expect(result.parsedDescription.effects[0].name).toBe('Magical Opus')
})
})
describe('edge case items', () => {
it('should parse Mercurial Scimitar with ACTIVE label before effect name', () => {
const description =
'<mainText><stats><attention> 50</attention> Attack Damage<br><attention> 35</attention> Magic Resist<br><attention> 10%</attention> Life Steal</stats><br><br><br><br> <active>ACTIVE</active><br><active>Quicksilver</active><br>Removes all crowd control debuffs (excluding <keyword>Airborne</keyword>) and grants Move Speed.</mainText>'
const result = parseItemDescription(description)
expect(result.stats.attackDamage).toBe(50)
expect(result.stats.magicResist).toBe(35)
expect(result.stats.lifeSteal).toBe(10)
expect(result.effects).toHaveLength(1)
expect(result.effects[0].type).toBe('active')
expect(result.effects[0].name).toBe('Quicksilver')
expect(result.effects[0].description.length).toBeGreaterThan(0)
expect(result.effects[0].description[0].content).toContain('Removes all crowd control')
})
it('should parse Hextech Gunblade with ACTIVE label and cooldown', () => {
const description =
'<mainText><stats><attention> 80</attention> Ability Power<br><attention> 40</attention> Attack Damage<br><attention> 10%</attention> Omnivamp</stats><br><br><br><br> <active>ACTIVE</active> (0s)<br><active>Lightning Bolt</active><br>Shocks the target enemy champion, dealing magic damage and slowing them by 25% for 1.5 seconds.</mainText>'
const result = parseItemDescription(description)
expect(result.stats.abilityPower).toBe(80)
expect(result.stats.attackDamage).toBe(40)
expect(result.stats.omnivamp).toBe(10)
expect(result.effects).toHaveLength(1)
expect(result.effects[0].type).toBe('active')
expect(result.effects[0].name).toBe('Lightning Bolt')
expect(result.effects[0].description.length).toBeGreaterThan(0)
expect(result.effects[0].description[0].content).toContain('Shocks the target enemy champion')
})
it('should parse Dark Seal with passive name appearing in description', () => {
const description =
'<mainText><stats><attention> 15</attention> Ability Power<br><attention> 50</attention> Health</stats><br><br><passive>Glory</passive><br><keyword>Takedowns</keyword> grant <passive>Glory</passive>, up to 10. 5 <passive>Glory</passive> is lost on death.<br>Gain <scaleAP>4 Ability Power</scaleAP> per <passive>Glory</passive>.</mainText>'
const result = parseItemDescription(description)
expect(result.stats.abilityPower).toBe(15)
expect(result.stats.health).toBe(50)
expect(result.effects).toHaveLength(1)
expect(result.effects[0].type).toBe('passive')
expect(result.effects[0].name).toBe('Glory')
// Description should contain the full text with Glory mentions
const descText = result.effects[0].description.map(d => d.content).join('')
expect(descText).toContain('Takedowns')
expect(descText).toContain('Glory')
expect(descText).toContain('Ability Power')
})
})