Odoo18-Base/addons/spreadsheet/static/tests/pivots/pivot_helpers.test.js
2025-01-06 10:57:38 +07:00

270 lines
13 KiB
JavaScript

import { describe, expect, test } from "@odoo/hoot";
import { getFirstListFunction, getNumberOfListFormulas } from "@spreadsheet/list/list_helpers";
import { constants, tokenize, helpers } from "@odoo/o-spreadsheet";
import { patchTranslations } from "@web/../tests/web_test_helpers";
const {
getFirstPivotFunction,
getNumberOfPivotFunctions,
pivotTimeAdapter,
toNormalizedPivotValue,
toNumber,
} = helpers;
const { DEFAULT_LOCALE } = constants;
function stringArg(value) {
return { type: "STRING", value: `${value}` };
}
describe.current.tags("headless");
describe("pivot_helpers", () => {
test("Basic formula extractor", async function () {
const formula = `=PIVOT.VALUE("1", "test") + ODOO.LIST("2", "hello", "bla")`;
const tokens = tokenize(formula);
let functionName;
let args;
({ functionName, args } = getFirstPivotFunction(tokens));
expect(functionName).toBe("PIVOT.VALUE");
expect(args.length).toBe(2);
expect(args[0]).toEqual(stringArg("1"));
expect(args[1]).toEqual(stringArg("test"));
({ functionName, args } = getFirstListFunction(tokens));
expect(functionName).toBe("ODOO.LIST");
expect(args.length).toBe(3);
expect(args[0]).toEqual(stringArg("2"));
expect(args[1]).toEqual(stringArg("hello"));
expect(args[2]).toEqual(stringArg("bla"));
});
test("Extraction with two PIVOT formulas", async function () {
const formula = `=PIVOT.VALUE("1", "test") + PIVOT.VALUE("2", "hello", "bla")`;
const tokens = tokenize(formula);
const { functionName, args } = getFirstPivotFunction(tokens);
expect(functionName).toBe("PIVOT.VALUE");
expect(args.length).toBe(2);
expect(args[0]).toEqual(stringArg("1"));
expect(args[1]).toEqual(stringArg("test"));
expect(getFirstListFunction(tokens)).toBe(undefined);
});
test("Number of formulas", async function () {
const formula = `=PIVOT.VALUE("1", "test") + PIVOT.VALUE("2", "hello", "bla") + ODOO.LIST("1", "bla")`;
expect(getNumberOfPivotFunctions(tokenize(formula))).toBe(2);
expect(getNumberOfListFormulas(tokenize(formula))).toBe(1);
expect(getNumberOfPivotFunctions(tokenize("=1+1"))).toBe(0);
expect(getNumberOfListFormulas(tokenize("=1+1"))).toBe(0);
expect(getNumberOfPivotFunctions(tokenize("=bla"))).toBe(0);
expect(getNumberOfListFormulas(tokenize("=bla"))).toBe(0);
});
test("getFirstPivotFunction does not crash when given crap", async function () {
expect(getFirstListFunction(tokenize("=SUM(A1)"))).toBe(undefined);
expect(getFirstPivotFunction(tokenize("=SUM(A1)"))).toBe(undefined);
expect(getFirstListFunction(tokenize("=1+1"))).toBe(undefined);
expect(getFirstPivotFunction(tokenize("=1+1"))).toBe(undefined);
expect(getFirstListFunction(tokenize("=bla"))).toBe(undefined);
expect(getFirstPivotFunction(tokenize("=bla"))).toBe(undefined);
expect(getFirstListFunction(tokenize("bla"))).toBe(undefined);
expect(getFirstPivotFunction(tokenize("bla"))).toBe(undefined);
});
});
describe("toNormalizedPivotValue", () => {
test("parse values of a selection, char or text field", () => {
for (const fieldType of ["selection", "text", "char"]) {
const dimension = {
type: fieldType,
displayName: "A field",
name: "my_field_name",
};
expect(toNormalizedPivotValue(dimension, "won")).toBe("won");
expect(toNormalizedPivotValue(dimension, "1")).toBe("1");
expect(toNormalizedPivotValue(dimension, 1)).toBe("1");
expect(toNormalizedPivotValue(dimension, "11/2020")).toBe("11/2020");
expect(toNormalizedPivotValue(dimension, "2020")).toBe("2020");
expect(toNormalizedPivotValue(dimension, "01/11/2020")).toBe("01/11/2020");
expect(toNormalizedPivotValue(dimension, "false")).toBe(false);
expect(toNormalizedPivotValue(dimension, false)).toBe(false);
expect(toNormalizedPivotValue(dimension, "true")).toBe("true");
}
});
test("parse values of time fields", () => {
for (const fieldType of ["date", "datetime"]) {
const dimension = {
type: fieldType,
displayName: "A field",
name: "my_field_name",
};
dimension.granularity = "day";
expect(toNormalizedPivotValue(dimension, "1/11/2020")).toBe(43841);
expect(toNormalizedPivotValue(dimension, "01/11/2020")).toBe(43841);
expect(toNormalizedPivotValue(dimension, "11/2020")).toBe(44136);
expect(toNormalizedPivotValue(dimension, "1")).toBe(1);
expect(toNormalizedPivotValue(dimension, 1)).toBe(1);
expect(toNormalizedPivotValue(dimension, "false")).toBe(false);
expect(toNormalizedPivotValue(dimension, false)).toBe(false);
dimension.granularity = "week";
expect(toNormalizedPivotValue(dimension, "11/2020")).toBe("11/2020");
expect(toNormalizedPivotValue(dimension, "1/2020")).toBe("1/2020");
expect(toNormalizedPivotValue(dimension, "01/2020")).toBe("1/2020");
expect(toNormalizedPivotValue(dimension, "false")).toBe(false);
expect(toNormalizedPivotValue(dimension, false)).toBe(false);
dimension.granularity = "month";
expect(toNormalizedPivotValue(dimension, "11/2020")).toBe("11/2020");
expect(toNormalizedPivotValue(dimension, "1/2020")).toBe("01/2020");
expect(toNormalizedPivotValue(dimension, "01/2020")).toBe("01/2020");
expect(toNormalizedPivotValue(dimension, "2/11/2020")).toBe("02/2020");
expect(toNormalizedPivotValue(dimension, "2/1/2020")).toBe("02/2020");
expect(toNormalizedPivotValue(dimension, 1)).toBe("12/1899");
expect(toNormalizedPivotValue(dimension, "false")).toBe(false);
expect(toNormalizedPivotValue(dimension, false)).toBe(false);
expect(() => toNormalizedPivotValue(dimension, "true")).toThrow();
expect(() => toNormalizedPivotValue(dimension, true)).toThrow();
expect(() => toNormalizedPivotValue(dimension, "won")).toThrow();
dimension.granularity = "quarter";
// special quarter syntax:
expect(toNormalizedPivotValue(dimension, "1/2020")).toBe("1/2020");
expect(toNormalizedPivotValue(dimension, "2/2020")).toBe("2/2020");
expect(toNormalizedPivotValue(dimension, "3/2020")).toBe("3/2020");
expect(toNormalizedPivotValue(dimension, "4/2020")).toBe("4/2020");
// falls back on regular date parsing:
expect(toNormalizedPivotValue(dimension, "5/2020")).toBe("2/2020");
expect(toNormalizedPivotValue(dimension, "01/01/2020")).toBe("1/2020");
expect(toNormalizedPivotValue(dimension, toNumber("01/01/2020", DEFAULT_LOCALE))).toBe(
"1/2020"
);
expect(() => toNormalizedPivotValue(dimension, "hello")).toThrow();
dimension.granularity = "year";
expect(toNormalizedPivotValue(dimension, "2020")).toBe(2020);
expect(toNormalizedPivotValue(dimension, 2020)).toBe(2020);
expect(toNormalizedPivotValue(dimension, "false")).toBe(false);
expect(toNormalizedPivotValue(dimension, false)).toBe(false);
}
});
test("parse values of boolean field", () => {
const dimension = {
type: "boolean",
displayName: "A field",
name: "my_field_name",
};
expect(toNormalizedPivotValue(dimension, "false")).toBe(false);
expect(toNormalizedPivotValue(dimension, false)).toBe(false);
expect(toNormalizedPivotValue(dimension, "true")).toBe(true);
expect(toNormalizedPivotValue(dimension, true)).toBe(true);
expect(() => toNormalizedPivotValue(dimension, "11/2020")).toThrow();
expect(() => toNormalizedPivotValue(dimension, "2020")).toThrow();
expect(() => toNormalizedPivotValue(dimension, "01/11/2020")).toThrow();
expect(() => toNormalizedPivotValue(dimension, "1")).toThrow();
expect(() => toNormalizedPivotValue(dimension, 1)).toThrow();
expect(() => toNormalizedPivotValue(dimension, "won")).toThrow();
});
test("parse values of numeric fields", () => {
for (const fieldType of ["float", "integer", "monetary", "many2one", "many2many"]) {
const dimension = {
type: fieldType,
displayName: "A field",
name: "my_field_name",
};
expect(toNormalizedPivotValue(dimension, "2020")).toBe(2020);
expect(toNormalizedPivotValue(dimension, "01/11/2020")).toBe(43841); // a date is actually a number in a spreadsheet
expect(toNormalizedPivotValue(dimension, "11/2020")).toBe(44136); // 1st of november 2020
expect(toNormalizedPivotValue(dimension, "1")).toBe(1);
expect(toNormalizedPivotValue(dimension, 1)).toBe(1);
expect(toNormalizedPivotValue(dimension, "false")).toBe(false);
expect(toNormalizedPivotValue(dimension, false)).toBe(false);
expect(() => toNormalizedPivotValue(dimension, "true")).toThrow();
expect(() => toNormalizedPivotValue(dimension, true)).toThrow();
expect(() => toNormalizedPivotValue(dimension, "won")).toThrow();
}
});
test("parse values of unsupported fields", () => {
for (const fieldType of ["one2many", "binary", "html"]) {
const dimension = {
type: fieldType,
displayName: "A field",
name: "my_field_name",
};
expect(() => toNormalizedPivotValue(dimension, "false")).toThrow();
expect(() => toNormalizedPivotValue(dimension, false)).toThrow();
expect(() => toNormalizedPivotValue(dimension, "true")).toThrow();
expect(() => toNormalizedPivotValue(dimension, true)).toThrow();
expect(() => toNormalizedPivotValue(dimension, "11/2020")).toThrow();
expect(() => toNormalizedPivotValue(dimension, "2020")).toThrow();
expect(() => toNormalizedPivotValue(dimension, "01/11/2020")).toThrow();
expect(() => toNormalizedPivotValue(dimension, "1")).toThrow();
expect(() => toNormalizedPivotValue(dimension, 1)).toThrow();
expect(() => toNormalizedPivotValue(dimension, "won")).toThrow();
}
});
});
describe("pivot time adapters formatted value", () => {
test("Day adapter", () => {
const adapter = pivotTimeAdapter("day");
expect(adapter.toValueAndFormat("11/12/2020", DEFAULT_LOCALE)).toEqual({
value: 44147,
format: "dd mmm yyyy",
});
expect(adapter.toValueAndFormat("01/11/2020", DEFAULT_LOCALE)).toEqual({
value: 43841,
format: "dd mmm yyyy",
});
expect(adapter.toValueAndFormat("12/05/2020", DEFAULT_LOCALE)).toEqual({
value: 44170,
format: "dd mmm yyyy",
});
});
test("Week adapter", () => {
patchTranslations();
const adapter = pivotTimeAdapter("week");
expect(adapter.toValueAndFormat("5/2024", DEFAULT_LOCALE)).toEqual({ value: "W5 2024" });
expect(adapter.toValueAndFormat("51/2020", DEFAULT_LOCALE)).toEqual({
value: "W51 2020",
});
});
test("Month adapter", () => {
patchTranslations();
const adapter = pivotTimeAdapter("month");
expect(adapter.toValueAndFormat("12/2020", DEFAULT_LOCALE)).toEqual({
value: 44166,
format: "mmmm yyyy",
});
expect(adapter.toValueAndFormat("02/2020", DEFAULT_LOCALE)).toEqual({
value: 43862,
format: "mmmm yyyy",
});
});
test("Quarter adapter", () => {
patchTranslations();
const adapter = pivotTimeAdapter("quarter");
expect(adapter.toValueAndFormat("1/2022", DEFAULT_LOCALE)).toEqual({ value: "Q1 2022" });
expect(adapter.toValueAndFormat("3/1998", DEFAULT_LOCALE)).toEqual({ value: "Q3 1998" });
});
test("Year adapter", () => {
const adapter = pivotTimeAdapter("year");
expect(adapter.toValueAndFormat("2020", DEFAULT_LOCALE)).toEqual({
value: 2020,
format: "0",
});
expect(adapter.toValueAndFormat("1997", DEFAULT_LOCALE)).toEqual({
value: 1997,
format: "0",
});
});
});