Commit 5b4b844c authored by Gergely Ujvari's avatar Gergely Ujvari

Break timeHelpers into smaller functions

Code from @nickstenning, introduce the breakpoints array and search
in it for the needed fuzzystring and when to update next instead of
a complex else-if tree.

timeHelpers service has two functions:
- toFuzzyString: returns the fuzzy time string
- nextFuzzyUpdate: returns the next time to update (in sec)
parent 9295c3bf
......@@ -298,9 +298,16 @@ annotation = [
if ctrl.editing then counter?.count 'edit', -1
updateTimeStamp = ->
{message, updateAt} = timeHelpers.timestamp ctrl.annotation.updated
scope.timestamp = dateFilter message
$timeout -> render updateTimeStamp, 1000*updateAt+500, false
stamp = ctrl.annotation.updated
fuzzyString= timeHelpers.toFuzzyString stamp
scope.timestamp = dateFilter fuzzyString
fuzzyUpdate = timeHelpers.nextFuzzyUpdate(stamp)
# Handle null value, give default 5 sec
fuzzyUpdate ?=5
nextUpdate = 1000*fuzzyUpdate+500
$timeout -> render updateTimeStamp, nextUpdate, false
render updateTimeStamp
......
minute = 60
hour = minute * 60
day = hour * 24
month = day * 30
year = day * 365
BREAKPOINTS = [
[30, 'moments ago', 1 ]
[minute, '{} seconds ago', 1 ]
[2 * minute, 'a minute ago', minute]
[hour, '{} minutes ago', minute]
[2 * hour, 'an hour ago', hour ]
[day, '{} hours ago', hour ]
[2 * day, 'yesterday', day ]
[month, '{} days ago', day ]
[year, '{} months ago', month ]
[Infinity, '{} years ago', year ]
]
arrayFind = (array, predicate) ->
if not array?
throw new TypeError('arrayFindIndex called on null or undefined')
if typeof predicate != 'function'
throw new TypeError('predicate must be a function')
for value, i in array
if predicate(value, i, array)
return value
return null
getBreakpoint = (date) ->
delta = Math.round((new Date() - new Date(date)) / 1000)
delta: delta
breakpoint: arrayFind(BREAKPOINTS, (x) -> x[0] > delta)
createTimeHelpers = ->
timestamp: (date) ->
return {message: '', updateAt: 5} if not date
delta = Math.round((+new Date - new Date(date)) / 1000)
minute = 60
hour = minute * 60
day = hour * 24
month = day * 30
year = day * 365
if (delta < 30)
message = 'moments ago'
updateAt = 30 - delta
else if (delta < minute)
message = delta + ' seconds ago'
updateAt = 1
else if (delta < 2 * minute)
message = 'a minute ago'
updateAt = 2*minute - delta
else if (delta < hour)
message = Math.floor(delta / minute) + ' minutes ago'
updateAt = minute
else if (Math.floor(delta / hour) == 1)
message = '1 hour ago'
updateAt = hour
else if (delta < day)
message = Math.floor(delta / hour) + ' hours ago'
updateAt = hour
else if (delta < day * 2)
message = 'yesterday'
updateAt = 2*day - delta
else if (delta < month)
message = Math.round(delta / day) + ' days ago'
updateAt = day
else if (delta < year)
message = Math.round(delta / month) + ' months ago'
updateAt = month
else
message = Math.round(delta / year) + ' years ago'
updateAt= year
message: message
updateAt: updateAt
toFuzzyString: (date) ->
return '' unless date
{delta, breakpoint} = getBreakpoint(date)
return '' unless breakpoint
template = breakpoint[1]
resolution = breakpoint[2]
return template.replace('{}', String(Math.floor(delta / resolution)))
nextFuzzyUpdate: (date) ->
return null if not date
{_, breakpoint} = getBreakpoint(date)
return null unless breakpoint
return breakpoint[2]
angular.module('h.helpers')
.factory('timeHelpers', createTimeHelpers)
\ No newline at end of file
.factory('timeHelpers', createTimeHelpers)
assert = chai.assert
sandbox = sinon.sandbox.create()
minute = 60
hour = minute * 60
......@@ -7,57 +6,74 @@ day = hour * 24
month = day * 30
year = day * 365
FIXTURES_TO_TEST = [
[10, 'moments ago', 20]
[29, 'moments ago', 1]
[49, '49 seconds ago', 1]
[minute + 5, 'a minute ago', 55]
[3 * minute + 5, '3 minutes ago', minute]
[4 * hour, '4 hours ago', hour]
[27 * hour, 'yesterday', 21*hour]
[3 * day + 30 * minute, '3 days ago', day]
[6 * month + 2 * day, '6 months ago', month]
[8 * year, '8 years ago', year]
FIXTURES_TO_FUZZY_STRING = [
[10, 'moments ago']
[29, 'moments ago']
[49, '49 seconds ago']
[minute + 5, 'a minute ago']
[3 * minute + 5, '3 minutes ago']
[4 * hour, '4 hours ago']
[27 * hour, 'yesterday']
[3 * day + 30 * minute, '3 days ago']
[6 * month + 2 * day, '6 months ago']
[8 * year, '8 years ago']
]
FIXTURES_NEXT_FUZZY_UPDATE = [
[10, 1]
[29, 1]
[49, 1]
[minute + 5, minute]
[3 * minute + 5, minute]
[4 * hour, hour]
[27 * hour, day]
[3 * day + 30 * minute, day]
[6 * month + 2 * day, month]
[8 * year, year]
]
describe 'timeHelpers', ->
beforeEach module('h.helpers')
timeHelpers = null
sandbox = null
beforeEach inject (_timeHelpers_) ->
timeHelpers = _timeHelpers_
sandbox = sinon.sandbox.create()
sandbox.useFakeTimers()
afterEach ->
sandbox.restore()
describe '.toFuzzyString', ->
it 'Handles empty dates', ->
time = null
expect = ''
assert.equal(timeHelpers.toFuzzyString(time), expect)
describe 'timestamp', ->
it 'Handles undefined', ->
time = undefined
{message, updateAt} = timeHelpers.timestamp time
assert.equal(message, '')
assert.equal(updateAt, 5)
it 'it counts the seconds', ->
time = new Date()
sandbox.clock.tick(5000)
timeHelpers.timestamp time
sandbox.clock.tick(1000)
testFixture = (f) ->
->
time = new Date()
expect = f[1]
sandbox.clock.tick(f[0]*1000)
assert.equal(timeHelpers.toFuzzyString(time), expect)
{message, updateAt} = timeHelpers.timestamp time
assert.equal(message, 'moments ago')
assert.equal(updateAt, 24)
for f, i in FIXTURES_TO_FUZZY_STRING
it "creates correct fuzzy string for fixture #{i}", testFixture(f)
describe '.nextFuzzyUpdate', ->
it 'Handles empty dates', ->
time = null
expect = null
assert.equal(timeHelpers.nextFuzzyUpdate(time), expect)
testFixture = (f) ->
->
time = new Date()
expect = f[1]
sandbox.clock.tick(f[0]*1000)
{message, updateAt} = timeHelpers.timestamp time
assert.equal(message, f[1])
assert.equal(updateAt, f[2])
assert.equal(timeHelpers.nextFuzzyUpdate(time), expect)
for f,i in FIXTURES_TO_TEST
it 'gives correct next fuzzy update time for fixture #{i}', testFixture(f)
for f, i in FIXTURES_NEXT_FUZZY_UPDATE
it "gives correct next fuzzy update time for fixture #{i}", testFixture(f)
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment