Add a bunch of client tests

This commit is contained in:
Jérémie Astori 2017-11-29 00:31:03 -05:00
parent 36e0ce46b4
commit f368dcdc69
No known key found for this signature in database
GPG key ID: B9A4F245CD67BDE8
9 changed files with 234 additions and 41 deletions

View file

@ -2,7 +2,7 @@
module.exports = function(count) {
if (count < 1000) {
return count;
return count.toString();
}
return (count / 1000).toFixed(2).slice(0, -1) + "k";

View file

@ -1,5 +1,5 @@
"use strict";
module.exports = function(context) {
return window.JSON.stringify(context);
module.exports = function tojson(context) {
return JSON.stringify(context);
};

View file

@ -0,0 +1,61 @@
"use strict";
const expect = require("chai").expect;
const constants = require("../../../client/js/constants");
describe("client-side constants", function() {
describe(".colorCodeMap", function() {
it("should be a non-empty array", function() {
expect(constants.colorCodeMap).to.be.an("array").of.length(16);
});
it("should be made of pairs of strings", function() {
constants.colorCodeMap.forEach((tuple) => { // TODO: In Node v6+, use `[code, name]`
expect(tuple[0]).to.be.a("string").that.match(/[0-9]{2}/);
expect(tuple[1]).to.be.a("string");
});
});
});
describe(".commands", function() {
it("should be a non-empty array", function() {
expect(constants.commands).to.be.an("array").that.is.not.empty;
});
it("should only contain strings with no whitespaces and starting with /", function() {
constants.commands.forEach((command) => {
expect(command).to.be.a("string").that.does.not.match(/\s/);
expect(command[0]).to.equal("/");
});
});
});
describe(".actionTypes", function() {
it("should be a non-empty array", function() {
expect(constants.actionTypes).to.be.an("array").that.is.not.empty;
});
it("should only contain strings with no whitespaces", function() {
constants.actionTypes.forEach((type) => {
expect(type).to.be.a("string").that.does.not.match(/\s/);
});
});
});
describe(".condensedTypes", function() {
it("should be a non-empty array", function() {
expect(constants.condensedTypes).to.be.an("array").that.is.not.empty;
});
it("should be a subset of `actionTypes`", function() {
expect(constants.actionTypes).to.include.members(constants.condensedTypes);
});
});
describe(".timeFormats", function() {
it("should be objects of strings", function() {
expect(constants.timeFormats.msgDefault).to.be.an("string").that.is.not.empty;
expect(constants.timeFormats.msgWithSeconds).to.be.an("string").that.is.not.empty;
});
});
});

View file

@ -0,0 +1,19 @@
"use strict";
const expect = require("chai").expect;
const localedate = require("../../../../../client/js/libs/handlebars/localedate");
describe("localedate Handlebars helper", function() {
it("should render a human-readable date", function() {
// 12PM in UTC time
const date = new Date("2014-05-22T12:00:00Z");
// Offset between UTC and local timezone
const offset = date.getTimezoneOffset() * 60 * 1000;
// Pretend local timezone is UTC by moving the clock of that offset
const time = date.getTime() + offset;
expect(localedate(time)).to.equal("22 May 2014");
});
});

View file

@ -0,0 +1,23 @@
"use strict";
const expect = require("chai").expect;
const modes = require("../../../../../client/js/libs/handlebars/modes");
describe("modes Handlebars helper", function() {
it("should return text modes based on symbols", function() {
expect(modes("~")).to.equal("owner");
expect(modes("&")).to.equal("admin");
expect(modes("!")).to.equal("admin");
expect(modes("@")).to.equal("op");
expect(modes("%")).to.equal("half-op");
expect(modes("+")).to.equal("voice");
});
it("should return no special mode when given an empty string", function() {
expect(modes("")).to.equal("normal");
});
it("should return nothing if the symbol does not exist", function() {
expect(modes("?")).to.be.undefined;
});
});

View file

@ -203,44 +203,57 @@ describe("parse Handlebars helper", () => {
expect(actual).to.deep.equal(expected);
});
it("should style like mirc", () => {
const testCases = [{
input: "\x02bold",
expected: '<span class="irc-bold">bold</span>',
}, {
input: "\x038yellowText",
expected: '<span class="irc-fg8">yellowText</span>',
}, {
input: "\x030,0white,white",
expected: '<span class="irc-fg0 irc-bg0">white,white</span>',
}, {
input: "\x034,8yellowBGredText",
expected: '<span class="irc-fg4 irc-bg8">yellowBGredText</span>',
}, {
input: "\x1ditalic",
expected: '<span class="irc-italic">italic</span>',
}, {
input: "\x1funderline",
expected: '<span class="irc-underline">underline</span>',
}, {
input: "\x02bold\x038yellow\x02nonBold\x03default",
expected:
'<span class="irc-bold">bold</span>' +
'<span class="irc-bold irc-fg8">yellow</span>' +
'<span class="irc-fg8">nonBold</span>' +
"default",
}, {
input: "\x02bold\x02 \x02bold\x02",
expected:
'<span class="irc-bold">bold</span>' +
" " +
'<span class="irc-bold">bold</span>',
}];
const actual = testCases.map((testCase) => parse(testCase.input));
const expected = testCases.map((testCase) => testCase.expected);
expect(actual).to.deep.equal(expected);
[{
name: "bold",
input: "\x02bold",
expected: '<span class="irc-bold">bold</span>',
}, {
name: "foreground color",
input: "\x038yellowText",
expected: '<span class="irc-fg8">yellowText</span>',
}, {
name: "foreground and background colors (white)",
input: "\x030,0white,white",
expected: '<span class="irc-fg0 irc-bg0">white,white</span>',
}, {
name: "foreground and background colors",
input: "\x034,8yellowBGredText",
expected: '<span class="irc-fg4 irc-bg8">yellowBGredText</span>',
}, {
name: "hex foreground color",
input: "\x04663399rebeccapurple",
expected: '<span style="color:#663399">rebeccapurple</span>',
}, {
name: "hex foreground and background colors",
input: "\x04415364,ff9e18The Lounge",
expected: '<span style="color:#415364;background-color:#FF9E18">The Lounge</span>',
}, {
name: "italic",
input: "\x1ditalic",
expected: '<span class="irc-italic">italic</span>',
}, {
name: "underline",
input: "\x1funderline",
expected: '<span class="irc-underline">underline</span>',
}, {
name: "resets",
input: "\x02bold\x038yellow\x02nonBold\x03default",
expected:
'<span class="irc-bold">bold</span>' +
'<span class="irc-bold irc-fg8">yellow</span>' +
'<span class="irc-fg8">nonBold</span>' +
"default",
}, {
name: "duplicates",
input: "\x02bold\x02 \x02bold\x02",
expected:
'<span class="irc-bold">bold</span>' +
" " +
'<span class="irc-bold">bold</span>',
}].forEach((item) => { // TODO: In Node v6+, use `{name, input, expected}`
it(`should handle style characters: ${item.name}`, function() {
expect(parse(item.input)).to.equal(item.expected);
});
});
it("should find nicks", () => {
@ -312,6 +325,36 @@ describe("parse Handlebars helper", () => {
expect(actual).to.deep.equal(expected);
});
// Emoji
[{
name: "in text",
input: "Hello💬",
expected: 'Hello<span class="emoji">💬</span>',
}, {
name: "with modifiers",
input: "🤷‍♀️",
expected: '<span class="emoji">🤷‍♀️</span>',
}, {
// FIXME: These multiple `span`s should be optimized into a single one. See https://github.com/thelounge/lounge/issues/1783
name: "wrapped in style",
input: "Super \x034💚 green!",
expected: 'Super <span class="emoji"><span class="irc-fg4">💚</span></span><span class="irc-fg4"> green!</span>',
}, {
name: "wrapped in URLs",
input: "https://i.❤️.thelounge.chat",
// FIXME: Emoji in text should be `<span class="emoji">❤️</span>`. See https://github.com/thelounge/lounge/issues/1784
expected: '<a href="https://i.❤️.thelounge.chat" target="_blank" rel="noopener">https://i.❤️.thelounge.chat</a>',
}, {
name: "wrapped in channels",
input: "#i❤thelounge",
// FIXME: Emoji in text should be `<span class="emoji">❤️</span>`. See https://github.com/thelounge/lounge/issues/1784
expected: '<span class="inline-channel" role="button" tabindex="0" data-chan="#i❤thelounge">#i❤thelounge</span>',
}].forEach((item) => { // TODO: In Node v6+, use `{name, input, expected}`
it(`should find emoji: ${item.name}`, function() {
expect(parse(item.input)).to.equal(item.expected);
});
});
it("should optimize generated html", () => {
const testCases = [{
input: 'test \x0312#\x0312\x0312"te\x0312st\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312a',

View file

@ -0,0 +1,24 @@
"use strict";
const expect = require("chai").expect;
const roundBadgeNumber = require("../../../../../client/js/libs/handlebars/roundBadgeNumber");
describe("roundBadgeNumber Handlebars helper", function() {
it("should return any number under 1000 as a string", function() {
expect(roundBadgeNumber(123)).to.equal("123");
});
it("should return numbers above 999 in thousands", function() {
expect(roundBadgeNumber(1000)).to.be.equal("1.0k");
});
it("should round and not floor", function() {
expect(roundBadgeNumber(9999)).to.be.equal("10.0k");
});
it("should always include a single digit when rounding up", function() {
expect(roundBadgeNumber(1234)).to.be.equal("1.2k");
expect(roundBadgeNumber(12345)).to.be.equal("12.3k");
expect(roundBadgeNumber(123456)).to.be.equal("123.4k");
});
});

View file

@ -0,0 +1,10 @@
"use strict";
const expect = require("chai").expect;
const slugify = require("../../../../../client/js/libs/handlebars/slugify");
describe("slugify Handlebars helper", function() {
it("should only produce lowercase strings", function() {
expect(slugify("#TheLounge")).to.equal("\\#thelounge");
});
});

View file

@ -0,0 +1,13 @@
"use strict";
const expect = require("chai").expect;
const tojson = require("../../../../../client/js/libs/handlebars/tojson");
describe("tojson Handlebars helper", function() {
it("should return JSON strings", function() {
expect(tojson([])).to.equal("[]");
expect(tojson({})).to.equal("{}");
expect(tojson("")).to.equal('""');
expect(tojson({foo: "bar"})).to.be.equal('{"foo":"bar"}');
});
});