From 6ebf8605e8c5746da3daa7ee4f684c2ab77c260c Mon Sep 17 00:00:00 2001 From: coyotte508 Date: Thu, 2 Feb 2017 06:51:32 +0100 Subject: [PATCH] Add mocha tests from @caresx A few are outdated and should be fixed (I fixed some too!) --- .gitignore | 3 + app/assets/javascript/afterload.js | 2 + app/assets/javascript/pokeinfo.js | 44 -------- app/assets/javascript/utils.js | 25 ++--- package.json | 10 +- test/abilityinfo.js | 48 +++++++++ test/genderinfo.js | 13 +++ test/geninfo.js | 62 +++++++++++ test/mocha.opts | 3 + test/moveinfo.js | 43 ++++++++ test/pokeinfo.js | 72 +++++++++++++ test/statinfo.js | 20 ++++ test/statusinfo.js | 21 ++++ test/typeinfo.js | 34 ++++++ test/utilities.js | 164 +++++++++++++++++++++++++++++ webpack.config-test.js | 6 ++ 16 files changed, 510 insertions(+), 60 deletions(-) create mode 100644 test/abilityinfo.js create mode 100644 test/genderinfo.js create mode 100644 test/geninfo.js create mode 100644 test/mocha.opts create mode 100644 test/moveinfo.js create mode 100644 test/pokeinfo.js create mode 100644 test/statinfo.js create mode 100644 test/statusinfo.js create mode 100644 test/typeinfo.js create mode 100644 test/utilities.js create mode 100644 webpack.config-test.js diff --git a/.gitignore b/.gitignore index 5d14982d..e2a7db27 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,6 @@ bower_components #Copied from bower components by grunt concat app/assets/stylesheets/colorpicker.less + +#mocha +.tmp diff --git a/app/assets/javascript/afterload.js b/app/assets/javascript/afterload.js index f8271045..e76a9eaf 100644 --- a/app/assets/javascript/afterload.js +++ b/app/assets/javascript/afterload.js @@ -4,8 +4,10 @@ import {afterLoad as playerList} from "./playerlistui"; import {afterLoad as chat} from "./chat"; import {afterLoad as pms} from "./pms/pmlistui"; import {afterLoad as battles} from "./battles/battlelistui"; +import {afterLoad as utils} from "./utils"; export default function() { + utils(); chat(); playerList(); channelList(); diff --git a/app/assets/javascript/pokeinfo.js b/app/assets/javascript/pokeinfo.js index 754d2d3d..fe216d34 100644 --- a/app/assets/javascript/pokeinfo.js +++ b/app/assets/javascript/pokeinfo.js @@ -250,50 +250,6 @@ PokeInfo.sprite = function(poke, params) { return path; }; -PokeInfo.battlesprite = function(poke, params) { - params = params || {}; - - var back = params.back || false; - var data = PokeInfo.spriteData(poke, params); - - var path = pokedex.generations.options[GenInfo.lastGen.num].sprite_folder; - if ((data.ext || "gif") === "gif") { - path += "animated/"; - } - if (back) { - path += "back/"; - } - if (poke.shiny) { - path += "shiny/"; - } - if (poke.female) { - path += "female/"; - } - if ((data.ext || "gif") === "gif") { - path += ("00" + poke.num).slice(-3); - } else { - path += poke.num; - } - if (poke.forme && !data.noforme) { - path += "-" + poke.forme; - } - path += "." + (data.ext || "gif"); - - return path; -}; - -PokeInfo.spriteData = function(poke, params) { - var back = (params || {}).back || false; - var num = this.toNum(poke); - - var ret = (back ? pokedex.pokes.images.back[num] : pokedex.pokes.images[num]); - if (!ret) { - ret = (back ? pokedex.pokes.images.back[num%65356] : pokedex.pokes.images[num%65356]) || {"w":96,"h":96}; - ret.noforme = true; - } - return ret; -}; - PokeInfo.icon = function(poke) { poke = this.toObject(poke); return "/images/icons/" + poke.num + (poke.forme ? "-" + poke.forme : "") + ".png"; diff --git a/app/assets/javascript/utils.js b/app/assets/javascript/utils.js index 4a6eef55..62f4239c 100644 --- a/app/assets/javascript/utils.js +++ b/app/assets/javascript/utils.js @@ -23,11 +23,6 @@ export function queryField(key, defaultStr, query) { return (match && decodeURIComponent(match[1].replace(/\+/g, " "))) || defaultStr; } -// HTML utilities -export function escapeHtmlQuotes(str) { - return str.replace(/"/g, """).replace(/'/g, "'"); -} - export function escapeHtml(str) { return (str || "").replace(/&/g, "&") .replace(/ ({[d]: GenInfo.version(d)}))).should.eql(pokedex.gens.versions); + GenInfo.list().length.should.equal(Object.keys(pokedex.gens.versions).length); + }); + }); + describe('.name', function () { + it('should return the generation name if it exists', function () { + GenInfo.name(3).should.equal("Generation 3"); + GenInfo.name({num: 4}).should.equal("Generation 4"); + GenInfo.name(6).should.equal("Generation 6"); + should(GenInfo.name(-1)).equal(undefined); + should(GenInfo.name({num: "Generation 1"})).equal(undefined); + }); + }); + describe('.options', function () { + it('should return the list of generation options', function () { + GenInfo.options().should.equal(pokedex.generations.options); + Object.keys(GenInfo.options()).length.should.equal(numGens); + }); + }); + describe('.option', function () { + it('should return options specific to a generation if given', function () { + GenInfo.option(1).sprite_folder.should.equal('http://pokemon-online.eu/images/pokemon/red-blue/'); + GenInfo.option(2).ability.should.equal(false); + GenInfo.option({num: 4}).gender.should.equal(true); + should(GenInfo.option(-1)).equal(undefined); + GenInfo.option(6).animated.should.equal(true); + GenInfo.option(7).animated.should.equal(false); + }); + }); + describe('.hasOption', function () { + it('should return true or false depending on if given gen has that option enabled', function () { + GenInfo.hasOption(1, 'sprite_folder').should.equal(true); + GenInfo.hasOption(2, 'ability').should.equal(false); + GenInfo.hasOption({num: 4}, 'gender').should.equal(true); + }); + }); +}); diff --git a/test/mocha.opts b/test/mocha.opts new file mode 100644 index 00000000..a782c5d1 --- /dev/null +++ b/test/mocha.opts @@ -0,0 +1,3 @@ +--require should +--reporter spec +--ui bdd diff --git a/test/moveinfo.js b/test/moveinfo.js new file mode 100644 index 00000000..5118d9c6 --- /dev/null +++ b/test/moveinfo.js @@ -0,0 +1,43 @@ +var should = require("should"); + +import {MoveInfo} from '../app/assets/javascript/pokeinfo'; +import '../app/assets/javascript/pokedex-full'; + +describe('moveinfo', function () { + describe('.accuracy', function () { + it('should resolve data from older/newer gens when not found', function () { + MoveInfo.accuracy(3, 1).should.equal(85); + }); + }); + describe('.category', function () { + it('should resolve data from older/newer gens when not found', function () { + MoveInfo.category(44, 3).should.equal(1); + }); + }); + describe('.effect', function () { + it('should resolve data from older/newer gens when not found', function () { + MoveInfo.effect(34, 4).should.equal("Has a $effect_chance% chance to paralyze the target."); + }); + }); + describe('.pp', function () { + it('should resolve data from older/newer gens when not found', function () { + MoveInfo.pp(26, 2).should.equal(25); + }); + }); + describe('.type', function () { + it('should resolve data from older/newer gens when not found', function () { + // Flower Shield + MoveInfo.type(592).should.equal(17); + }); + }); + describe('.power', function () { + it('should resolve data from older/newer gens when not found', function () { + MoveInfo.power(143, 2).should.equal(140); + }); + it("should use the given gen's data", function () { + // Crabhammer: 90 in 5th, 100 in 6th + MoveInfo.power(152, 5).should.equal(90); + MoveInfo.power(152, 6).should.equal(100); + }); + }); +}); diff --git a/test/pokeinfo.js b/test/pokeinfo.js new file mode 100644 index 00000000..f486aba5 --- /dev/null +++ b/test/pokeinfo.js @@ -0,0 +1,72 @@ +var should = require("should"); + +import {PokeInfo} from '../app/assets/javascript/pokeinfo'; +import '../app/assets/javascript/pokedex-full'; + +describe('pokeinfo', function () { + describe('.toNum', function () { + it('should return a number if given one', function () { + PokeInfo.toNum(40).should.equal(40); + }); + it('should deal with formes', function () { + PokeInfo.toNum({num: 3, forme: 1}).should.equal((1 << 16) + 3); + }); + }); + + describe('.toArray', function () { + it('should convert numbers to arrays', function () { + PokeInfo.toArray(493).should.eql([493, 0]); + PokeInfo.toArray(200).should.eql([200, 0]); + }); + it('should convert strings to arrays', function () { + PokeInfo.toArray("493").should.eql([493, 0]); + PokeInfo.toArray("493-2").should.eql([493, 2]); + PokeInfo.toArray("262637").should.eql([493, 4]); + }); + it('should fix up arrays', function () { + PokeInfo.toArray(["493", "0"]).should.eql([493, 0]); + }); + }); + + describe('.types', function () { + it('should resolve data from older/newer gens when not found', function () { + // Pidgeot + PokeInfo.types(18, 4).should.eql([0, 2]); // Normal Flying + + // Clefairy in gen 1 + PokeInfo.types(35, 1).should.eql([0]); // Normal + // Clefairy in gen 6 + PokeInfo.types(35).should.eql([17]); // Fairy + + // Retest, to make sure internal expand didn't touch anything + // Clefairy in gen 1 + PokeInfo.types(35, 1).should.eql([0]); // Normal + // Clefairy in gen 6 + PokeInfo.types(35).should.eql([17]); // Fairy + }); + }); + + describe('.stats', function () { + it("should use the given gen's data", function () { + // Butterfree + PokeInfo.stats(12, 3).should.eql([60, 45, 50, 80, 80, 70]); + PokeInfo.stats(12, 6).should.eql([60, 45, 50, 90, 80, 70]); + }); + }); + + describe('.sprite', function () { + it('should generate sprite urls from parameters', function () { + PokeInfo.sprite({num: 1, gen: 6}).should.equal("http://pokemon-online.eu/images/pokemon/x-y/animated/001.gif"); + PokeInfo.sprite({num: 1, gen: {num: 6}}).should.equal("http://pokemon-online.eu/images/pokemon/x-y/animated/001.gif"); + PokeInfo.sprite({num: 1}).should.equal("http://pokemon-online.eu/images/pokemon/x-y/animated/001.gif"); + PokeInfo.sprite({num: 3, forme: 1, gen: {num: 6}}).should.equal("http://pokemon-online.eu/images/pokemon/x-y/animated/003-1.gif"); + PokeInfo.sprite({num: 3, forme: 1, gen: {num: 6}}, {back: true}).should.equal("http://pokemon-online.eu/images/pokemon/x-y/animated/back/003-1.gif"); + }); + }); + + describe('.trainerSprite', function () { + it('should generate sprite urls from parameters', function () { + PokeInfo.trainerSprite(200).should.equal('http://pokemon-online.eu/images/trainers/200.png'); + }); + }); +}); diff --git a/test/statinfo.js b/test/statinfo.js new file mode 100644 index 00000000..5d6aad29 --- /dev/null +++ b/test/statinfo.js @@ -0,0 +1,20 @@ +var should = require("should"); +import {StatInfo} from "../app/assets/javascript/pokeinfo"; +import pokedex from "../app/assets/javascript/pokedex"; + +describe('statinfo', function () { + describe('.list', function () { + it('should return the list of stats', function () { + StatInfo.list().should.equal(pokedex.status.stats); + Object.keys(StatInfo.list()).length.should.equal(8); + }); + }); + describe('.name', function () { + it("should return the stat's name", function () { + StatInfo.name(0).should.equal('HP'); + StatInfo.name(3).should.equal('Sp. Att.'); + StatInfo.name(5).should.equal('Speed'); + StatInfo.name(7).should.equal('Evasion'); + }); + }); +}); diff --git a/test/statusinfo.js b/test/statusinfo.js new file mode 100644 index 00000000..0226eab7 --- /dev/null +++ b/test/statusinfo.js @@ -0,0 +1,21 @@ +var should = require("should"); + +import {StatusInfo} from "../app/assets/javascript/pokeinfo"; +import pokedex from "../app/assets/javascript/pokedex"; + +describe('statusinfo', function () { + describe('.list', function () { + it('should return the list of statuses', function () { + StatusInfo.list().should.equal(pokedex.status.status); + Object.keys(StatusInfo.list()).length.should.equal(7); + }); + }); + describe('.name', function () { + it("should return the status' name", function () { + StatusInfo.name(0).should.equal('fine'); + StatusInfo.name(2).should.equal('asleep'); + StatusInfo.name(5).should.equal('poisoned'); + StatusInfo.name(6).should.equal('confused'); + }); + }); +}); diff --git a/test/typeinfo.js b/test/typeinfo.js new file mode 100644 index 00000000..369dcec7 --- /dev/null +++ b/test/typeinfo.js @@ -0,0 +1,34 @@ +var should = require("should"); + +import {TypeInfo} from "../app/assets/javascript/pokeinfo"; +import pokedex from "../app/assets/javascript/pokedex"; + +describe('typeinfo', function () { + describe('.list', function () { + it('should return the list of types', function () { + TypeInfo.list().should.equal(pokedex.types.types); + Object.keys(TypeInfo.list()).length.should.equal(19); + }); + }); + describe('.name', function () { + it('should return the type name', function () { + TypeInfo.name(0).should.equal('Normal'); + TypeInfo.name(17).should.equal('Fairy'); + TypeInfo.name(18).should.equal('???'); + }); + }); + describe('.categoryList', function () { + it('should return the list of categories', function () { + TypeInfo.categoryList().should.equal(pokedex.types.category); + Object.keys(TypeInfo.categoryList()).length.should.equal(19); + }); + }); + describe('.category', function () { + it('should return the category id', function () { + TypeInfo.category(0).should.equal(1); + TypeInfo.category(9).should.equal(2); + TypeInfo.category(14).should.equal(2); + TypeInfo.category(18).should.equal(1); + }); + }); +}); diff --git a/test/utilities.js b/test/utilities.js new file mode 100644 index 00000000..a5b80bb4 --- /dev/null +++ b/test/utilities.js @@ -0,0 +1,164 @@ +var should = require('should'); + +import { + toAlphanumeric, + addDatePadding, + addChannelLinks, + unenumerable, + rank, + onEnterPressed +} from "../app/assets/javascript/utils"; + +describe('utils', function() { + describe('.toAlphanumeric', function() { + it('should remove non-alphanumeric characters and lower case the string', function() { + toAlphanumeric(30).should.equal('30'); + toAlphanumeric(1.301).should.equal('1301'); + toAlphanumeric('abcdef1234').should.equal('abcdef1234'); + toAlphanumeric('AB-C').should.equal('abc'); + toAlphanumeric({}).should.equal('objectobject'); // [object Object] + }); + }); + + describe('.inherits', function() { + // No tests for now + }); + + describe('.queryField', function() { + // ... + }); + + describe('.escapeHtml', function() {}); + + describe('.stripHtml', function() {}); + + describe('.addDatePadding', function() { + it('should prefix a 0 to a number if it is below 10', function() { + addDatePadding(0).should.equal('00'); + addDatePadding(10).should.equal('10'); + addDatePadding(9).should.equal('09'); + }); + }); + + describe('.timestamp', function() { + // ... + }); + + describe('.addChannelLinks', function() { + var chans = [ + 'tohjo', + 'tohjo falls', + 'tournaments', + 'mafia', + 'trivia', + 'hangman' + ]; + + it('should add links to channel tags', function() { + addChannelLinks('#Tohjo', chans).should.equal("#Tohjo"); + + // Case sensitive + addChannelLinks('#tohjo', chans).should.equal("#tohjo"); + + // Two channels + addChannelLinks('#Tohjo #Hangman', chans).should.equal("#Tohjo #Hangman"); + + // Longest match wins + addChannelLinks('#Tohjo Falls #Tohjo', chans).should.equal("#Tohjo Falls #Tohjo"); + addChannelLinks('#Tohjo #Tohjo Falls', chans).should.equal("#Tohjo #Tohjo Falls"); + + addChannelLinks('#Mafia Tutoring', chans).should.equal("#Mafia Tutoring"); + }); + + it('should not add links to non-existent channels', function() { + addChannelLinks('No channels here.', chans).should.equal('No channels here.'); + addChannelLinks('#Indigo Plateau', chans).should.equal('#Indigo Plateau'); + }); + }); + + describe('.unenumerable', function() { + var obj = {}; + + function func() {} + + function ts() { + return '[object obj]'; + } + + it('should add properties to an object with [[Enumerable]] being false', function() { + var hasFunc = false, + i; + unenumerable(obj, 'f', func); + obj.f.should.equal(func); + + for (i in obj) { + if (i === 'f') { + hasFunc = true; + break; + } + } + + hasFunc.should.equal(false); + }); + + it('should not overwrite own properties', function() { + unenumerable(obj, 'toString', ts); // toString is not an own property, fine + obj.toString.should.equal(ts); + obj.toString().should.equal('[object obj]'); + + // f is an own property, don't overwrite + unenumerable(obj, 'f', ts); + obj.f.should.equal(func); + should(obj.f()).equal(undefined); + }); + }); + + describe('.rank', function() { + var set2 = ['', '~', '~', '%', ''], + rangeTest = ['a', '', '', '', 'b']; + it('should replace an auth level with a rank icon', function() { + rank(0).should.equal(''); + rank(3).should.equal('+'); + }); + + it('should accept custom rank sets', function() { + rank(0, set2).should.equal(''); + rank(1, set2).should.equal('~'); + rank(2, set2).should.equal('~'); + rank(3, set2).should.equal('%'); + rank(4, set2).should.equal(''); + }); + + it('should range limit auth', function() { + rank(-3, rangeTest).should.equal('a'); + rank(1000, rangeTest).should.equal('b'); + }); + }); + + describe('.rankStyle', function() { + // ... + }); + + describe('.onEnterPressed', function() { + it('should return a wrapper around the callback listening to enter events', function() { + var called = false; + // Additional argument verification + function cb(event) { + called = event.which === 13; + } + + // Event code is 13, cb should have been called + onEnterPressed(cb)({ + which: 13 + }); + called.should.equal(true); + + called = false; + // Which is not 13, should not have been called. + onEnterPressed(cb)({ + which: 1 + }); + called.should.equal(false); + }); + }); +}); \ No newline at end of file diff --git a/webpack.config-test.js b/webpack.config-test.js new file mode 100644 index 00000000..bba055a5 --- /dev/null +++ b/webpack.config-test.js @@ -0,0 +1,6 @@ +var nodeExternals = require('webpack-node-externals'); + +module.exports = { + target: 'node', // in order to ignore built-in modules like path, fs, etc. + externals: [nodeExternals()], // in order to ignore all modules in node_modules folder +}; \ No newline at end of file