CI / verify (push) Failing after 5m43s
- Biome: formatacao, ordem de imports, max-width duplicado no cabecalho de secao, supressao justificada para nomes de view-transition, ajustes nos scripts de auditoria de SEO - next 16.3.3 -> 16.3.8: GHSA-vcvr-r3jv-pc5j (execucao remota de codigo em next/og ImageResponse, usado nas imagens de compartilhamento) - overrides de brace-expansion (GHSA-qhr7-859c-m2p7, GHSA-6j4f-fj2g-mc7p, GHSA-q2hr-2g5m-vwhr), dependencia de desenvolvimento via jest - visibilidade das cenas le as posicoes a cada quadro e o GSAP remede as passagens quando a pagina muda de altura (fontes, imagens, Experiencia) Co-Authored-By: Claude Opus 5.5 <[email protected]>
125 lines
3.8 KiB
TypeScript
125 lines
3.8 KiB
TypeScript
import { caseStudies, getRelatedServices, servicePages } from "./site-content";
|
|
|
|
const detailedIds = [
|
|
"as-servicos",
|
|
"gcc-installer",
|
|
"nutriscan",
|
|
"reddit-explorer",
|
|
"twins-lab",
|
|
] as const;
|
|
const immutableGitHubBlobUrl =
|
|
/^https:\/\/github\.com\/[^/]+\/[^/]+\/blob\/[0-9a-f]{40}\/.+$/;
|
|
|
|
function getDetail(id: (typeof detailedIds)[number]) {
|
|
const detail = caseStudies.find((item) => item.id === id)?.detail;
|
|
expect(detail).toBeDefined();
|
|
if (!detail) throw new Error(`Missing detail for ${id}`);
|
|
return detail;
|
|
}
|
|
|
|
it("limits detailed content to the evidenced cases (public repositories pinned to a commit)", () => {
|
|
expect(
|
|
caseStudies
|
|
.filter(({ detail }) => detail !== undefined)
|
|
.map(({ id }) => id)
|
|
.sort(),
|
|
).toEqual([...detailedIds].sort());
|
|
});
|
|
|
|
it("uses unique source IDs and immutable GitHub commit URLs", () => {
|
|
for (const id of detailedIds) {
|
|
const { sources } = getDetail(id);
|
|
const sourceIds = sources.map(({ id }) => id);
|
|
expect(new Set(sourceIds).size).toBe(sourceIds.length);
|
|
|
|
for (const { url } of sources) {
|
|
expect(url).toMatch(immutableGitHubBlobUrl);
|
|
}
|
|
}
|
|
});
|
|
|
|
it("requires sources for factual statements and resolves every source ID", () => {
|
|
for (const id of detailedIds) {
|
|
const detail = getDetail(id);
|
|
const sourceIds = new Set(detail.sources.map(({ id }) => id));
|
|
const factualStatements = [
|
|
detail.answer,
|
|
detail.challenge,
|
|
...detail.implementation,
|
|
];
|
|
|
|
for (const statement of [...factualStatements, ...detail.boundaries]) {
|
|
expect(
|
|
statement.sourceIds.every((sourceId) => sourceIds.has(sourceId)),
|
|
).toBe(true);
|
|
}
|
|
for (const statement of factualStatements) {
|
|
expect(statement.sourceIds.length).toBeGreaterThan(0);
|
|
}
|
|
}
|
|
|
|
expect(
|
|
getDetail("as-servicos").boundaries.map(({ sourceIds }) => sourceIds),
|
|
).toEqual([[]]);
|
|
|
|
for (const id of ["nutriscan", "twins-lab"] as const) {
|
|
expect(
|
|
getDetail(id).boundaries.every(({ sourceIds }) => sourceIds.length > 0),
|
|
).toBe(true);
|
|
}
|
|
expect(getDetail("nutriscan").boundaries[0]?.sourceIds).toContain(
|
|
"nutri-readme",
|
|
);
|
|
|
|
// reddit-explorer e gcc-installer: o 1º limite vem da documentação do repositório; o 2º é o escopo editorial (sem fonte)
|
|
for (const id of ["reddit-explorer", "gcc-installer"] as const) {
|
|
const { boundaries } = getDetail(id);
|
|
expect(boundaries[0]?.sourceIds.length).toBeGreaterThan(0);
|
|
expect(
|
|
boundaries.slice(1).every(({ sourceIds }) => sourceIds.length === 0),
|
|
).toBe(true);
|
|
}
|
|
});
|
|
|
|
it("derives the exact related service set from the existing relationship", () => {
|
|
expect(
|
|
getRelatedServices("twins-lab")
|
|
.map(({ slug }) => slug)
|
|
.sort(),
|
|
).toEqual(
|
|
[
|
|
"consultoria-nextjs",
|
|
"integracao-hardware-software-iot",
|
|
"arquitetura-de-software",
|
|
].sort(),
|
|
);
|
|
});
|
|
|
|
it("resolves every declared related case ID", () => {
|
|
const caseIds = new Set(caseStudies.map(({ id }) => id));
|
|
const unresolved = servicePages.flatMap(({ slug, relatedCaseIds }) =>
|
|
relatedCaseIds
|
|
.filter((caseId) => !caseIds.has(caseId))
|
|
.map((caseId) => ({ slug, caseId })),
|
|
);
|
|
|
|
expect(unresolved).toEqual([]);
|
|
});
|
|
|
|
it("does not publish the unavailable Twins Lab demo", () => {
|
|
expect(
|
|
caseStudies.find((item) => item.id === "twins-lab")?.demoUrl,
|
|
).toBeUndefined();
|
|
});
|
|
|
|
it("keeps AS Serviços as a project (code only) and states the author's participation", () => {
|
|
const asServicos = caseStudies.find(({ id }) => id === "as-servicos");
|
|
expect(asServicos?.demoUrl).toBeNull();
|
|
expect(asServicos?.githubUrl).toBe(
|
|
"https://github.com/evandrodevbr/as-servicos",
|
|
);
|
|
expect(asServicos?.role).toMatch(/primeira landing page/i);
|
|
expect(asServicos?.role).toMatch(/animações 3D/i);
|
|
expect(asServicos?.role).toMatch(/painel para controle de projetos/i);
|
|
});
|