Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions src/__tests__/applyCssUnits.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { describe, expect, it } from "vitest";
import { applyCssUnits } from "../helpers";
import { type CSSUnitMap } from "../types";

describe("applyCssUnits", () => {
it("returns string values as-is", () => {
expect(applyCssUnits("fontSize", "2em")).toBe("2em");
expect(applyCssUnits("color", "red")).toBe("red");
});

it('returns "0" as-is (without unit)', () => {
expect(applyCssUnits("marginTop", 0)).toBe("0");
});

it("applies default px unit to numeric values", () => {
expect(applyCssUnits("marginTop", 10)).toBe("10px");
});

it("uses custom unit string when provided", () => {
expect(applyCssUnits("fontSize", 1.5, "em")).toBe("1.5em");
});

it("uses unit map when provided", () => {
const unitMap: CSSUnitMap = {
fontSize: "rem",
marginTop: "%",
};
expect(applyCssUnits("fontSize", 2, unitMap)).toBe("2rem");
expect(applyCssUnits("marginTop", 5, unitMap)).toBe("5%");
});

it("falls back to default px if unit not found in map", () => {
expect(applyCssUnits("paddingLeft", 8, {})).toBe("8px");
});

it("omits unit for known unitless properties", () => {
// @emotion/unitless is used to define unitless properties
expect(applyCssUnits("lineHeight", 1.2)).toBe("1.2");
expect(applyCssUnits("zIndex", 2)).toBe("2");
expect(applyCssUnits("flex", 1)).toBe("1");
});

it("throws if value is not string or number", () => {
// @ts-expect-error - testing invalid input
expect(() => applyCssUnits("fontSize", null)).toThrowError();
// @ts-expect-error - testing invalid input
expect(() => applyCssUnits("fontSize", {})).toThrowError();
});
});
26 changes: 26 additions & 0 deletions src/__tests__/camelToKebab.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { describe, expect, it } from "vitest";
import { camelToKebab } from "../helpers";

describe("camelToKebab", () => {
it("converts camelCase to kebab-case", () => {
expect(camelToKebab("backgroundColor")).toBe("background-color");
expect(camelToKebab("fontSize")).toBe("font-size");
expect(camelToKebab("borderTopLeftRadius")).toBe("border-top-left-radius");
expect(camelToKebab("WebkitBorderBeforeWidth")).toBe(
"-webkit-border-before-width"
);
});

it("returns the same string if there are no uppercase letters", () => {
expect(camelToKebab("color")).toBe("color");
expect(camelToKebab("display")).toBe("display");
});

it("handles empty string", () => {
expect(camelToKebab("")).toBe("");
});

it("handles single uppercase character", () => {
expect(camelToKebab("A")).toBe("-a");
});
});
50 changes: 47 additions & 3 deletions src/__tests__/stringifyCSSProperties.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, it, expect } from "vitest";

import { stringifyCSSProperties } from "../stringifyCSSProperties";
import { stringifyCSSProperties } from "../stringify-react-styles";

