Current and Longest streak calculation fixed

Minor refactoring and unit tests added

After CR: user-stats file moved to util folder, export keywork added to exported functions, new line added at the end of gulp file

User-stats-test file moved to replicate user-stats path in test folder
This commit is contained in:
JelenaBarinova
2015-12-10 14:52:09 -08:00
parent cf65c698bb
commit 6c7d2685fd
8 changed files with 240 additions and 46 deletions

View File

@@ -10,9 +10,9 @@ import {
} from '../utils/constantStrings.json';
import { ifNoUser401, ifNoUserRedirectTo } from '../utils/middleware';
import { observeQuery } from '../utils/rx';
import { calcCurrentStreak, calcLongestStreak } from '../utils/user-stats';
const debug = debugFactory('freecc:boot:user');
const daysBetween = 1.5;
const sendNonUserToMap = ifNoUserRedirectTo('/map');
function replaceScriptTags(value) {
@@ -31,47 +31,6 @@ function encodeFcc(value = '') {
return replaceScriptTags(replaceFormAction(value));
}
function calcCurrentStreak(cals) {
const revCals = cals.concat([Date.now()]).slice().reverse();
let streakBroken = false;
const lastDayInStreak = revCals
.reduce((current, cal, index) => {
const before = revCals[index === 0 ? 0 : index - 1];
if (
!streakBroken &&
moment(before).diff(cal, 'days', true) < daysBetween
) {
return index;
}
streakBroken = true;
return current;
}, 0);
const lastTimestamp = revCals[lastDayInStreak];
return Math.ceil(moment().diff(lastTimestamp, 'days', true));
}
function calcLongestStreak(cals) {
let tail = cals[0];
const longest = cals.reduce((longest, head, index) => {
const last = cals[index === 0 ? 0 : index - 1];
// is streak broken
if (moment(head).diff(last, 'days', true) > daysBetween) {
tail = head;
}
if (dayDiff(longest) < dayDiff([head, tail])) {
return [head, tail];
}
return longest;
}, [cals[0], cals[0]]);
return Math.ceil(dayDiff(longest));
}
function dayDiff([head, tail]) {
return moment(head).diff(tail, 'days', true);
}
module.exports = function(app) {
var router = app.loopback.Router();
var User = app.models.User;

View File

@@ -0,0 +1,11 @@
import moment from 'moment';
// day count between two epochs (inclusive)
export function dayCount([head, tail]) {
return Math.ceil(
moment(moment(head).endOf('day')).diff(
moment(tail).startOf('day'),
'days',
true)
);
}

View File

@@ -0,0 +1,46 @@
import moment from 'moment';
import { dayCount } from '../utils/date-utils';
const daysBetween = 1.5;
export function calcCurrentStreak(cals) {
const revCals = cals.slice().reverse();
if (dayCount([moment(), revCals[0]]) > daysBetween) {
return 0;
}
let streakBroken = false;
const lastDayInStreak = revCals
.reduce((current, cal, index) => {
const before = revCals[index === 0 ? 0 : index - 1];
if (
!streakBroken &&
moment(before).diff(cal, 'days', true) < daysBetween
) {
return index;
}
streakBroken = true;
return current;
}, 0);
const lastTimestamp = revCals[lastDayInStreak];
return dayCount([moment(), lastTimestamp]);
}
export function calcLongestStreak(cals) {
let tail = cals[0];
const longest = cals.reduce((longest, head, index) => {
const last = cals[index === 0 ? 0 : index - 1];
// is streak broken
if (moment(head).diff(last, 'days', true) > daysBetween) {
tail = head;
}
if (dayCount(longest) < dayCount([head, tail])) {
return [head, tail];
}
return longest;
}, [cals[0], cals[0]]);
return dayCount(longest);
}

View File

@@ -119,8 +119,8 @@ block content
.row
.hidden-xs.col-sm-12.text-center
.row.text-primary
h4.col-sm-6.text-right Longest Streak: #{longestStreak} #{longestStreak + longestStreak === 1 ? ' day' : ' days'}
h4.col-sm-6.text-left Current Streak: #{currentStreak} #{currentStreak + currentStreak === 1 ? ' day' : ' days'}
h4.col-sm-6.text-right Longest Streak: #{longestStreak} #{longestStreak === 1 ? ' day' : ' days'}
h4.col-sm-6.text-left Current Streak: #{currentStreak} #{currentStreak === 1 ? ' day' : ' days'}
if (user && user.username == username || !isLocked)