Skip to content

Commit b0742db

Browse files
committed
test(contributors): verify compilation bounds and schema constraints for page
1 parent f4db3bd commit b0742db

1 file changed

Lines changed: 100 additions & 0 deletions

File tree

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import { describe, it, expect, expectTypeOf } from 'vitest';
2+
import { z } from 'zod';
3+
4+
// Type definitions used by the contributors page
5+
type ExpectedContributor = {
6+
id: number;
7+
username: string;
8+
avatarUrl: string;
9+
contributions: number;
10+
};
11+
12+
type PageProps = {
13+
contributors: ExpectedContributor[];
14+
showAvatars?: boolean;
15+
topN?: number;
16+
};
17+
18+
describe('ContributorsPage type & schema compiler checks (Variation 10)', () => {
19+
it('Case 1: Validate core property shapes match design boundaries', () => {
20+
type Matching = {
21+
id: number;
22+
username: string;
23+
avatarUrl: string;
24+
contributions: number;
25+
};
26+
27+
expectTypeOf<Matching>().toEqualTypeOf<ExpectedContributor>();
28+
});
29+
30+
it('Case 2: Ensure invalid parameters are blocked via static assignability', () => {
31+
type Invalid = {
32+
id: string; // wrong type
33+
username: number; // wrong type
34+
contributions?: string; // wrong and optional
35+
};
36+
37+
expectTypeOf<Invalid>().not.toMatchTypeOf<ExpectedContributor>();
38+
});
39+
40+
it('Case 3: Optional fields accepted safely without compile-time warnings', () => {
41+
const minimal: PageProps = {
42+
contributors: [{ id: 1, username: 'bob', avatarUrl: '/img/bob.png', contributions: 3 }],
43+
};
44+
45+
expect(minimal.contributors.length).toBe(1);
46+
type MinimalType = typeof minimal;
47+
expectTypeOf<MinimalType>().toMatchTypeOf<PageProps>();
48+
});
49+
50+
it('Case 4: Zod runtime schema flags out-of-bound structural types with flat reports', () => {
51+
const contributorSchema = z
52+
.object({
53+
id: z.number().int().positive(),
54+
username: z.string().min(1),
55+
avatarUrl: z.string().min(1),
56+
contributions: z.number().int().nonnegative(),
57+
})
58+
.strict();
59+
60+
const bad = {
61+
id: -5,
62+
username: '',
63+
avatarUrl: 12345,
64+
contributions: -1,
65+
extra: 'unexpected',
66+
} as unknown;
67+
68+
try {
69+
contributorSchema.parse(bad);
70+
expect(false).toBe(true);
71+
} catch (err) {
72+
const zErr = err as z.ZodError;
73+
expect(zErr.issues.length).toBeGreaterThan(0);
74+
// flat validation: all issue paths are shallow (no deep nesting)
75+
const allShallow = zErr.issues.every((i) => i.path.length <= 1);
76+
expect(allShallow).toBe(true);
77+
}
78+
});
79+
80+
it('Case 5: Correct payloads safely clear validation limits', () => {
81+
const contributorSchema = z.object({
82+
id: z.number().int().positive(),
83+
username: z.string().min(1),
84+
avatarUrl: z.string().min(1),
85+
contributions: z.number().int().nonnegative(),
86+
});
87+
88+
const good = {
89+
id: 2,
90+
username: 'alice',
91+
avatarUrl: 'https://cdn.test/a.png',
92+
contributions: 10,
93+
};
94+
95+
const parsed = contributorSchema.parse(good);
96+
expect(parsed).toEqual(good);
97+
type ParsedType = z.infer<typeof contributorSchema>;
98+
expectTypeOf<ParsedType>().toEqualTypeOf<ExpectedContributor>();
99+
});
100+
});

0 commit comments

Comments
 (0)