mirror of
https://github.com/home-assistant/frontend.git
synced 2025-12-24 20:55:49 +00:00
Use browser default time and number formatting with polyfills if needed (#9481)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
64
test/common/string/format_number.ts
Normal file
64
test/common/string/format_number.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { assert } from "chai";
|
||||
|
||||
import { formatNumber } from "../../../src/common/number/format_number";
|
||||
import {
|
||||
FrontendLocaleData,
|
||||
NumberFormat,
|
||||
TimeFormat,
|
||||
} from "../../../src/data/translation";
|
||||
|
||||
describe("formatNumber", () => {
|
||||
// Create default to not have to specify a not relevant TimeFormat over and over again.
|
||||
const defaultLocale: FrontendLocaleData = {
|
||||
language: "en",
|
||||
number_format: NumberFormat.language,
|
||||
time_format: TimeFormat.language,
|
||||
};
|
||||
|
||||
// Node only ships with English support for `Intl`, so we can not test for other number formats here.
|
||||
it("Formats English numbers", () => {
|
||||
assert.strictEqual(formatNumber(1234.5, defaultLocale), "1,234.5");
|
||||
});
|
||||
|
||||
it("Test format 'none' (keep dot despite language 'de')", () => {
|
||||
assert.strictEqual(
|
||||
formatNumber(1.23, {
|
||||
...defaultLocale,
|
||||
language: "de",
|
||||
number_format: NumberFormat.none,
|
||||
}),
|
||||
"1.23"
|
||||
);
|
||||
});
|
||||
|
||||
it("Ensure zero is kept for format 'language'", () => {
|
||||
assert.strictEqual(formatNumber(0, defaultLocale), "0");
|
||||
});
|
||||
|
||||
it("Ensure zero is kept for format 'none'", () => {
|
||||
assert.strictEqual(
|
||||
formatNumber(0, { ...defaultLocale, number_format: NumberFormat.none }),
|
||||
"0"
|
||||
);
|
||||
});
|
||||
|
||||
it("Test empty string input for format 'none'", () => {
|
||||
assert.strictEqual(
|
||||
formatNumber("", { ...defaultLocale, number_format: NumberFormat.none }),
|
||||
""
|
||||
);
|
||||
});
|
||||
|
||||
it("Test empty string input for format 'language'", () => {
|
||||
assert.strictEqual(formatNumber("", defaultLocale), "0");
|
||||
});
|
||||
|
||||
it("Formats number with options", () => {
|
||||
assert.strictEqual(
|
||||
formatNumber(1234.5, defaultLocale, {
|
||||
minimumFractionDigits: 2,
|
||||
}),
|
||||
"1,234.50"
|
||||
);
|
||||
});
|
||||
});
|
||||
12
test/common/string/is_date.ts
Normal file
12
test/common/string/is_date.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { assert } from "chai";
|
||||
import { isDate } from "../../../src/common/string/is_date";
|
||||
|
||||
describe("isDate", () => {
|
||||
assert.strictEqual(isDate("ABC"), false);
|
||||
|
||||
assert.strictEqual(isDate("2021-02-03", false), true);
|
||||
assert.strictEqual(isDate("2021-02-03", true), true);
|
||||
|
||||
assert.strictEqual(isDate("2021-05-25T19:23:52+00:00", true), true);
|
||||
assert.strictEqual(isDate("2021-05-25T19:23:52+00:00", false), false);
|
||||
});
|
||||
118
test/common/string/sequence_matching.test.ts
Normal file
118
test/common/string/sequence_matching.test.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
import { assert } from "chai";
|
||||
|
||||
import {
|
||||
fuzzyFilterSort,
|
||||
fuzzySequentialMatch,
|
||||
ScorableTextItem,
|
||||
} from "../../../src/common/string/filter/sequence-matching";
|
||||
|
||||
describe("fuzzySequentialMatch", () => {
|
||||
const item: ScorableTextItem = {
|
||||
strings: ["automation.ticker", "Stocks"],
|
||||
};
|
||||
|
||||
const createExpectation: (
|
||||
pattern,
|
||||
expected
|
||||
) => {
|
||||
pattern: string;
|
||||
expected: string | number | undefined;
|
||||
} = (pattern, expected) => ({
|
||||
pattern,
|
||||
expected,
|
||||
});
|
||||
|
||||
const shouldMatchEntity = [
|
||||
createExpectation("automation.ticker", 131),
|
||||
createExpectation("automation.ticke", 121),
|
||||
createExpectation("automation.", 82),
|
||||
createExpectation("au", 10),
|
||||
createExpectation("automationticker", 85),
|
||||
createExpectation("tion.tick", 8),
|
||||
createExpectation("ticker", -4),
|
||||
createExpectation("automation.r", 73),
|
||||
createExpectation("tick", -8),
|
||||
createExpectation("aumatick", 9),
|
||||
createExpectation("aion.tck", 4),
|
||||
createExpectation("ioticker", -4),
|
||||
createExpectation("atmto.ikr", -34),
|
||||
createExpectation("uoaintce", -39),
|
||||
createExpectation("au.tce", -3),
|
||||
createExpectation("tomaontkr", -19),
|
||||
createExpectation("s", 1),
|
||||
createExpectation("stocks", 42),
|
||||
createExpectation("sks", -5),
|
||||
];
|
||||
|
||||
const shouldNotMatchEntity = [
|
||||
"",
|
||||
" ",
|
||||
"abcdefghijklmnopqrstuvwxyz",
|
||||
"automation.tickerz",
|
||||
"automation. ticke",
|
||||
"1",
|
||||
"noitamotua",
|
||||
"autostocks",
|
||||
"stox",
|
||||
];
|
||||
|
||||
describe(`Entity '${item.strings[0]}'`, () => {
|
||||
for (const expectation of shouldMatchEntity) {
|
||||
it(`matches '${expectation.pattern}' with return of '${expectation.expected}'`, () => {
|
||||
const res = fuzzySequentialMatch(expectation.pattern, item);
|
||||
assert.equal(res, expectation.expected);
|
||||
});
|
||||
}
|
||||
|
||||
for (const badFilter of shouldNotMatchEntity) {
|
||||
it(`fails to match with '${badFilter}'`, () => {
|
||||
const res = fuzzySequentialMatch(badFilter, item);
|
||||
assert.equal(res, undefined);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("fuzzyFilterSort", () => {
|
||||
const filter = "ticker";
|
||||
const automationTicker = {
|
||||
strings: ["automation.ticker", "Stocks"],
|
||||
score: 0,
|
||||
};
|
||||
const ticker = {
|
||||
strings: ["ticker", "Just ticker"],
|
||||
score: 0,
|
||||
};
|
||||
const sensorTicker = {
|
||||
strings: ["sensor.ticker", "Stocks up"],
|
||||
score: 0,
|
||||
};
|
||||
const timerCheckRouter = {
|
||||
strings: ["automation.check_router", "Timer Check Router"],
|
||||
score: 0,
|
||||
};
|
||||
const badMatch = {
|
||||
strings: ["light.chandelier", "Chandelier"],
|
||||
score: 0,
|
||||
};
|
||||
const itemsBeforeFilter = [
|
||||
automationTicker,
|
||||
sensorTicker,
|
||||
timerCheckRouter,
|
||||
ticker,
|
||||
badMatch,
|
||||
];
|
||||
|
||||
it(`filters and sorts correctly`, () => {
|
||||
const expectedItemsAfterFilter = [
|
||||
{ ...ticker, score: 44 },
|
||||
{ ...sensorTicker, score: 1 },
|
||||
{ ...automationTicker, score: -4 },
|
||||
{ ...timerCheckRouter, score: -8 },
|
||||
];
|
||||
|
||||
const res = fuzzyFilterSort(filter, itemsBeforeFilter);
|
||||
|
||||
assert.deepEqual(res, expectedItemsAfterFilter);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user