toefungi-elo-calculator
Version:
A package to do all necessary computations to determine ELO rankings
154 lines (117 loc) • 5.32 kB
text/typescript
import { EloCalculator, Probabilities, ScoringBonus } from '../../src'
describe('EloCalculator', () => {
let eloCalculator: EloCalculator
const playerElo: number = 2000
const opponentElo: number = 2000
const shouldRound: boolean = true
beforeEach(() => {
eloCalculator = new EloCalculator(shouldRound)
})
describe('#constructor', () => {
const kFactorDefault = 32
const shouldRoundDefault = true
const kFactorSet = 10
const shouldRoundSet = false
it('defaults both `shouldRound` and `kFactor` when no values are passed', () => {
const eloCalculator = new EloCalculator()
eloCalculator.kFactor.should.deep.equal(kFactorDefault)
eloCalculator.shouldRound.should.deep.equal(shouldRoundDefault)
})
it('defaults `kFactor` and sets `shouldRound` when `shouldRound` is passed', () => {
const eloCalculator = new EloCalculator(shouldRoundSet)
eloCalculator.kFactor.should.deep.equal(kFactorDefault)
eloCalculator.shouldRound.should.deep.equal(shouldRoundSet)
})
it('defaults `shouldRound` and sets `kFactor` when `kFactor` is passed', () => {
const eloCalculator = new EloCalculator(shouldRoundDefault, kFactorSet)
eloCalculator.kFactor.should.deep.equal(kFactorSet)
eloCalculator.shouldRound.should.deep.equal(shouldRoundDefault)
})
it('sets both `shouldRound` and `kFactor` when both values are passed', () => {
const eloCalculator = new EloCalculator(shouldRoundSet, kFactorSet)
eloCalculator.kFactor.should.deep.equal(kFactorSet)
eloCalculator.shouldRound.should.deep.equal(shouldRoundSet)
})
})
describe('#calculateElo', () => {
describe('win', () => {
it('returns a specific ELO which is higher after a win', () => {
const expectedElo: number = 2016
return eloCalculator.calculateElo(playerElo, opponentElo, ScoringBonus.WIN)
.should.become(expectedElo)
})
it('returns a specific ELO which is higher after a win and takes into account score difference', () => {
const expectedElo: number = 2026
return eloCalculator.calculateElo(playerElo, opponentElo, ScoringBonus.WIN, 4)
.should.become(expectedElo)
})
})
describe('draw', () => {
it('returns a higher ELO when the opponent has a higher ELO and the game was a draw', () => {
const opponentElo: number = 2400
const expectedElo: number = 2013
return eloCalculator.calculateElo(playerElo, opponentElo, ScoringBonus.DRAW)
.should.become(expectedElo)
})
it('returns the same ELO when both players have equal ELO and the game was a draw', () => {
const expectedElo: number = 2000
return eloCalculator.calculateElo(playerElo, opponentElo, ScoringBonus.DRAW)
.should.become(expectedElo)
})
it('returns a lower ELO when the opponent has a lower ELO and the game was a draw', () => {
const playerElo: number = 2400
const expectedElo: number = 2387
return eloCalculator.calculateElo(playerElo, opponentElo, ScoringBonus.DRAW)
.should.become(expectedElo)
})
})
describe('loss', () => {
it('returns a specific ELO which is lower after a loss', () => {
const expectedElo: number = 1984
return eloCalculator.calculateElo(playerElo, opponentElo, ScoringBonus.LOSS)
.should.become(expectedElo)
})
it('returns a specific ELO which is lower after a loss and takes into account score difference', () => {
const expectedElo: number = 1969
return eloCalculator.calculateElo(playerElo, opponentElo, ScoringBonus.LOSS, 6)
.should.become(expectedElo)
})
})
it('returns an ELO that is not rounded', () => {
const playerElo = 2400
const shouldRound = false
const expectedElo = 2386.909090909091
eloCalculator = new EloCalculator(shouldRound)
return eloCalculator.calculateElo(playerElo, opponentElo, ScoringBonus.DRAW)
.should.become(expectedElo)
})
})
describe('#caluclateWinProbability', () => {
it('returns a 50 / 50 probability of winning', () => {
const expectedProbability: Probabilities = {
player: 50,
opponent: 50
}
return eloCalculator.caluclateWinProbability(playerElo, opponentElo)
.should.become(expectedProbability)
})
it('returns a high probability when the player has a higher ELO than the opponent', () => {
const playerElo: number = 2364
const expectedProbability: Probabilities = {
player: 89,
opponent: 11
}
return eloCalculator.caluclateWinProbability(playerElo, opponentElo)
.should.become(expectedProbability)
})
it('returns a low probability when the player has a lower ELO than the opponent', () => {
const playerElo: number = 1800
const expectedProbability: Probabilities = {
player: 24,
opponent: 76
}
return eloCalculator.caluclateWinProbability(playerElo, opponentElo)
.should.become(expectedProbability)
})
})
})