UNPKG

@sscovil/rtf

Version:

Relative time formatter that leverages Intl.RelativeTimeFormat() under the hood.

179 lines (156 loc) 7.04 kB
import RTF from "./rtf.js"; describe("RTF", () => { describe("instance with default options", () => { let rtf; beforeEach(() => { rtf = new RTF(); }); describe("addLocale", () => { test("returns false if language is not supported", () => { const locale = "invalid"; const result = rtf.addLocale(locale); expect(result).toBe(false); expect(rtf.formatters[locale] instanceof Intl.RelativeTimeFormat).toBe(false); }); test("returns true if language is supported", () => { const locale = "de-DE"; const result = rtf.addLocale(locale); expect(result).toBe(true); expect(rtf.formatters[locale] instanceof Intl.RelativeTimeFormat).toBe(true); }); test("returns true even if language has already been added", () => { const locale = "es"; const result1 = rtf.addLocale(locale); const result2 = rtf.addLocale(locale); expect(result1).toBe(true); expect(result2).toBe(true); expect(rtf.formatters[locale] instanceof Intl.RelativeTimeFormat).toBe(true); }); }); describe("format", () => { test("accepts a Date object as the first argument", () => { const date = new Date(); const result = rtf.format(date); expect(result).toMatch(/(now|1 second ago|2 seconds ago)/); }); test("accepts a UTC string as the first argument", () => { const date = new Date().toUTCString(); const result = rtf.format(date); expect(result).toMatch(/(now|1 second ago|2 seconds ago)/); }); test("accepts a numeric timestamp as the first argument", () => { const date = Date.now(); const result = rtf.format(date); expect(result).toMatch(/(now|1 second ago|2 seconds ago)/); }); test("accepts a locale string as the second argument", () => { const today = new Date(); const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000); const result = rtf.format(yesterday, "zh"); expect(result).toBe("昨天"); }); test("works with future dates", () => { const today = new Date(); const tomorrow = new Date(today.getTime() + 24 * 60 * 60 * 1000); const result = rtf.format(tomorrow); expect(result).toBe("tomorrow"); }); test("formats minutes properly", () => { const today = new Date(); const minutesAgo = new Date(today.getTime() - 30 * 60 * 1000); const result = rtf.format(minutesAgo); expect(result).toBe("30 minutes ago"); }); test("formats hours properly", () => { const today = new Date(); const hoursAgo = new Date(today.getTime() - 12 * 60 * 60 * 1000); const result = rtf.format(hoursAgo); expect(result).toBe("12 hours ago"); }); test("formats days properly", () => { const today = new Date(); const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000); const result = rtf.format(yesterday); expect(result).toBe("yesterday"); }); test("formats weeks properly", () => { const today = new Date(); const lastWeek = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000); const result = rtf.format(lastWeek); expect(result).toBe("last week"); }); test("formats months properly", () => { const today = new Date(); const lastMonth = new Date(today.getTime() - (365/12) * 24 * 60 * 60 * 1000); const result = rtf.format(lastMonth); expect(result).toBe("last month"); }); test("formats years properly", () => { const today = new Date(); const lastYear = new Date(today.getTime() - 365 * 24 * 60 * 60 * 1000); const result = rtf.format(lastYear); expect(result).toBe("last year"); }); }); }); describe("instance with custom options", () => { let rtf; beforeEach(() => { rtf = new RTF({ localeMatcher: RTF.opt.localeMatcher.lookup, numeric: RTF.opt.numeric.always, style: RTF.opt.style.short }); }); describe("format method", () => { test("uses the specified options", () => { const today = new Date(); const lastWeek = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000); const result = rtf.format(lastWeek, "fr"); expect(result).toBe("il y a 1 sem."); }); }); }); describe("static", () => { describe("httpMiddleware method", () => { test("returns a function", () => { const middleware = RTF.httpMiddleware(); expect(typeof middleware === "function").toBe(true); }); test("middleware adds req.rtf function that formats dates using req.language", (done) => { const rtf = new RTF(); const middleware = RTF.httpMiddleware(rtf); const req = { language: "ja" }; const res = {}; const next = () => { try { const ts = Date.now() - 30 * 60 * 1000; const result = req.rtf(ts); expect(result).toBe("30 分前"); done(); } catch (err) { done(err); } }; middleware(req, res, next); }); test("allows you to specify property names to use for req context", (done) => { const rtf = new RTF(); const middleware = RTF.httpMiddleware(rtf, "relativeTimeFormat", "lng"); const req = { lng: "ru" }; const res = {}; const next = () => { try { const ts = Date.now() - 30 * 60 * 1000; const result = req.relativeTimeFormat(ts); expect(result).toBe("30 минут назад"); done(); } catch (err) { done(err); } }; middleware(req, res, next); }); }); }); });