BattleSim/test/battle_queue_spec.coffee

225 lines
7.9 KiB
CoffeeScript

require './helpers'
should = require 'should'
async = require 'async'
{BattleQueue} = require('../server/queue')
redis = require('../server/redis')
ratings = require('../server/ratings')
alts = require('../server/alts')
async = require('async')
describe 'BattleQueue', ->
it 'should be empty by default', ->
new BattleQueue().should.have.length(0)
describe '#add', ->
it 'queues a new player', ->
queue = new BattleQueue()
queue.add('derp', 'derp', {})
queue.should.have.length 1
it 'queues two players', ->
queue = new BattleQueue()
queue.add('batman', 'batman', {})
queue.add('superman', 'superman', {})
queue.should.have.length 2
it 'cannot queue the same player twice', ->
queue = new BattleQueue()
queue.add('batman', 'batman', {})
queue.add('batman', 'batman', {})
queue.should.have.length 1
it 'cannot queue falsy references', ->
queue = new BattleQueue()
queue.add(null, null, {})
queue.add(false, false, {})
queue.add(undefined, undefined, {})
queue.should.have.length 0
describe '#remove', ->
it 'can dequeue old players', ->
queue = new BattleQueue()
player = 'abc'
queue.add(player, player, {})
queue.remove(player)
queue.size().should.equal 0
it "can take an array of players", ->
queue = new BattleQueue()
player1 = 'abc'
player2 = 'def'
queue.add(player1, player1, {})
queue.add(player2, player2, {})
queue.remove([ player1, player2 ])
queue.should.have.length 0
describe '#queuedPlayers', ->
it 'returns the players who are queued', ->
queue = new BattleQueue()
dude = 'dude'
queue.add(dude)
queue.queuedPlayers().should.containEql(dude)
queue.queuedPlayers().should.have.length 1
describe '#hasRecentlyMatched', ->
it "returns false if two players have not queued", ->
queue = new BattleQueue()
queue.hasRecentlyMatched("p1", "p2").should.be.false
it "returns true if two players have queued", ->
queue = new BattleQueue()
queue.addRecentMatch("p1", "p2")
queue.hasRecentlyMatched("p1", "p2").should.be.true
it "is not affected by ordering", ->
queue = new BattleQueue()
queue.addRecentMatch("p1", "p2")
queue.hasRecentlyMatched("p1", "p2").should.be.true
queue.hasRecentlyMatched("p2", "p1").should.be.true
it "returns false if 30 minutes has passed since two players have queued", ->
queue = new BattleQueue()
queue.addRecentMatch("p1", "p2")
queue.hasRecentlyMatched("p1", "p2").should.be.true
@clock.tick(31 * 60 * 1000)
queue.hasRecentlyMatched("p1", "p2").should.be.false
describe '#pairPlayers', ->
it 'takes players out of the queue', (done) ->
queue = new BattleQueue()
queue.add('batman')
queue.add('superman')
queue.pairPlayers ->
queue.queuedPlayers().should.be.empty
done()
it 'leaves one person out if the queue length is odd', (done) ->
queue = new BattleQueue()
queue.add('batman')
queue.add('superman')
queue.add('flash')
queue.pairPlayers ->
queue.queuedPlayers().should.have.length 1
done()
it 'returns an array of pairs', (done) ->
queue = new BattleQueue()
queue.add('batman', 'Bruce Wayne')
queue.add('superman', 'Clark Kent')
queue.add('flash', 'Wally West')
queue.add('spiderman', 'Peter Parker')
queue.pairPlayers (err, results) ->
should.not.exist(err)
should.exist(results)
results.should.be.instanceOf(Array)
results.should.have.length(2)
done()
it 'returns id/name/team/ratingkeyobjects', (done) ->
queue = new BattleQueue()
queue.add('batman', 'Bruce Wayne', [], 'bat')
queue.add('superman', 'Clark Kent', [], 'supes')
queue.pairPlayers (err, results) ->
should.not.exist(err)
should.exist(results)
results.should.eql [[
{id: 'batman', name: 'Bruce Wayne', team: [], ratingKey: 'bat' }
{id: 'superman', name: 'Clark Kent', team: [], ratingKey: 'supes' }
]]
done()
it "returns an array of pairs in the order of their rating", (done) ->
scores = [["batman", 1], ["superman", 4], ["flash", 3], ["spiderman", 2]]
callbacks = for [player, score] in scores
ratings.setRating.bind(ratings, player, score)
async.parallel callbacks, ->
queue = new BattleQueue()
queue.add(pair[0]) for pair in scores
queue.pairPlayers (err, results) ->
should.not.exist(err)
should.exist(results)
results.should.be.instanceOf(Array)
results.should.have.length(2)
results = results.map (result) ->
[result[0].id, result[1].id]
results.should.eql [[ "batman", "spiderman" ]
[ "flash", "superman" ]]
done()
it "does not match the same players twice", (done) ->
scores = [["batman", 1], ["superman", 4], ["flash", 3], ["spiderman", 2]]
callbacks = for [player, score] in scores
ratings.setRating.bind(ratings, player, score)
async.parallel callbacks, ->
queue = new BattleQueue()
queue.add(pair[0]) for pair in scores
queue.pairPlayers (err, results) ->
should.not.exist(err)
results = results.map (result) ->
[result[0].id, result[1].id]
results.should.eql [[ "batman", "spiderman" ]
[ "flash", "superman" ]]
# now perform round two: Should get different results
queue.add(pair[0]) for pair in scores
queue.pairPlayers (err, results) ->
should.not.exist(err)
results = results.map (result) ->
[result[0].id, result[1].id]
results.should.eql [[ "batman", "flash" ]
[ "spiderman", "superman" ]]
done()
it "does not match players with a large rating gap until it expands", (done) ->
scores = [["batman", 900], ["superman", 1005]]
callbacks = for [player, score] in scores
ratings.setRating.bind(ratings, player, score)
async.parallel callbacks, ->
queue = new BattleQueue()
queue.add(pair[0]) for pair in scores
# first run - no matches should be found
queue.pairPlayers (err, results) ->
should.not.exist(err)
results.should.have.length 0
# second run - should have found a match
queue.pairPlayers (err, results) ->
should.not.exist(err)
results.should.have.length 1
done()
it "returns a different ordering for alts ratings", (done) ->
users = [
["batman", "Bruce Wayne", 1, 1]
["superman", "Clark Kent", 4, 4]
["flash", "Wally West", 3, 2]
["spiderman", "Peter Parker", 2, 3]
]
ratingTasks = []
for user in users
# non-alt
ratingTasks.push ratings.setRating.bind(null, user[0], user[2])
# alt
altId = alts.uniqueId(user[0], user[1])
ratingTasks.push ratings.setRating.bind(this, altId, user[3])
async.series ratingTasks, ->
queue = new BattleQueue()
queue.add(user[0]) for user in users
queue.pairPlayers (err, results) ->
should.not.exist(err)
results = results.map((result) -> [result[0].id, result[1].id])
results.should.eql [[ "batman", "spiderman" ], [ "flash", "superman" ]]
# now test alts getting added
queue.add(user[0], user[1], null, alts.uniqueId(user[0], user[1])) for user in users
queue.pairPlayers (err, results) ->
should.not.exist(err)
results = results.map((result) -> [result[0].id, result[1].id])
results.should.eql [["batman", "flash"], ["spiderman", "superman"]]
done()