/** * @copyright NHCarrigan * @license Naomi's Public License * @author Naomi Carrigan */ import { readFile } from "node:fs/promises"; import { join } from "node:path"; import { describe, expect, it } from "vitest"; import { parse } from "yaml"; import type { Donate } from "../src/interfaces/donate.js"; import type { Funding } from "../src/interfaces/funding.js"; import type { Projects } from "../src/interfaces/projects.js"; import type { Resume } from "../src/interfaces/resume.js"; import type { Testimonials } from "../src/interfaces/testimonials.js"; describe("project data", () => { it("should match the interface", async() => { expect.hasAssertions(); const data = await readFile( join(import.meta.dirname, "..", "data", "projects.yml"), "utf8", ); const parsed = parse(data) as Projects; expect(parsed, `Parsed projects data should be defined`).toBeDefined(); expect( Array.isArray(parsed), `Parsed projects data should be an array`, ).toBeTruthy(); for (const project of parsed) { expect(project, `Project should be defined`).toBeDefined(); expect( typeof project.name, `Project name should be a string for project: ${ project.name ?? "unknown" }`, ).toBe("string"); expect( typeof project.category, `Project category should be a string for project: ${ project.name ?? "unknown" }`, ).toBe("string"); expect( typeof project.description, `Project description should be a string for project: ${ project.name ?? "unknown" }`, ).toBe("string"); expect( typeof project.premium, `Project premium should be a boolean for project: ${ project.name ?? "unknown" }`, ).toBe("boolean"); expect( typeof project.wip, `Project wip should be a boolean for project: ${ project.name ?? "unknown" }`, ).toBe("boolean"); if (project.avatar) { expect( typeof project.avatar, `Project avatar should be a string for project: ${ project.name ?? "unknown" }`, ).toBe("string"); } if (project.url) { expect( typeof project.url, `Project url should be a string for project: ${ project.name ?? "unknown" }`, ).toBe("string"); } } }); }); describe("resume data", () => { it("should match the interface", async() => { expect.hasAssertions(); const data = await readFile( join(import.meta.dirname, "..", "data", "resume.yml"), "utf8", ); const parsed = parse(data) as Resume; expect(parsed, `Parsed resume data should be defined`).toBeDefined(); expect(typeof parsed.name, `Resume name should be a string`).toBe("string"); expect(typeof parsed.contact, `Resume contact should be a string`).toBe( "string", ); expect(typeof parsed.summary, `Resume summary should be a string`).toBe( "string", ); expect( Array.isArray(parsed.employment), `Resume employment should be an array`, ).toBeTruthy(); for (const employment of parsed.employment) { expect(employment, `Employment entry should be defined`).toBeDefined(); expect( typeof employment.title, `Employment title should be a string for ${ employment.company ?? "unknown company" }`, ).toBe("string"); expect( typeof employment.company, `Employment company should be a string for ${ employment.title ?? "unknown position" }`, ).toBe("string"); expect( typeof employment.type, `Employment type should be a string for ${ employment.company ?? "unknown company" } - ${employment.title ?? "unknown position"}`, ).toBe("string"); expect( typeof employment.start_date, `Employment start_date should be a string for ${ employment.company ?? "unknown company" } - ${employment.title ?? "unknown position"}`, ).toBe("string"); expect( typeof employment.end_date, `Employment end_date should be a string for ${ employment.company ?? "unknown company" } - ${employment.title ?? "unknown position"}`, ).toBe("string"); expect( typeof employment.description, `Employment description should be a string for ${ employment.company ?? "unknown company" } - ${employment.title ?? "unknown position"}`, ).toBe("string"); if (employment.prior_positions) { expect( Array.isArray(employment.prior_positions), `Employment prior_positions should be an array for ${ employment.company ?? "unknown company" }`, ).toBeTruthy(); for (const position of employment.prior_positions) { expect( position, `Prior position entry should be defined for ${ employment.company ?? "unknown company" }`, ).toBeDefined(); expect( typeof position.title, `Prior position title should be a string for ${ employment.company ?? "unknown company" } - ${position.title ?? "unknown position"}`, ).toBe("string"); expect( typeof position.start_date, `Prior position start_date should be a string for ${ employment.company ?? "unknown company" } - ${position.title ?? "unknown position"}`, ).toBe("string"); expect( typeof position.end_date, `Prior position end_date should be a string for ${ employment.company ?? "unknown company" } - ${position.title ?? "unknown position"}`, ).toBe("string"); } } } expect( Array.isArray(parsed.volunteer), `Resume volunteer should be an array`, ).toBeTruthy(); for (const volunteer of parsed.volunteer) { expect(volunteer, `Volunteer entry should be defined`).toBeDefined(); expect( typeof volunteer.title, `Volunteer title should be a string for ${ volunteer.company ?? "unknown organization" }`, ).toBe("string"); expect( typeof volunteer.company, `Volunteer company should be a string for ${ volunteer.title ?? "unknown position" }`, ).toBe("string"); expect( typeof volunteer.start_date, `Volunteer start_date should be a string for ${ volunteer.company ?? "unknown organization" } - ${volunteer.title ?? "unknown position"}`, ).toBe("string"); expect( typeof volunteer.end_date, `Volunteer end_date should be a string for ${ volunteer.company ?? "unknown organization" } - ${volunteer.title ?? "unknown position"}`, ).toBe("string"); expect( typeof volunteer.description, `Volunteer description should be a string for ${ volunteer.company ?? "unknown organization" } - ${volunteer.title ?? "unknown position"}`, ).toBe("string"); } expect( Array.isArray(parsed.education), `Resume education should be an array`, ).toBeTruthy(); for (const education of parsed.education) { expect(education, `Education entry should be defined`).toBeDefined(); expect( typeof education.title, `Education title should be a string for ${ education.institution ?? "unknown institution" }`, ).toBe("string"); expect( typeof education.institution, `Education institution should be a string for ${ education.title ?? "unknown degree" }`, ).toBe("string"); expect( typeof education.type, `Education type should be a string for ${ education.institution ?? "unknown institution" } - ${education.title ?? "unknown degree"}`, ).toBe("string"); expect( typeof education.start_date, `Education start_date should be a string for ${ education.institution ?? "unknown institution" } - ${education.title ?? "unknown degree"}`, ).toBe("string"); expect( typeof education.end_date, `Education end_date should be a string for ${ education.institution ?? "unknown institution" } - ${education.title ?? "unknown degree"}`, ).toBe("string"); expect( typeof education.description, `Education description should be a string for ${ education.institution ?? "unknown institution" } - ${education.title ?? "unknown degree"}`, ).toBe("string"); } expect( Array.isArray(parsed.certifications), `Resume certifications should be an array`, ).toBeTruthy(); for (const certification of parsed.certifications) { expect( certification, `Certification entry should be defined`, ).toBeDefined(); expect( typeof certification.title, `Certification title should be a string for ${ certification.issuer ?? "unknown issuer" }`, ).toBe("string"); expect( typeof certification.issuer, `Certification issuer should be a string for ${ certification.title ?? "unknown certification" }`, ).toBe("string"); expect( typeof certification.date, `Certification date should be a string for ${ certification.issuer ?? "unknown issuer" } - ${certification.title ?? "unknown certification"}`, ).toBe("string"); } expect( Array.isArray(parsed.projects), `Resume projects should be an array`, ).toBeTruthy(); for (const project of parsed.projects) { expect(project, `Resume project entry should be defined`).toBeDefined(); expect( typeof project.title, `Resume project title should be a string for ${ project.company ?? "unknown company" }`, ).toBe("string"); expect( typeof project.company, `Resume project company should be a string for ${ project.title ?? "unknown project" }`, ).toBe("string"); expect( typeof project.description, `Resume project description should be a string for ${ project.company ?? "unknown company" } - ${project.title ?? "unknown project"}`, ).toBe("string"); expect( typeof project.date, `Resume project date should be a string for ${ project.company ?? "unknown company" } - ${project.title ?? "unknown project"}`, ).toBe("string"); } expect( Array.isArray(parsed.publications), `Resume publications should be an array`, ).toBeTruthy(); for (const publication of parsed.publications) { expect(publication, `Publication entry should be defined`).toBeDefined(); expect( typeof publication.title, `Publication title should be a string for ${ publication.company ?? "unknown company" }`, ).toBe("string"); expect( typeof publication.company, `Publication company should be a string for ${ publication.title ?? "unknown publication" }`, ).toBe("string"); expect( typeof publication.description, `Publication description should be a string for ${ publication.company ?? "unknown company" } - ${publication.title ?? "unknown publication"}`, ).toBe("string"); expect( typeof publication.date, `Publication date should be a string for ${ publication.company ?? "unknown company" } - ${publication.title ?? "unknown publication"}`, ).toBe("string"); } }); }); describe("donate data", () => { it("should match the interface", async() => { expect.hasAssertions(); const data = await readFile( join(import.meta.dirname, "..", "data", "donate.yml"), "utf8", ); const parsed = parse(data) as Donate; expect(parsed, `Parsed donate data should be defined`).toBeDefined(); expect( Array.isArray(parsed), `Parsed donate data should be an array`, ).toBeTruthy(); for (const method of parsed) { expect(method, `Donation method should be defined`).toBeDefined(); expect( typeof method.name, `Donation method name should be a string for ${ method.name ?? "unknown method" }`, ).toBe("string"); expect( typeof method.description, `Donation method description should be a string for ${ method.name ?? "unknown method" }`, ).toBe("string"); expect( typeof method.url, `Donation method url should be a string for ${ method.name ?? "unknown method" }`, ).toBe("string"); expect( typeof method.icon, `Donation method icon should be a string for ${ method.name ?? "unknown method" }`, ).toBe("string"); expect( typeof method.foreground, `Donation method foreground should be a string for ${ method.name ?? "unknown method" }`, ).toBe("string"); expect( typeof method.background, `Donation method background should be a string for ${ method.name ?? "unknown method" }`, ).toBe("string"); } }); }); describe("funding data", () => { it("should match the interface", async() => { expect.hasAssertions(); const data = await readFile( join(import.meta.dirname, "..", "data", "funding.yml"), "utf8", ); const parsed = parse(data) as Funding; expect(parsed, `Parsed funding data should be defined`).toBeDefined(); expect(typeof parsed.version, `Funding version should be a string`).toBe( "string", ); expect(parsed.version, `Funding version should be "v1.0.0"`).toBe("v1.0.0"); expect(parsed.entity, `Funding entity should be defined`).toBeDefined(); expect( typeof parsed.entity.type, `Funding entity type should be a string`, ).toBe("string"); expect( typeof parsed.entity.role, `Funding entity role should be a string`, ).toBe("string"); expect( typeof parsed.entity.name, `Funding entity name should be a string`, ).toBe("string"); expect( typeof parsed.entity.email, `Funding entity email should be a string`, ).toBe("string"); expect( typeof parsed.entity.phone, `Funding entity phone should be a string`, ).toBe("string"); expect( typeof parsed.entity.description, `Funding entity description should be a string`, ).toBe("string"); expect( parsed.entity.webpageUrl, `Funding entity webpageUrl should be defined`, ).toBeDefined(); expect( typeof parsed.entity.webpageUrl.url, `Funding entity webpageUrl.url should be a string`, ).toBe("string"); if (parsed.entity.webpageUrl.wellKnown) { expect( typeof parsed.entity.webpageUrl.wellKnown, `Funding entity webpageUrl.wellKnown should be a string`, ).toBe("string"); } expect( Array.isArray(parsed.projects), `Funding projects should be an array`, ).toBeTruthy(); expect(parsed.projects.length, `There should be at least one funding project`).toBeGreaterThan(0); expect(parsed.projects.length, `There should not be more than 30 funding projects`).toBeLessThan(31); for (const project of parsed.projects) { expect(project, `Funding project should be defined`).toBeDefined(); expect( typeof project.guid, `Funding project guid should be a string for project: ${ project.name ?? "unknown" }`, ).toBe("string"); expect( typeof project.name, `Funding project name should be a string for guid: ${ project.guid ?? "unknown" }`, ).toBe("string"); expect( typeof project.description, `Funding project description should be a string for project: ${ project.name ?? "unknown" }`, ).toBe("string"); expect( project.webpageUrl, `Funding project webpageUrl should be defined for project: ${ project.name ?? "unknown" }`, ).toBeDefined(); expect( typeof project.webpageUrl.url, `Funding project webpageUrl.url should be a string for project: ${ project.name ?? "unknown" }`, ).toBe("string"); if (project.webpageUrl.wellKnown) { expect( typeof project.webpageUrl.wellKnown, `Funding project webpageUrl.wellKnown should be a string for project: ${ project.name ?? "unknown" }`, ).toBe("string"); } expect( project.repositoryUrl, `Funding project repositoryUrl should be defined for project: ${ project.name ?? "unknown" }`, ).toBeDefined(); expect( typeof project.repositoryUrl.url, `Funding project repositoryUrl.url should be a string for project: ${ project.name ?? "unknown" }`, ).toBe("string"); if (project.repositoryUrl.wellKnown) { expect( typeof project.repositoryUrl.wellKnown, `Funding project repositoryUrl.wellKnown should be a string for project: ${ project.name ?? "unknown" }`, ).toBe("string"); } expect( Array.isArray(project.licenses), `Funding project licenses should be an array for project: ${ project.name ?? "unknown" }`, ).toBeTruthy(); for (const license of project.licenses) { expect( typeof license, `License should be a string for project: ${project.name ?? "unknown"}`, ).toBe("string"); } expect( Array.isArray(project.tags), `Funding project tags should be an array for project: ${ project.name ?? "unknown" }`, ).toBeTruthy(); for (const tag of project.tags) { expect( typeof tag, `Tag should be a string for project: ${project.name ?? "unknown"}`, ).toBe("string"); } } expect(parsed.funding, `Funding data should be defined`).toBeDefined(); expect( Array.isArray(parsed.funding.channels), `Funding channels should be an array`, ).toBeTruthy(); for (const channel of parsed.funding.channels) { expect(channel, `Funding channel should be defined`).toBeDefined(); expect( typeof channel.guid, `Funding channel guid should be a string for channel: ${ channel.type ?? "unknown" }`, ).toBe("string"); expect( typeof channel.type, `Funding channel type should be a string for guid: ${ channel.guid ?? "unknown" }`, ).toBe("string"); expect( typeof channel.address, `Funding channel address should be a string for channel: ${ channel.type ?? "unknown" }`, ).toBe("string"); expect( typeof channel.description, `Funding channel description should be a string for channel: ${ channel.type ?? "unknown" }`, ).toBe("string"); } expect( Array.isArray(parsed.funding.plans), `Funding plans should be an array`, ).toBeTruthy(); for (const plan of parsed.funding.plans) { expect(plan, `Funding plan should be defined`).toBeDefined(); expect( typeof plan.guid, `Funding plan guid should be a string for plan: ${ plan.name ?? "unknown" }`, ).toBe("string"); expect( typeof plan.status, `Funding plan status should be a string for plan: ${ plan.name ?? "unknown" }`, ).toBe("string"); expect( typeof plan.name, `Funding plan name should be a string for guid: ${ plan.guid ?? "unknown" }`, ).toBe("string"); expect( typeof plan.description, `Funding plan description should be a string for plan: ${ plan.name ?? "unknown" }`, ).toBe("string"); expect( typeof plan.amount, `Funding plan amount should be a number for plan: ${ plan.name ?? "unknown" }`, ).toBe("number"); expect( typeof plan.currency, `Funding plan currency should be a string for plan: ${ plan.name ?? "unknown" }`, ).toBe("string"); expect( typeof plan.frequency, `Funding plan frequency should be a string for plan: ${ plan.name ?? "unknown" }`, ).toBe("string"); expect( Array.isArray(plan.channels), `Funding plan channels should be an array for plan: ${ plan.name ?? "unknown" }`, ).toBeTruthy(); for (const channel of plan.channels) { expect( typeof channel, `Funding plan channel should be a string for plan: ${ plan.name ?? "unknown" }`, ).toBe("string"); } } expect( Array.isArray(parsed.funding.history), `Funding history should be an array`, ).toBeTruthy(); for (const history of parsed.funding.history) { expect(history, `Funding history entry should be defined`).toBeDefined(); expect( typeof history.year, `Funding history year should be a number for year: ${ history.year ?? "unknown" }`, ).toBe("number"); expect( typeof history.income, `Funding history income should be a number for year: ${ history.year ?? "unknown" }`, ).toBe("number"); expect( typeof history.expenses, `Funding history expenses should be a number for year: ${ history.year ?? "unknown" }`, ).toBe("number"); expect( typeof history.taxes, `Funding history taxes should be a number for year: ${ history.year ?? "unknown" }`, ).toBe("number"); expect( typeof history.currency, `Funding history currency should be a string for year: ${ history.year ?? "unknown" }`, ).toBe("string"); expect( typeof history.description, `Funding history description should be a string for year: ${ history.year ?? "unknown" }`, ).toBe("string"); } }); }); describe("testimonials data", () => { it("should match the interface", async() => { expect.hasAssertions(); const data = await readFile( join(import.meta.dirname, "..", "data", "testimonials.yml"), "utf8", ); const parsed = parse(data) as Testimonials; expect(parsed, `Parsed testimonials data should be defined`).toBeDefined(); expect( Array.isArray(parsed), `Parsed testimonials data should be an array`, ).toBeTruthy(); for (const testimonial of parsed) { expect(testimonial, `Testimonial should be defined`).toBeDefined(); expect( typeof testimonial.name, `Testimonial name should be a string for ${ testimonial.name ?? "unknown" }`, ).toBe("string"); expect( typeof testimonial.content, `Testimonial content should be a string for ${ testimonial.name ?? "unknown" }`, ).toBe("string"); expect( typeof testimonial.date, `Testimonial date should be a string for ${ testimonial.name ?? "unknown" }`, ).toBe("string"); // Check date is parsable in DD month YYYY format (e.g. 30 June 2023) expect( Boolean(/^\d{1,2} \w+ \d{4}$/.test(testimonial.date)), `Testimonial date should be in "DD month YYYY" format for ${ testimonial.name ?? "unknown" }`, ).toBeTruthy(); expect( Boolean(Date.parse(testimonial.date)), `Testimonial date should be a valid date for ${ testimonial.name ?? "unknown" }`, ).toBeTruthy(); } }); });