Skip to content

Commit d7ac55f

Browse files
committed
refactor: library weight reduction, more unit tests and additions to
README
1 parent 3ee4f66 commit d7ac55f

File tree

5 files changed

+225
-118
lines changed

5 files changed

+225
-118
lines changed

.changeset/honest-cougars-beam.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"typed-string-interpolation": patch
3+
---
4+
5+
Library weight reduction

README.md

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
- Options to customize return, pattern matching and sanity checking
1616
- Both ES Module and CommonJS distributions available. Use anywhere!
1717
- Tiny footprint:
18-
- ES Module: `424B` Gzipped (`660B` unpacked)
19-
- CommonJS: `660B` Gzipped (`1.13kB` unpacked)
18+
- ES Module: `396B` Gzipped (`572B` unpacked)
19+
- CommonJS: `634B` Gzipped (`1.04kB` unpacked)
2020

2121
## Motivation
2222

@@ -61,6 +61,11 @@ stringInterpolation("You have {{n}} messages", {
6161
}) // ["You have ", <strong>3</strong>, " messages"]
6262
```
6363

64+
For more example use cases, see the unit test files in the repository:
65+
66+
- [Unit tests for library logic](src/__tests__/stringInterpolation.test.ts)
67+
- [Unit tests for inferred Typescript types](src/__typetests__/stringInterpolation.test.ts)
68+
6469
## TypeScript support
6570

6671
If the string can be joined you'll get back a `string` type. Otherwise a `union` type within an array is returned based on the passed in variables.
@@ -115,7 +120,19 @@ stringInterpolation(
115120
Provide your own `RegExp` pattern for variable matching. Must be defined as:
116121
117122
```ts
118-
pattern: new RegExp(/\{{([^{]+)}}/g)
123+
pattern: new RegExp(/\{{([^{]+)}}/g) // Default
124+
```
125+
126+
Example alternative pattern:
127+
128+
```ts
129+
stringInterpolation(
130+
"Hi %{name}",
131+
{ name: "John" },
132+
{
133+
pattern: /%\{([^}]+)\}/g,
134+
},
135+
),
119136
```
120137
121138
`sanity`

src/__tests__/stringInterpolation.test.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,70 @@ describe("stringInterpolation()", () => {
6767
"foobar",
6868
)
6969
})
70+
71+
test("Interpolate falsy values (0 and empty string)", () => {
72+
expect(
73+
stringInterpolation("Zero: {{v0}}, Empty: '{{v1}}'", { v0: 0, v1: "" }),
74+
).toBe("Zero: 0, Empty: ''")
75+
})
76+
77+
test("Return raw with number when raw option is true", () => {
78+
expect(
79+
stringInterpolation("Num {{n}}!", { n: 42 }, { raw: true }),
80+
).toStrictEqual(["Num ", 42, "!"])
81+
})
82+
83+
test("Custom pattern option works", () => {
84+
expect(
85+
stringInterpolation(
86+
"Hi %{name}",
87+
{ name: "John" },
88+
{
89+
pattern: /%\{([^}]+)\}/g,
90+
},
91+
),
92+
).toBe("Hi John")
93+
})
94+
95+
test("Sanity disabled allows extra variables without throwing", () => {
96+
expect(
97+
stringInterpolation(
98+
"Hello {{world}}",
99+
{ world: "earth", extra: "x" },
100+
{ sanity: false },
101+
),
102+
).toBe("Hello earth")
103+
})
104+
105+
test("Duplicate variables with sanity enabled triggers count mismatch", () => {
106+
expect(() =>
107+
stringInterpolation("{{name}} {{name}}", { name: "A" }),
108+
).toThrow("Variable count mismatch")
109+
})
110+
111+
test("No variables returns input unchanged", () => {
112+
expect(stringInterpolation("Just text", {} as any)).toBe("Just text")
113+
})
114+
115+
test("Numeric variable key is supported", () => {
116+
expect(stringInterpolation("Value {{0}}", { 0: "zero" } as any)).toBe(
117+
"Value zero",
118+
)
119+
})
120+
121+
test("Empty input with sanity disabled returns empty string", () => {
122+
expect(stringInterpolation("", { a: 1 } as any, { sanity: false })).toBe("")
123+
})
124+
125+
test("Raw output with multiple variables returns segments array", () => {
126+
expect(
127+
stringInterpolation("A{{x}}B{{y}}C", { x: "X", y: "Y" }, { raw: true }),
128+
).toStrictEqual(["A", "X", "B", "Y", "C"])
129+
})
130+
131+
test("Missing variable with sanity disabled yields raw array with undefined", () => {
132+
expect(
133+
stringInterpolation("Hello {{world}}", {} as any, { sanity: false }),
134+
).toStrictEqual(["Hello ", undefined])
135+
})
70136
})

src/__typetests__/stringInterpolation.test.tsx

Lines changed: 110 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,71 +3,125 @@ import { stringInterpolation } from "../index"
33

44
// ~~~~~~~~~~~~~~ TYPESCRIPT TYPE TESTING ~~~~~~~~~~~~~~
55

6-
expectType<string>(
7-
stringInterpolation("hello {{one}}", {
8-
one: "one",
6+
describe("stringInterpolation types", () => {
7+
test("returns string for single variable string", () => {
8+
expectType<string>(
9+
stringInterpolation("hello {{one}}", {
10+
one: "one",
11+
}),
12+
)
13+
14+
expectType<string>(
15+
stringInterpolation("hello {{one}}", {
16+
one: "one",
17+
}),
18+
)
19+
})
20+
21+
test("returns string[] when raw is true with string values", () => {
22+
expectType<string[]>(
23+
stringInterpolation(
24+
"hello {{one}}",
25+
{
26+
one: "one",
27+
},
28+
{ raw: true },
29+
),
30+
)
931
})
10-
)
1132

12-
expectType<string>(
13-
stringInterpolation("hello {{one}}", {
14-
one: "one",
33+
test("returns string when mixed string and number are joinable", () => {
34+
expectType<string>(
35+
stringInterpolation("hello {{one}} {{two}}", {
36+
one: "one",
37+
two: 2,
38+
}),
39+
)
1540
})
16-
)
1741

18-
expectType<string[]>(
19-
stringInterpolation(
20-
"hello {{one}}",
21-
{
22-
one: "one",
23-
},
24-
{ raw: true }
25-
)
26-
)
42+
test("returns string when variable is a number", () => {
43+
expectType<string>(
44+
stringInterpolation("hello {{one}}", {
45+
one: 2,
46+
}),
47+
)
48+
})
49+
50+
test("returns array union when non-primitive element is included", () => {
51+
expectType<
52+
(
53+
| string
54+
| number
55+
| {
56+
type: string
57+
props: {
58+
className: string
59+
children: string
60+
}
61+
}
62+
)[]
63+
>(
64+
stringInterpolation("hello {{one}} {{two}} {{three}}", {
65+
one: "one",
66+
two: 2,
67+
three: {
68+
type: "span",
69+
props: {
70+
className: "bold",
71+
children: "one",
72+
},
73+
},
74+
}),
75+
)
76+
})
77+
78+
test("returns array including Date when Date is included", () => {
79+
expectType<(string | number | Date)[]>(
80+
stringInterpolation("hello {{one}} {{two}} {{three}}", {
81+
one: "one",
82+
two: 2,
83+
three: new Date(),
84+
}),
85+
)
86+
})
87+
88+
test("raw true with only string/number returns (string | number)[]", () => {
89+
expectType<(string | number)[]>(
90+
stringInterpolation("num {{n}}", { n: 123 }, { raw: true }),
91+
)
92+
93+
expectType<(string | number)[]>(
94+
stringInterpolation("a {{a}} b {{b}}", { a: "A", b: 2 }, { raw: true }),
95+
)
96+
})
2797

28-
expectType<string>(
29-
stringInterpolation("hello {{one}} {{two}}", {
30-
one: "one",
31-
two: 2,
98+
test("raw false with non-(string|number) still returns array", () => {
99+
expectType<(string | Date)[]>(
100+
stringInterpolation("date {{d}}", { d: new Date() }, { raw: false }),
101+
)
32102
})
33-
)
34103

35-
expectType<string>(
36-
stringInterpolation("hello {{one}}", {
37-
one: 2,
104+
test("including a function forces array regardless of raw option", () => {
105+
const fnReturnsString: () => string = () => "ok"
106+
expectType<(string | (() => string))[]>(
107+
stringInterpolation("fn {{f}}", { f: fnReturnsString }),
108+
)
38109
})
39-
)
40110

41-
expectType<
42-
(
43-
| string
44-
| number
45-
| {
46-
type: string
47-
props: {
48-
className: string
49-
children: string
50-
}
51-
}
52-
)[]
53-
>(
54-
stringInterpolation("hello {{one}} {{two}} {{three}}", {
55-
one: "one",
56-
two: 2,
57-
three: {
58-
type: "span",
59-
props: {
60-
className: "bold",
61-
children: "one",
62-
},
63-
},
111+
test("raw true + string values returns string[]", () => {
112+
expectType<string[]>(
113+
stringInterpolation("hello {{one}}", { one: "one" }, { raw: true }),
114+
)
64115
})
65-
)
66116

67-
expectType<(string | number | Date)[]>(
68-
stringInterpolation("hello {{one}} {{two}} {{three}}", {
69-
one: "one",
70-
two: 2,
71-
three: new Date(),
117+
test("raw true with object value returns array including object type", () => {
118+
expectType<
119+
(
120+
| string
121+
| {
122+
id: number
123+
}
124+
)[]
125+
>(stringInterpolation("obj {{o}}", { o: { id: 1 } }, { raw: true }))
72126
})
73-
)
127+
})

0 commit comments

Comments
 (0)