diff --git a/.gitignore b/.gitignore index 002780bbdc..4ae45467dc 100644 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,4 @@ coverage coverage.html common/dist/scripts/habitrpg-shared.js -test/spec/translations.js +test/spec/mocks/translations.js diff --git a/karma.conf.js b/karma.conf.js index 0b79578199..a4ee7a1296 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -35,7 +35,7 @@ module.exports = function(config) { 'website/public/bower_components/js-emoji/emoji.js', 'common/dist/scripts/habitrpg-shared.js', - "test/spec/translations.js", + "test/spec/mocks/translations.js", "website/public/js/env.js", @@ -51,7 +51,9 @@ module.exports = function(config) { "website/public/js/services/challengeServices.js", "website/public/js/services/paymentServices.js", - "website/public/js/filters/filters.js", + "website/public/js/filters/money.js", + "website/public/js/filters/roundLargeNumbers.js", + "website/public/js/filters/taskOrdering.js", "website/public/js/directives/focus-me.directive.js", "website/public/js/directives/from-now.directive.js", @@ -77,7 +79,7 @@ module.exports = function(config) { "website/public/js/controllers/footerCtrl.js", "website/public/js/controllers/challengesCtrl.js", "website/public/js/controllers/hallCtrl.js", - 'test/spec/mock/**/*.js', + 'test/spec/mocks/**/*.js', 'test/spec/specHelper.js', 'test/spec/**/*.js' ], diff --git a/test/spec/authCtrlSpec.js b/test/spec/controllers/authCtrlSpec.js similarity index 100% rename from test/spec/authCtrlSpec.js rename to test/spec/controllers/authCtrlSpec.js diff --git a/test/spec/filtersCtrlSpec.js b/test/spec/controllers/filtersCtrlSpec.js similarity index 100% rename from test/spec/filtersCtrlSpec.js rename to test/spec/controllers/filtersCtrlSpec.js diff --git a/test/spec/groupCtrlSpec.js b/test/spec/controllers/groupCtrlSpec.js similarity index 100% rename from test/spec/groupCtrlSpec.js rename to test/spec/controllers/groupCtrlSpec.js diff --git a/test/spec/hallCtrlSpec.js b/test/spec/controllers/hallCtrlSpec.js similarity index 100% rename from test/spec/hallCtrlSpec.js rename to test/spec/controllers/hallCtrlSpec.js diff --git a/test/spec/headerCtrlSpec.js b/test/spec/controllers/headerCtrlSpec.js similarity index 100% rename from test/spec/headerCtrlSpec.js rename to test/spec/controllers/headerCtrlSpec.js diff --git a/test/spec/inventoryCtrlSpec.js b/test/spec/controllers/inventoryCtrlSpec.js similarity index 100% rename from test/spec/inventoryCtrlSpec.js rename to test/spec/controllers/inventoryCtrlSpec.js diff --git a/test/spec/rootCtrlSpec.js b/test/spec/controllers/rootCtrlSpec.js similarity index 100% rename from test/spec/rootCtrlSpec.js rename to test/spec/controllers/rootCtrlSpec.js diff --git a/test/spec/filters/largeRoundNumbersSpec.js b/test/spec/filters/largeRoundNumbersSpec.js new file mode 100644 index 0000000000..bb563b0a87 --- /dev/null +++ b/test/spec/filters/largeRoundNumbersSpec.js @@ -0,0 +1,33 @@ +describe('roundLargeNumbers', function() { + + beforeEach(module('habitrpg')); + + it('returns same number if less than 1000', inject(function(roundLargeNumbersFilter) { + for(var num = 0; num < 1000; num++) { + expect(roundLargeNumbersFilter(num)).to.eql(num); + }; + })); + + it('truncates number and appends "k" if number is 1000-999999', inject(function(roundLargeNumbersFilter) { + expect(roundLargeNumbersFilter(999.01)).to.eql("1.0k"); + expect(roundLargeNumbersFilter(1000)).to.eql("1.0k"); + expect(roundLargeNumbersFilter(3284.12)).to.eql("3.3k"); + expect(roundLargeNumbersFilter(52983.99)).to.eql("53.0k"); + expect(roundLargeNumbersFilter(452983.99)).to.eql("453.0k"); + expect(roundLargeNumbersFilter(999999)).to.eql("1000.0k"); + })); + + it('truncates number and appends "m" if number is 1000000-999999999', inject(function(roundLargeNumbersFilter) { + expect(roundLargeNumbersFilter(999999.01)).to.eql("1.0m"); + expect(roundLargeNumbersFilter(1000000)).to.eql("1.0m"); + expect(roundLargeNumbersFilter(3284124.12)).to.eql("3.3m"); + expect(roundLargeNumbersFilter(52983105.99)).to.eql("53.0m"); + expect(roundLargeNumbersFilter(452983410.99)).to.eql("453.0m"); + expect(roundLargeNumbersFilter(999999999)).to.eql("1000.0m"); + })); + + it('truncates number and appends b" if number is greater than 999999999', inject(function(roundLargeNumbersFilter) { + expect(roundLargeNumbersFilter(999999999.01)).to.eql("1.0b"); + expect(roundLargeNumbersFilter(1423985738.54)).to.eql("1.4b"); + })); +}); diff --git a/test/spec/filters/moneySpec.js b/test/spec/filters/moneySpec.js new file mode 100644 index 0000000000..6f557cc433 --- /dev/null +++ b/test/spec/filters/moneySpec.js @@ -0,0 +1,35 @@ +describe('filter', function() { + + beforeEach(module('habitrpg')); + + describe('gold', function() { + it('rounds down decimal values', inject(function(goldFilter) { + expect(goldFilter(10)).to.eql(10); + expect(goldFilter(10.0)).to.eql(10); + expect(goldFilter(10.1)).to.eql(10); + expect(goldFilter(10.2)).to.eql(10); + expect(goldFilter(10.3)).to.eql(10); + expect(goldFilter(10.4)).to.eql(10); + expect(goldFilter(10.5)).to.eql(10); + expect(goldFilter(10.6)).to.eql(10); + expect(goldFilter(10.7)).to.eql(10); + expect(goldFilter(10.8)).to.eql(10); + expect(goldFilter(10.9)).to.eql(10); + expect(goldFilter(11)).to.eql(11); + })); + }); + + describe('silver', function() { + it('converts decimal value of gold to silver', inject(function(silverFilter) { + expect(silverFilter(10)).to.be.closeTo(0, 1); + expect(silverFilter(10.01)).to.be.closeTo(1, 1); + expect(silverFilter(10.05)).to.be.closeTo(5, 1); + expect(silverFilter(10.17)).to.be.closeTo(17, 1); + expect(silverFilter(10.23)).to.be.closeTo(23, 1); + expect(silverFilter(10.25)).to.be.closeTo(25, 1); + expect(silverFilter(10.53)).to.be.closeTo(53, 1); + expect(silverFilter(10.75)).to.be.closeTo(75, 1); + expect(silverFilter(10.99)).to.be.closeTo(99, 1); + })); + }); +}); diff --git a/test/spec/filters/taskOrderingSpec.js b/test/spec/filters/taskOrderingSpec.js new file mode 100644 index 0000000000..989a56c7e8 --- /dev/null +++ b/test/spec/filters/taskOrderingSpec.js @@ -0,0 +1,54 @@ +'use strict'; + +describe('Task Ordering Filters', function() { + var filter + , orderBySpy = sinon.spy(); + + beforeEach(function() { + module(function($provide) { + $provide.value('orderByFilter', orderBySpy); + }); + inject(function($rootScope, $filter) { + filter = $filter; + }); + }); + + describe('conditionalOrderBy', function() { + describe('when the predicate is true', function() { + it('delegates the arguments to the orderBy filter', function() { + filter('conditionalOrderBy')('array', true, 'sortPredicate', 'reverseOrder'); + expect(orderBySpy).to.have.been.calledWith('array','sortPredicate','reverseOrder'); + }); + }); + + describe('when the predicate is false', function() { + it('returns the initial array', function() { + expect(filter('conditionalOrderBy')([1,2,3], false)).to.eql([1,2,3]); + }); + }); + }); + + describe('filterByTextAndNotes', function () { + it('returns undefined when no input given', function () { + expect(filter('filterByTextAndNotes')()).to.eql(undefined); + }); + + it('returns input if term is not a string', function () { + var input = [1, 2, 3]; + expect(filter('filterByTextAndNotes')(input, '')).to.eql(input); + expect(filter('filterByTextAndNotes')(input, undefined)).to.eql(input); + expect(filter('filterByTextAndNotes')(input, [])).to.eql(input); + expect(filter('filterByTextAndNotes')(input, new Date())).to.eql(input); + }); + + it('filters items by notes and text', function () { + var tasks = [ + { text: 'foo' }, + { text: 'foo', notes: 'bar' } + ]; + + expect(filter('filterByTextAndNotes')(tasks, 'bar')).to.eql([tasks[1]]); + expect(filter('filterByTextAndNotes')(tasks, 'foo')).to.eql([tasks[0], tasks[1]]); + }); + }); +}); diff --git a/test/spec/mock/mixpanelMock.js b/test/spec/mocks/mixpanelMock.js similarity index 100% rename from test/spec/mock/mixpanelMock.js rename to test/spec/mocks/mixpanelMock.js diff --git a/test/spec/groupServicesSpec.js b/test/spec/services/groupServicesSpec.js similarity index 100% rename from test/spec/groupServicesSpec.js rename to test/spec/services/groupServicesSpec.js diff --git a/test/spec/memberServicesSpec.js b/test/spec/services/memberServicesSpec.js similarity index 100% rename from test/spec/memberServicesSpec.js rename to test/spec/services/memberServicesSpec.js diff --git a/test/spec/notificationServicesSpec.js b/test/spec/services/notificationServicesSpec.js similarity index 100% rename from test/spec/notificationServicesSpec.js rename to test/spec/services/notificationServicesSpec.js diff --git a/test/spec/userServicesSpec.js b/test/spec/services/userServicesSpec.js similarity index 100% rename from test/spec/userServicesSpec.js rename to test/spec/services/userServicesSpec.js diff --git a/website/public/js/filters/filters.js b/website/public/js/filters/filters.js deleted file mode 100644 index cb59c76042..0000000000 --- a/website/public/js/filters/filters.js +++ /dev/null @@ -1,52 +0,0 @@ -angular.module('habitrpg') - .filter('gold', function () { - return function (gp) { - return Math.floor(gp); - } - }) - .filter('silver', function () { - return function (gp) { - return Math.floor((gp - Math.floor(gp))*100); - } - }) - .filter('htmlDecode',function(){ - return function(html){ - return $('
').html(html).text(); - } - }) - .filter('goldRoundThousandsToK', function(){ - return function (gp) { - return (gp > 999999999) ? (gp / Math.pow(10, 9)).toFixed(1) + "b" : - (gp > 999999) ? (gp / Math.pow(10, 6)).toFixed(1) + "m" : - (gp > 999) ? (gp / Math.pow(10, 3)).toFixed(1) + "k" : gp; - } - }) - .filter('conditionalOrderBy', ['$filter', function($filter) { - return function (array, predicate, sortPredicate, reverseOrder) { - if (predicate) { - return $filter('orderBy')(array, sortPredicate, reverseOrder); - } - return array; - }; - }]) - .filter('filterByTextAndNotes', ['$filter', function($filter) { - return function (input, term) { - if (!input) return; - - if (!angular.isString(term) || term.legth === 0) { - return input; - } - - term = new RegExp(term, 'i'); - - var result = [], i; - - for (i = 0; i < input.length; i++) { - if (term.test(input[i].text) || term.test(input[i].notes)) { - result.push(input[i]); - } - } - - return result; - }; - }]); diff --git a/website/public/js/filters/money.js b/website/public/js/filters/money.js new file mode 100644 index 0000000000..ae22604d49 --- /dev/null +++ b/website/public/js/filters/money.js @@ -0,0 +1,11 @@ +angular.module('habitrpg') + .filter('gold', function () { + return function (gp) { + return Math.floor(gp); + } + }) + .filter('silver', function () { + return function (gp) { + return Math.floor((gp - Math.floor(gp))*100); + } + }); diff --git a/website/public/js/filters/roundLargeNumbers.js b/website/public/js/filters/roundLargeNumbers.js new file mode 100644 index 0000000000..9eebd6c546 --- /dev/null +++ b/website/public/js/filters/roundLargeNumbers.js @@ -0,0 +1,30 @@ +angular.module('habitrpg') + .filter('roundLargeNumbers', function(){ + return function (num) { + return _calculateRoundedNumber(num); + } + }); + +function _calculateRoundedNumber(num) { + if (num > 999999999) { + return _convertToBillion(num); + } else if (num > 999999) { + return _convertToMillion(num); + } else if (num > 999) { + return _convertToThousand(num); + } else { + return num; + } +} + +function _convertToThousand(num) { + return (num / Math.pow(10, 3)).toFixed(1) + "k"; +} + +function _convertToMillion(num) { + return (num / Math.pow(10, 6)).toFixed(1) + "m"; +} + +function _convertToBillion(num) { + return (num / Math.pow(10, 9)).toFixed(1) + "b"; +} diff --git a/website/public/js/filters/taskOrdering.js b/website/public/js/filters/taskOrdering.js new file mode 100644 index 0000000000..42abd471c0 --- /dev/null +++ b/website/public/js/filters/taskOrdering.js @@ -0,0 +1,30 @@ +angular.module('habitrpg') + .filter('conditionalOrderBy', ['$filter', function($filter) { + return function (array, predicate, sortPredicate, reverseOrder) { + if (predicate) { + return $filter('orderBy')(array, sortPredicate, reverseOrder); + } + return array; + }; + }]) + .filter('filterByTextAndNotes', ['$filter', function($filter) { + return function (input, term) { + if (!input) return; + + if (!angular.isString(term) || term.legth === 0) { + return input; + } + + term = new RegExp(term, 'i'); + + var result = []; + + for (var i = 0; i < input.length; i++) { + if (term.test(input[i].text) || term.test(input[i].notes)) { + result.push(input[i]); + } + } + + return result; + }; + }]); diff --git a/website/public/manifest.json b/website/public/manifest.json index 7436040c57..d7afa0e961 100644 --- a/website/public/manifest.json +++ b/website/public/manifest.json @@ -38,6 +38,7 @@ "js/app.js", "common/script/public/config.js", + "js/services/sharedServices.js", "js/services/notificationServices.js", "common/script/public/userServices.js", @@ -48,7 +49,9 @@ "js/services/challengeServices.js", "js/services/paymentServices.js", - "js/filters/filters.js", + "js/filters/money.js", + "js/filters/roundLargeNumbers.js", + "js/filters/taskOrdering.js", "js/directives/focus-me.directive.js", "js/directives/from-now.directive.js", diff --git a/website/views/options/social/boss.jade b/website/views/options/social/boss.jade index 1574f648e8..6411462bbe 100644 --- a/website/views/options/social/boss.jade +++ b/website/views/options/social/boss.jade @@ -52,13 +52,13 @@ mixin boss(tavern, mobile) .meter.health .bar(style='width: {{Shared.percent(progress.hp, boss.hp)}}%;') span.meter-text.value - | {{Math.ceil(progress.hp) | goldRoundThousandsToK}} / {{boss.hp | goldRoundThousandsToK}} + | {{Math.ceil(progress.hp) | roundLargeNumbers}} / {{boss.hp | roundLargeNumbers}} .meter-label(tooltip='Rage', ng-if='boss.rage') span.glyphicon.glyphicon-fire .meter.mana(ng-if='boss.rage',popover="{{::boss.rage.description()}}",popover-title="{{::boss.rage.title()}}",popover-trigger='mouseenter',popover-placement='right') .bar(style='width: {{Shared.percent(progress.rage, boss.rage.value)}}%;') span.meter-text.value - | {{Math.ceil(progress.rage) | goldRoundThousandsToK}} / {{boss.rage.value | goldRoundThousandsToK}} + | {{Math.ceil(progress.rage) | roundLargeNumbers}} / {{boss.rage.value | roundLargeNumbers}} div(ng-if='::Content.quests[group.quest.key].collect') div(class="quest_{{::group.quest.key}}") h4=env.t('collected') + ':' diff --git a/website/views/shared/header/menu.jade b/website/views/shared/header/menu.jade index ebfdd6a6ff..6f77f79fe6 100644 --- a/website/views/shared/header/menu.jade +++ b/website/views/shared/header/menu.jade @@ -264,7 +264,7 @@ nav.toolbar(ng-controller='AuthCtrl', ng-class='{active: isToolbarHidden}') span.gem-text {{user.balance * 4 | number:0}} li.toolbar-currency.gold(popover=env.t('gold') + ' ({{Shared.gold(user.stats.gp)}})', popover-placement='bottom',popover-trigger='mouseenter') span.shop_gold - span {{Shared.gold(user.stats.gp) | goldRoundThousandsToK}} + span {{Shared.gold(user.stats.gp) | roundLargeNumbers}} li.toolbar-currency.silver(popover=env.t('silver'), popover-placement='bottom',popover-trigger='mouseenter') span.shop_silver span {{Shared.silver(user.stats.gp)}}