habitica-self-host/tests/algos.mocha.coffee

163 lines
6 KiB
CoffeeScript
Raw Normal View History

_ = require 'lodash'
expect = require 'expect.js'
moment = require 'moment'
# Custom modules
algos = require '../script/algos'
helpers = require '../script/helpers'
items = require '../script/items'
### Helper Functions ####
expectStrings = (obj, paths) ->
_.each paths, (path) -> expect(obj[path]).to.be.ok()
beforeAfter = (options={}) ->
user = helpers.newUser()
[before, after] = [_.cloneDeep(user), _.cloneDeep(user)]
lastCron = +moment(options.now || +new Date).subtract('days', options.daysAgo) if options.daysAgo
_.each [before,after], (obj) ->
obj.lastCron = lastCron if options.daysAgo
{before:before, after:after}
#TODO calculate actual poins
expectLostPoints = (before, after, taskType) ->
if taskType in ['daily','habit']
expect(after.stats.hp).to.be.lessThan before.stats.hp
expect(_.size(after["#{taskType}s"][0].history)).to.be(1)
else expect(_.size(after.history.todos)).to.be(1)
expect(after.stats.exp).to.be 0
expect(after.stats.gp).to.be 0
expect(after["#{taskType}s"][0].value).to.be.lessThan before["#{taskType}s"][0].value
expectGainedPoints = (before, after, taskType) ->
expect(after.stats.hp).to.be 50
expect(after.stats.exp).to.be.greaterThan before.stats.exp
expect(after.stats.gp).to.be.greaterThan before.stats.gp
expect(after["#{taskType}s"][0].value).to.be.greaterThan before["#{taskType}s"][0].value
expect(_.size(after["#{taskType}s"][0].history)).to.be(1) if taskType is 'habit'
# daily & todo histories handled on cron
###### Specs ######
describe 'User', ->
it 'sets correct user defaults', ->
user = helpers.newUser()
expect(user.stats).to.eql { gp: 0, exp: 0, lvl: 1, hp: 50 }
expect(user.party).to.eql { invitation: null }
expect(user.items).to.eql { weapon: 0, armor: 0, head: 0, shield: 0 }
expect(user.preferences).to.eql { gender: 'm', skin: 'white', hair: 'blond', armorSet: 'v1', dayStart:0, showHelm: true }
expect(user.balance).to.eql 0
expect(user.lastCron).to.eql 'new'
expect(user.flags).to.eql {partyEnabled: false, itemsEnabled: false, ads: 'show'}
expectStrings(user, ['apiToken'])
expectStrings(user.habits[0], ['text','id'])
expectStrings(user.dailys[0], ['text','id'])
expectStrings(user.todos[0], ['text','id'])
expectStrings(user.rewards[0], ['text','id'])
expectStrings(user.tags[0], ['name','id'])
expectStrings(user.tags[1], ['name','id'])
expectStrings(user.tags[2], ['name','id'])
describe 'Simple Scoring', ->
it 'Habits : Up', ->
{before,after} = beforeAfter()
algos.score(after, after.habits[0], 'down', {times:5})
expectLostPoints(before,after,'habit')
it 'Habits : Down', ->
{before,after} = beforeAfter()
algos.score(after, after.habits[0], 'up', {times:5})
expectGainedPoints(before,after,'habit')
it 'Dailys : Up', ->
{before,after} = beforeAfter()
algos.score(after, after.dailys[0], 'up')
expectGainedPoints(before,after,'daily')
2013-05-24 15:12:55 +00:00
it 'Todos : Up', ->
{before,after} = beforeAfter()
algos.score(after, after.todos[0], 'up')
expectGainedPoints(before,after,'todo')
describe 'Cron', ->
2013-05-24 15:12:55 +00:00
it 'computes shouldCron', ->
user = helpers.newUser()
2013-05-24 15:12:55 +00:00
expect(algos.shouldCron(user)).to.be true # handlomg lastCron='new'
user.lastCron = moment().subtract('days',1)
expect(algos.shouldCron(user)).to.be true
2013-05-24 15:12:55 +00:00
user.lastCron = moment().add('days',1)
expect(algos.shouldCron(user)).to.be false
it 'only dailies & todos are effected', ->
{before,after} = beforeAfter({daysAgo:1})
before.dailys = before.todos = after.dailys = after.todos = []
algos.cron(after)
expect(after.lastCron).to.not.be before.lastCron # make sure cron was run
expect(before.stats).to.eql after.stats
beforeTasks = before.habits.concat(before.dailys).concat(before.todos).concat(before.rewards)
afterTasks = after.habits.concat(after.dailys).concat(after.todos).concat(after.rewards)
expect(beforeTasks).to.eql afterTasks
describe 'Todos', ->
it '1 day missed', ->
{before,after} = beforeAfter({daysAgo:1})
before.dailys = after.dailys = []
algos.cron(after)
# todos don't effect stats
expect(after.stats.hp).to.be 50
expect(after.stats.exp).to.be 0
expect(after.stats.gp).to.be 0
# but they devalue
expect(after.todos[0].value).to.be.lessThan before.todos[0].value
expect(_.size(after.history.todos)).to.be 1
describe 'Dailies', ->
it '1 day missed', ->
{before,after} = beforeAfter({daysAgo:1})
[before.dailys, after.dailys] = [ [before.dailys[0]], [after.dailys[0]] ]
algos.cron(after)
expectLostPoints(before,after,'daily')
it 'due yesterday, custom day not started', ->
now = moment().startOf('week')
[before.dailys, after.dailys] = [ [before.dailys[0]], [after.dailys[0]] ]
# due yesterday, but not today
before.dailys[0].repeat = after.dailys[0].repeat = {su:0,m:1,t:1,w:1,th:1,f:1,s:1}
{before,after} = beforeAfter({now, daysAgo:1})
expectLostPoints(before,after,'daily') # todos don't effect stats
# but they devalue
expect(after.dailys[0].value).to.be.lessThan before.dailys[0].value
expect(_.size(after.dailys[0].history)).to.be 1
2013-05-24 15:12:55 +00:00
it 'due today, custom day not started'
it 'checked yesterday, custom day not started'
it 'checked yesterday, custom day started'
it '1 day missed, not due'
it '1 day missed, not day start yet'
it '3 day missed, only 1 due'
it '3 day missed, only 1 due, not day start yet'
2013-05-24 15:12:55 +00:00
it 'calculates day differences with dayStart properly', ->
dayStart = 4
yesterday = moment().subtract('d', 1).add('h', dayStart)
now = moment().startOf('day').add('h', dayStart-1) #today
console.log {yesterday: yesterday.format('MM/DD HH:00'), now: now.format('MM/DD HH:00')}
console.log {diff: Math.abs(moment(yesterday).diff(moment(now), 'days'))}
expect(helpers.daysBetween(yesterday, now, dayStart)).to.eql 0
now = moment().startOf('day').add('h', dayStart)
console.log {now: now.format('MM/DD HH:00')}
expect(helpers.daysBetween(yesterday, now, dayStart)).to.eql 1