/* Copyright (c) 2022 Betim Beja and Shko Online LLC Licensed under the MIT license. */ import { stub } from 'sinon'; import type { SinonStub } from 'sinon'; type DateTimeFieldBehavior = ComponentFramework.FormattingApi.Types.DateTimeFieldBehavior; const symbolToCurrency: { [key: string]: string } = { '€': 'EUR', $: 'USD', }; export class FormattingMock implements ComponentFramework.Formatting { formatCurrency: SinonStub<[value: number, precision?: number, currencySymbol?: string], string>; formatDecimal: SinonStub<[value: number, precision?: number], string>; formatDateAsFilterStringInUTC: SinonStub<[value: Date, includeTime?: boolean], string>; formatDateLong: SinonStub<[value: Date], string>; formatDateLongAbbreviated: SinonStub<[value: Date], string>; formatDateShort: SinonStub<[value: Date, includeTime?: boolean], string>; formatDateYearMonth: SinonStub<[value: Date], string>; formatInteger: SinonStub<[value: number], string>; formatLanguage: SinonStub<[value: number], string>; formatTime: SinonStub<[value: Date, behavior: DateTimeFieldBehavior], string>; getWeekOfYear: SinonStub<[value: Date], number>; locale: 'en-US' | 'it-IT' = 'en-US'; constructor() { this.formatCurrency = stub(); this.formatCurrency.callsFake((value: number, precision?: number, currencySymbol?: string) => { const currency = currencySymbol ? symbolToCurrency[currencySymbol] : undefined; return ( (currencySymbol && !currency ? currencySymbol : '') + value.toLocaleString(this.locale, { style: currency ? 'currency' : 'decimal', currency, maximumFractionDigits: precision, minimumFractionDigits: precision, }) ); }); this.formatDecimal = stub(); this.formatDecimal.callsFake((value: number, precision?: number) => { return value.toLocaleString(this.locale, { maximumFractionDigits: precision, minimumFractionDigits: precision }); }); this.formatDateAsFilterStringInUTC = stub(); this.formatDateAsFilterStringInUTC.callsFake((value: Date, includeTime?: boolean) => { return value.toLocaleString(this.locale, { day: '2-digit', year: 'numeric', month: '2-digit', }); }); this.formatDateLong = stub(); this.formatDateLong.callsFake((value: Date) => { return value.toLocaleString(this.locale, { dateStyle: 'long', }); }); this.formatDateLongAbbreviated = stub(); this.formatDateLongAbbreviated.callsFake((value: Date) => { return value.toLocaleString(this.locale, { dateStyle: 'medium', }); }); this.formatDateShort = stub(); this.formatDateShort.callsFake((value: Date, includeTime?: boolean) => { if (includeTime === true) { return value .toLocaleString(this.locale, { dateStyle: 'short', timeStyle: 'short', }) .replace(',', ''); } return value.toLocaleDateString(this.locale, { dateStyle: 'short', }); }); this.formatDateYearMonth = stub(); this.formatDateYearMonth.callsFake((value: Date) => { return value.toLocaleString(this.locale, { year: 'numeric', month: 'long', }); }); this.formatInteger = stub(); this.formatInteger.callsFake((value: number) => { return value.toLocaleString(this.locale, {}); }); this.formatLanguage = stub(); this.formatLanguage.callsFake((value: number) => { return `${value}`; }); this.formatTime = stub(); this.formatTime.callsFake((value: Date, behavior: DateTimeFieldBehavior) => { throw new Error('Method not implemented.'); }); this.getWeekOfYear = stub(); this.getWeekOfYear.callsFake((value: Date) => { const leapYear = value.getFullYear() % 4 === 0; const monthDays = [31, leapYear ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; let dayOfYear = 0; for (let i = 0; i < value.getMonth(); i++) { dayOfYear += monthDays[i]; } dayOfYear += value.getDate(); return Math.ceil(dayOfYear / 7); }); } }