describe("stringifyCSSProperties", () => {
it("returns string", () => {
Expand All @@ -14,14 +14,14 @@ describe("stringifyCSSProperties", () => {
it("throws error for string input", () => {
//@ts-ignore
expect(() => stringifyCSSProperties("")).toThrowError(
"Invalid input: 'cssProperties' must be an object."
"[stringifyCSSProperties]: Expected 'cssProperties' to be a non-null object, but received (type:string)."
);
});

it("throws error for 'null' input", () => {
//@ts-ignore
expect(() => stringifyCSSProperties(null)).toThrowError(
"Invalid input: 'cssProperties' must be an object."
"[stringifyCSSProperties]: Expected 'cssProperties' to be a non-null object, but received null (type:object)."
);
});

Expand Down Expand Up @@ -99,3 +99,47 @@ describe("stringifyCSSProperties", () => {
expect(actual).toBe(expected);
});
});

describe("stringifyStyleMap accepts 'options' object", () => {
it("applies !important when the flag is set", () => {
expect(
stringifyCSSProperties(
{
display: "flex",
top: 100,
},
{
important: true,
}
)
).toBe("display:flex!important;top:100px!important;");
});

it("uses a global unit string when specified", () => {
expect(
stringifyCSSProperties(
{
top: 100,
},
{
unit: "rem",
}
)
).toBe("top:100rem;");
});

it("uses per-property unit map when provided (with 'px' fallback)", () => {
expect(
stringifyCSSProperties(
{
paddingBlock: 20,
paddingInline: 30,
top: 100,
},
{
unit: { paddingBlock: "vh", paddingInline: "vw" },
}
)
).toBe("padding-block:20vh;padding-inline:30vw;top:100px;");
});
});
70 changes: 70 additions & 0 deletions src/__tests__/stringifyStyleDeclaration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { describe, it, expect } from "vitest";

import { stringifyStyleDeclaration } from "../stringifyStyleDeclaration";

describe("stringifyStyleDeclaration", () => {
it("converts a basic style declaration to a CSS string", () => {
expect(
stringifyStyleDeclaration({
display: "flex",
fontSize: 16,
})
).toBe("display:flex;font-size:16px;");
});

it("applies !important when the flag is set", () => {
expect(
stringifyStyleDeclaration(
{ color: "red", marginTop: 8 },
{ important: true }
)
).toBe("color:red!important;margin-top:8px!important;");
});

it("uses a global unit string when specified", () => {
expect(stringifyStyleDeclaration({ padding: 10 }, { unit: "rem" })).toBe(
"padding:10rem;"
);
});

it("uses per-property unit map when provided (with 'px' fallback)", () => {
expect(
stringifyStyleDeclaration(
{ fontSize: 2, marginLeft: 5, marginBottom: 10 },
{ unit: { fontSize: "em", marginLeft: "%" } }
)
).toBe("font-size:2em;margin-left:5%;margin-bottom:10px;");
});

it("uses px as default unit if none is specified", () => {
expect(stringifyStyleDeclaration({ top: 100 })).toBe("top:100px;");
});

it("omits units for unitless properties", () => {
expect(stringifyStyleDeclaration({ lineHeight: 1.5 })).toBe(
"line-height:1.5;"
);
});

it("filters out invalid property values (e.g., null, undefined)", () => {
expect(
stringifyStyleDeclaration({
margin: { top: 10 },
fontSize: 14,
color: undefined,
background: null,
})
).toBe("font-size:14px;");
});

it("throws an error if styleDeclaration is not an object", () => {
// @ts-expect-error - invalid input
expect(() => stringifyStyleDeclaration(null)).toThrowError();
// @ts-expect-error - invalid input
expect(() => stringifyStyleDeclaration(123)).toThrowError();
});

it("returns an empty string for an empty object", () => {
expect(stringifyStyleDeclaration({})).toBe("");
});
});
68 changes: 65 additions & 3 deletions src/__tests__/stringifyStyleMap.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest";

import { stringifyStyleMap } from "../stringifyStyleMap";
import { stringifyStyleMap } from "../stringify-react-styles";

describe("stringifyStyleMap", () => {
const cssProperties = { color: "teal" };
Expand All @@ -16,14 +16,14 @@ describe("stringifyStyleMap", () => {
it("throws error for string input", () => {
//@ts-ignore
expect(() => stringifyStyleMap("")).toThrowError(
"Invalid input: 'styleMap' must be an object."
"[stringifyStyleMap]: Expected 'styleMap' to be a non-null object, but received (type:string)."
);
});

it("throws error for 'null' input", () => {
//@ts-ignore
expect(() => stringifyStyleMap(null)).toThrowError(
"Invalid input: 'styleMap' must be an object."
"[stringifyStyleMap]: Expected 'styleMap' to be a non-null object, but received null (type:object)."
);
});

Expand Down Expand Up @@ -78,3 +78,65 @@ describe("stringifyStyleMap", () => {
expect(actual).toBe(expected);
});
});

describe("stringifyStyleMap accepts 'options' object", () => {
it("applies !important when the flag is set", () => {
expect(
stringifyStyleMap(
{
".class-1": {
display: "flex",
},
".class-2": {
display: "flex",
},
},
{
important: true,
}
)
).toBe(
".class-1{display:flex!important;}.class-2{display:flex!important;}"
);
});

it("uses a global unit string when specified", () => {
expect(
stringifyStyleMap(
{
".class-1": {
margin: 10,
},
".class-2": {
padding: 20,
},
},
{
unit: "rem",
}
)
).toBe(".class-1{margin:10rem;}.class-2{padding:20rem;}");
});

it("uses per-property unit map when provided (with 'px' fallback)", () => {
expect(
stringifyStyleMap(
{
".class-1": {
marginBlock: 30,
},
".class-2": {
top: 100,
paddingBlock: 20,
paddingInline: 10,
},
},
{
unit: { paddingBlock: "vh", paddingInline: "vw" },
}
)
).toBe(
".class-1{margin-block:30px;}.class-2{top:100px;padding-block:20vh;padding-inline:10vw;}"
);
});
});
Loading