Skip to content

Commit

Permalink
fix: Parse YDS slash grades correctly
Browse files Browse the repository at this point in the history
YDS slash grades were being assigned the score of the first grade. This
was due to `.includes()` not matching the slash.

Change this to correctly identify slash grades.  Refactor a little to
help clarity.
Add test that score range of a slash grade is strict subset of that of
the two grades, and overlaps with both of them.

Add failing tests slash grades composed of non-consecutive grades and
slashes across number boundaries.

Fixes #142
  • Loading branch information
musoke committed Jul 26, 2023
1 parent 5870f1f commit dc2aa0c
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 9 deletions.
22 changes: 22 additions & 0 deletions src/__tests__/scales/yds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ describe('YosemiteDecimal', () => {
test('grade with slash', () => {
expect(YosemiteDecimal.isType('5.10a/b')).toBeTruthy()
})
test.failing('grade with slash', () => {
expect(YosemiteDecimal.isType('5.10d/5.11a')).toBeTruthy()
})

test.failing('grade with non-consecutive slash grades', () => {
expect(YosemiteDecimal.isType('5.10d/c')).toBeFalsy()
expect(YosemiteDecimal.isType('5.10a/c')).toBeFalsy()
expect(YosemiteDecimal.isType('5.10c/5.11a')).toBeFalsy()
})

test('incorrect type', () => {
expect(YosemiteDecimal.isType('11+')).toBeFalsy()
Expand Down Expand Up @@ -112,4 +121,17 @@ describe('YosemiteDecimal', () => {
expect(YosemiteDecimal.getGradeBand('5.15a')).toEqual(GradeBands.EXPERT)
})
})

describe('Slash scores', () => {
test('scores of slash grades should be subset of neighboring scores', () => {
const slashScore = YosemiteDecimal.getScore('5.10a/b')
const lowScore = YosemiteDecimal.getScore('5.10a')
const highScore = YosemiteDecimal.getScore('5.10b')

expect(slashScore[0]).toBeGreaterThan(lowScore[0])
expect(slashScore[1]).toBeGreaterThan(lowScore[1])
expect(slashScore[0]).toBeLessThan(highScore[0])
expect(slashScore[1]).toBeLessThan(highScore[1])
})
})
})
21 changes: 12 additions & 9 deletions src/scales/yds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,32 +66,35 @@ const getScore = (grade: string): number | Tuple => {
}
const [wholeMatch, basicGrade, number, letter, plusOrMinusOrSlash] = parse
let normalizedGrade = basicGrade
const plusSlash = ['+', '/'].includes(plusOrMinusOrSlash)

const slash = plusOrMinusOrSlash?.startsWith('/')
const minus = plusOrMinusOrSlash === '-'
const plus = plusOrMinusOrSlash === '+'

let normalizedLetter = letter
const isLargeNonLetter = parseInt(number, 10) > 9 && normalizedLetter === ''
if (isLargeNonLetter) {
// 11-, 13+, 12
normalizedLetter = minus ? 'a' : plusSlash ? 'c' : 'b'
normalizedLetter = minus ? 'a' : (plus || slash) ? 'c' : 'b'
}
normalizedGrade = basicGrade + normalizedLetter
const basicScore = findScoreRange((r: Route) => {
return r.yds === normalizedGrade
}, routes)

if (wholeMatch !== normalizedGrade) {
let otherGrade
// 5.11+, 5.10a/b
if (plusSlash || isLargeNonLetter) {
otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[1]) + 1
let otherScore
if (plus || slash || isLargeNonLetter) {
// 5.11+, 5.10a/b
otherScore = (typeof basicScore === 'number' ? basicScore : basicScore[1]) + 1
} else if (minus) {
// 5.11-
otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[0]) - 1
otherScore = (typeof basicScore === 'number' ? basicScore : basicScore[0]) - 1
}

if (otherGrade !== undefined) {
if (otherScore !== undefined) {
const nextGrade = findScoreRange((r: Route) => {
return r.yds.toLowerCase() === routes[Math.max(otherGrade, 0)].yds.toLowerCase()
return r.yds.toLowerCase() === routes[Math.max(otherScore, 0)].yds.toLowerCase()
}, routes)
return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort((a, b) => a - b) as Tuple
}
Expand Down

0 comments on commit dc2aa0c

Please sign in to comment.