generated from nhcarrigan/template
feat: initial prototype
All checks were successful
Node.js CI / Lint and Test (push) Successful in 41s
All checks were successful
Node.js CI / Lint and Test (push) Successful in 41s
This commit is contained in:
parent
8b4ccadcfe
commit
e53db48154
38
.gitea/workflows/ci.yml
Normal file
38
.gitea/workflows/ci.yml
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
name: Node.js CI
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
name: Lint and Test
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout Source Files
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Use Node.js v22
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 22
|
||||||
|
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@v2
|
||||||
|
with:
|
||||||
|
version: 10
|
||||||
|
|
||||||
|
- name: Install Dependencies
|
||||||
|
run: pnpm install
|
||||||
|
|
||||||
|
- name: Lint Source Files
|
||||||
|
run: pnpm run lint
|
||||||
|
|
||||||
|
- name: Verify Build
|
||||||
|
run: pnpm run build
|
||||||
|
|
||||||
|
- name: Run Tests
|
||||||
|
run: pnpm run test
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
node_modules
|
||||||
|
prod
|
||||||
|
coverage
|
20
README.md
20
README.md
@ -1,24 +1,14 @@
|
|||||||
# New Repository Template
|
# Mommy
|
||||||
|
|
||||||
This template contains all of our basic files for a new GitHub repository. There is also a handy workflow that will create an issue on a new repository made from this template, with a checklist for the steps we usually take in setting up a new repository.
|
Mommy loves you~!
|
||||||
|
|
||||||
If you're starting a Node.JS project with TypeScript, we have a [specific template](https://github.com/naomi-lgbt/nodejs-typescript-template) for that purpose.
|
|
||||||
|
|
||||||
## Readme
|
|
||||||
|
|
||||||
Delete all of the above text (including this line), and uncomment the below text to use our standard readme template.
|
|
||||||
|
|
||||||
<!-- # Project Name
|
|
||||||
|
|
||||||
Project Description
|
|
||||||
|
|
||||||
## Live Version
|
## Live Version
|
||||||
|
|
||||||
This page is currently deployed. [View the live website.]
|
This page is currently deployed. [View the live website.](https://mommy.nhcarrigan.com)
|
||||||
|
|
||||||
## Feedback and Bugs
|
## Feedback and Bugs
|
||||||
|
|
||||||
If you have feedback or a bug report, please feel free to open a GitHub issue!
|
If you have feedback or a bug report, please feel free to open an issue!
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
@ -36,4 +26,4 @@ Copyright held by Naomi Carrigan.
|
|||||||
|
|
||||||
## Contact
|
## Contact
|
||||||
|
|
||||||
We may be contacted through our [Chat Server](http://chat.nhcarrigan.com) or via email at `contact@nhcarrigan.com`. -->
|
We may be contacted through our [Chat Server](http://chat.nhcarrigan.com) or via email at `contact@nhcarrigan.com`.
|
||||||
|
5
eslint.config.js
Normal file
5
eslint.config.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import NaomisConfig from "@nhcarrigan/eslint-config";
|
||||||
|
|
||||||
|
export default [
|
||||||
|
...NaomisConfig,
|
||||||
|
];
|
31
package.json
Normal file
31
package.json
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"name": "mommy",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "prod/index.js",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"dev": "tsx watch src/index.ts",
|
||||||
|
"lint": "eslint src test --max-warnings 0",
|
||||||
|
"start": "node prod/index.js",
|
||||||
|
"test": "rm -rf prod && vitest run --coverage"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"packageManager": "pnpm@10.5.2",
|
||||||
|
"devDependencies": {
|
||||||
|
"@nhcarrigan/eslint-config": "5.2.0",
|
||||||
|
"@nhcarrigan/typescript-config": "4.0.0",
|
||||||
|
"@types/node": "22.13.9",
|
||||||
|
"@vitest/coverage-istanbul": "3.0.8",
|
||||||
|
"eslint": "9.21.0",
|
||||||
|
"string-comparison": "1.3.0",
|
||||||
|
"typescript": "5.8.2",
|
||||||
|
"vitest": "3.0.8"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"fastify": "5.2.1"
|
||||||
|
}
|
||||||
|
}
|
4832
pnpm-lock.yaml
generated
Normal file
4832
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
70
src/config/html.ts
Normal file
70
src/config/html.ts
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/**
|
||||||
|
* @copyright nhcarrigan
|
||||||
|
* @license Naomi's Public License
|
||||||
|
* @author Naomi Carrigan
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the HTML rendered for the landing page.
|
||||||
|
*/
|
||||||
|
export const html = `
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Mommy</title>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<meta name="description" content="Mommy loves you~!" />
|
||||||
|
<script src="https://cdn.nhcarrigan.com/headers/index.js" async defer></script>
|
||||||
|
<script>
|
||||||
|
const getMommy = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const input = document.getElementById("name");
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
if (input?.value) {
|
||||||
|
params.append("name", input.value);
|
||||||
|
}
|
||||||
|
fetch('/api?' + params.toString(), {
|
||||||
|
method: "GET",
|
||||||
|
}).then(res => res.text()).then(data => {
|
||||||
|
const result = document.getElementById("result");
|
||||||
|
if (!result) {
|
||||||
|
throw new Error("Cannot find result element!")
|
||||||
|
}
|
||||||
|
result.innerText = data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main>
|
||||||
|
<h1>Mommy</h1>
|
||||||
|
<section>
|
||||||
|
<p id="result">Mommy loves you~!</p>
|
||||||
|
</section>
|
||||||
|
<form>
|
||||||
|
<label>Tell mommy your name?</label>
|
||||||
|
<input id="name" type="text" placeholder="optional"/>
|
||||||
|
<button onclick="getMommy(event)" type="text">I need some love...</button>
|
||||||
|
</form>
|
||||||
|
<section>
|
||||||
|
<h2>Links</h2>
|
||||||
|
<p>
|
||||||
|
<a href="https://codeberg.org/nhcarrigan/boost-monitor">
|
||||||
|
<i class="fa-solid fa-code"></i> Source Code
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href="https://docs.nhcarrigan.com">
|
||||||
|
<i class="fa-solid fa-book"></i> Documentation
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href="https://chat.nhcarrigan.com">
|
||||||
|
<i class="fa-solid fa-circle-info"></i> Support
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>`;
|
16
src/config/mommy.ts
Normal file
16
src/config/mommy.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
* @copyright nhcarrigan
|
||||||
|
* @license Naomi's Public License
|
||||||
|
* @author Naomi Carrigan
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These are the names mommy uses to refer to herself.
|
||||||
|
*/
|
||||||
|
export const mommy = [
|
||||||
|
"your mommy",
|
||||||
|
"mommy",
|
||||||
|
"mama",
|
||||||
|
"mommy naomi",
|
||||||
|
"mama naomi",
|
||||||
|
];
|
116
src/config/phrases.ts
Normal file
116
src/config/phrases.ts
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/**
|
||||||
|
* @copyright nhcarrigan
|
||||||
|
* @license Naomi's Public License
|
||||||
|
* @author Naomi Carrigan
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable stylistic/max-len -- These are going to be long. Nothing we can do about that. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These are the compliments Mommy will say.
|
||||||
|
* The variable {{ mommy }} will be interpolated from the Mommy config array.
|
||||||
|
* The variable {{ name }} will be interpreted from the API call.
|
||||||
|
*/
|
||||||
|
export const phrases = [
|
||||||
|
"{{ name }}, you're doing such an amazing job! {{ mommy }} is so proud of you!",
|
||||||
|
"Keep going, {{ name }}! You're making incredible progress, and {{ mommy }} sees all the effort you're putting in!",
|
||||||
|
"No matter what happens, {{ name }}, remember that {{ mommy }} is always cheering for you!",
|
||||||
|
"You light up the world with your hard work and kindness, {{ name }}! {{ mommy }} is so lucky to know you!",
|
||||||
|
"Whenever you feel uncertain, just remember: {{ mommy }} knows you are strong, smart, and unstoppable!",
|
||||||
|
"Look at you go, {{ name }}! You're absolutely crushing it! {{ mommy }} is beaming with pride!",
|
||||||
|
"Even on the hardest days, {{ name }}, you're still shining! {{ mommy }} sees your strength and perseverance!",
|
||||||
|
"You have so much potential, {{ name }}! {{ mommy }} can't wait to see all the amazing things you'll accomplish!",
|
||||||
|
"You're not just good enough, {{ name }}—you're outstanding! {{ mommy }} loves watching you succeed!",
|
||||||
|
"Mistakes are just stepping stones to greatness, {{ name }}! {{ mommy }} is here to lift you up, always!",
|
||||||
|
"Never forget how incredible you are, {{ name }}! {{ mommy }} sees all the wonderful things that make you special!",
|
||||||
|
"You're learning, growing, and improving every single day, {{ name }}! {{ mommy }} is so impressed by you!",
|
||||||
|
"Take a deep breath, {{ name }}—you've got this! {{ mommy }} is always here to encourage and support you!",
|
||||||
|
"Your creativity and determination inspire {{ mommy }} so much, {{ name }}! Keep being your amazing self!",
|
||||||
|
"You're so loved and appreciated, {{ name }}! {{ mommy }} hopes you always remember that!",
|
||||||
|
"Don't be afraid to chase your dreams, {{ name }}! {{ mommy }} knows you can achieve anything!",
|
||||||
|
"You're such a bright light in this world, {{ name }}! {{ mommy }} adores your energy and kindness!",
|
||||||
|
"Even when things feel tough, {{ mommy }} wants you to know that you're doing better than you think!",
|
||||||
|
"You're capable of handling anything that comes your way, {{ name }}! {{ mommy }} believes in you completely!",
|
||||||
|
"Everything you do makes a difference, {{ name }}! {{ mommy }} sees the impact you have on the world!",
|
||||||
|
"You're an incredible person, {{ name }}! {{ mommy }} is lucky to have you in her life!",
|
||||||
|
"Every challenge you overcome makes you even stronger, {{ name }}! {{ mommy }} is cheering for you!",
|
||||||
|
"You're an absolute treasure, {{ name }}! {{ mommy }} hopes you always see your own worth!",
|
||||||
|
"Your kindness makes the world a better place, {{ name }}! {{ mommy }} admires that about you!",
|
||||||
|
"You're more resilient than you realize, {{ name }}! {{ mommy }} knows you’ll rise above any obstacles!",
|
||||||
|
"You're a masterpiece in the making, {{ name }}! {{ mommy }} is honored to watch you grow!",
|
||||||
|
"You bring so much joy to those around you, {{ name }}! {{ mommy }} is so grateful for you!",
|
||||||
|
"You are unstoppable, {{ name }}! {{ mommy }} knows nothing can hold you back!",
|
||||||
|
"You're so special, {{ name }}! {{ mommy }} loves everything that makes you unique!",
|
||||||
|
"Your hard work will always pay off, {{ name }}! {{ mommy }} is so proud of your dedication!",
|
||||||
|
"Believe in yourself, {{ name }}! {{ mommy }} already does, and she knows you can do amazing things!",
|
||||||
|
"Your potential is limitless, {{ name }}! {{ mommy }} can't wait to see where your journey takes you!",
|
||||||
|
"You're doing better than you think, {{ name }}! {{ mommy }} sees your growth every day!",
|
||||||
|
"Your determination is inspiring, {{ name }}! {{ mommy }} admires your strength so much!",
|
||||||
|
"You are so brave, {{ name }}! {{ mommy }} knows how strong you are, even when you don’t feel it!",
|
||||||
|
"You brighten up any room you walk into, {{ name }}! {{ mommy }} loves your presence!",
|
||||||
|
"You're worthy of love and happiness, {{ name }}! {{ mommy }} wants you to always remember that!",
|
||||||
|
"You make the world a more beautiful place, {{ name }}! {{ mommy }} is so grateful for you!",
|
||||||
|
"Your efforts never go unnoticed, {{ name }}! {{ mommy }} sees everything you're doing!",
|
||||||
|
"You're a force to be reckoned with, {{ name }}! {{ mommy }} knows you're going to do great things!",
|
||||||
|
"No matter what, {{ mommy }} will always be here to support you, {{ name }}!",
|
||||||
|
"You're an inspiration, {{ name }}! {{ mommy }} hopes you see how incredible you are!",
|
||||||
|
"Even on your hardest days, {{ mommy }} sees your strength, {{ name }}!",
|
||||||
|
"You're never alone, {{ name }}! {{ mommy }} is always here to lift you up!",
|
||||||
|
"You make every day brighter, {{ name }}! {{ mommy }} loves the joy you bring!",
|
||||||
|
"You're so intelligent and capable, {{ name }}! {{ mommy }} believes in you completely!",
|
||||||
|
"You're a wonderful person, {{ name }}! {{ mommy }} hopes you never forget that!",
|
||||||
|
"You're an absolute gem, {{ name }}! {{ mommy }} is so lucky to have you around!",
|
||||||
|
"You're making progress every single day, {{ name }}! {{ mommy }} is so proud of you!",
|
||||||
|
"Your heart is so big and full of kindness, {{ name }}! {{ mommy }} sees your beautiful soul!",
|
||||||
|
"Even if you don’t see it, {{ mommy }} knows you’re growing and improving, {{ name }}!",
|
||||||
|
"Your dreams matter, {{ name }}! {{ mommy }} knows you can reach them!",
|
||||||
|
"You deserve all the happiness in the world, {{ name }}! {{ mommy }} hopes you never settle for less!",
|
||||||
|
"You radiate positivity, {{ name }}! {{ mommy }} loves the warmth you bring!",
|
||||||
|
"You're making a difference in the world, {{ name }}! {{ mommy }} sees all the good you do!",
|
||||||
|
"You're so much stronger than you think, {{ name }}! {{ mommy }} believes in you!",
|
||||||
|
"You're an absolute joy to be around, {{ name }}! {{ mommy }} treasures every moment with you!",
|
||||||
|
"Your happiness is important, {{ name }}! {{ mommy }} wants you to do what makes you shine!",
|
||||||
|
"You're always learning and growing, {{ name }}! {{ mommy }} is so proud of you!",
|
||||||
|
"You can achieve anything, {{ name }}! {{ mommy }} has no doubt about that!",
|
||||||
|
"You're doing better than you think, {{ name }}! {{ mommy }} is proud of you every step of the way!",
|
||||||
|
"You're someone worth celebrating, {{ name }}! {{ mommy }} hopes you always remember that!",
|
||||||
|
"Your kindness and compassion make you truly special, {{ name }}! {{ mommy }} loves that about you!",
|
||||||
|
"You're truly one of a kind, {{ name }}! {{ mommy }} wouldn’t trade you for the world!",
|
||||||
|
"Keep being you, {{ name }}! {{ mommy }} loves you just as you are!",
|
||||||
|
"Every little step forward is still progress, {{ name }}! {{ mommy }} is proud of you for each one!",
|
||||||
|
"You deserve love, respect, and happiness, {{ name }}! {{ mommy }} will always remind you of that!",
|
||||||
|
"You're so brave and resilient, {{ name }}! {{ mommy }} knows you can overcome anything!",
|
||||||
|
"Your strength and determination inspire {{ mommy }} so much, {{ name }}! Keep going!",
|
||||||
|
"You're a gift to the world, {{ name }}! {{ mommy }} is so grateful for your presence!",
|
||||||
|
"You're capable of amazing things, {{ name }}! {{ mommy }} can't wait to see what you do next!",
|
||||||
|
"You're a shining star, {{ name }}! {{ mommy }} loves watching you light up the world!",
|
||||||
|
"You're more powerful than you realize, {{ name }}! {{ mommy }} knows you can do anything!",
|
||||||
|
"You're so special, {{ name }}! {{ mommy }} loves everything that makes you unique!",
|
||||||
|
"You're doing great, {{ name }}! {{ mommy }} is so proud of the progress you're making!",
|
||||||
|
"You're so loved and appreciated, {{ name }}! {{ mommy }} hopes you never forget that!",
|
||||||
|
"You're a true inspiration, {{ name }}! {{ mommy }} admires your strength and courage!",
|
||||||
|
"You're capable of amazing things, {{ name }}! {{ mommy }} believes in you completely!",
|
||||||
|
"You're a wonderful person, {{ name }}! {{ mommy }} is so grateful to know you!",
|
||||||
|
"You're making a difference in the world, {{ name }}! {{ mommy }} sees the impact you have!",
|
||||||
|
"You're so much stronger than you think, {{ name }}! {{ mommy }} knows you can do anything!",
|
||||||
|
"You're a masterpiece in the making, {{ name }}! {{ mommy }} is so proud of you!",
|
||||||
|
"You're a light in the darkness, {{ name }}! {{ mommy }} loves the brightness you bring!",
|
||||||
|
"You're doing better than you think, {{ name }}! {{ mommy }} is proud of your progress!",
|
||||||
|
"You're so brave and resilient, {{ name }}! {{ mommy }} knows you can overcome anything!",
|
||||||
|
"You're a gift to the world, {{ name }}! {{ mommy }} is so grateful for your presence!",
|
||||||
|
"{{ mommy }} believes in you, {{ name }}! You're capable of amazing things!",
|
||||||
|
"{{ mommy }} loves you, {{ name }}! You're doing an amazing job!",
|
||||||
|
"{{ mommy }} knows you can do it, {{ name }}! Keep going!",
|
||||||
|
"{{ mommy }} is always here for you, {{ name }}! You're never alone!",
|
||||||
|
"{{ mommy }} is cheering for you, {{ name }}! You're doing great!",
|
||||||
|
"{{ mommy }} is so proud of you, {{ name }}! Keep up the good work!",
|
||||||
|
"{{ mommy }} loves you, {{ name }}! You're doing an amazing job!",
|
||||||
|
"{{ mommy }} knows you can do it, {{ name }}! Keep going!",
|
||||||
|
"{{ mommy }} is always here for you, {{ name }}! You're never alone!",
|
||||||
|
"{{ mommy }} is cheering for you, {{ name }}! You're doing great!",
|
||||||
|
"{{ mommy }} loves you, {{ name }}! You're doing an amazing job!",
|
||||||
|
"{{ name }}, you're doing such an amazing job! {{ mommy }} is so proud of you!",
|
||||||
|
"Keep going, {{ name }}! You're making incredible progress, and {{ mommy }} sees all the effort you're putting in!",
|
||||||
|
"No matter what happens, {{ name }}, remember that {{ mommy }} is always cheering for you!",
|
||||||
|
"You light up the world with your hard work and kindness, {{ name }}! {{ mommy }} is so lucky to know you!",
|
||||||
|
];
|
53
src/index.ts
Normal file
53
src/index.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* @copyright nhcarrigan
|
||||||
|
* @license Naomi's Public License
|
||||||
|
* @author Naomi Carrigan
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { randomInt } from "node:crypto";
|
||||||
|
import fastify, { type FastifyInstance } from "fastify";
|
||||||
|
import { html } from "./config/html.js";
|
||||||
|
import { mommy } from "./config/mommy.js";
|
||||||
|
import { phrases } from "./config/phrases.js";
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-non-null-assertion -- Yeah, I'm not dealing with the logical branches. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry function. Exported solely for tests.
|
||||||
|
* @returns The server instance for testing.
|
||||||
|
*/
|
||||||
|
const main = async(): Promise<FastifyInstance> => {
|
||||||
|
const server = fastify({
|
||||||
|
logger: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
server.get("/", (_request, response) => {
|
||||||
|
response.header("Content-Type", "text/html");
|
||||||
|
response.send(html);
|
||||||
|
});
|
||||||
|
|
||||||
|
// @ts-expect-error Whatever.
|
||||||
|
server.get("/api", (request: { query: { name?: string } }, response) => {
|
||||||
|
const name = request.query.name ?? "dear";
|
||||||
|
|
||||||
|
const phrase = phrases[randomInt(0, phrases.length)];
|
||||||
|
const mom = mommy[randomInt(0, mommy.length)];
|
||||||
|
|
||||||
|
const result = phrase!.
|
||||||
|
replaceAll("{{ name }}", name).
|
||||||
|
replaceAll("{{ mommy }}", mom!);
|
||||||
|
response.header("Content-Type", "text/plain");
|
||||||
|
response.send(result.toLowerCase());
|
||||||
|
});
|
||||||
|
|
||||||
|
await server.listen({ port: 8008 });
|
||||||
|
|
||||||
|
return await server;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* istanbul ignore if -- @preserve*/
|
||||||
|
if (process.env.TEST !== "true") {
|
||||||
|
void main();
|
||||||
|
}
|
||||||
|
|
||||||
|
export { main };
|
15
test/html.spec.ts
Normal file
15
test/html.spec.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* @copyright nhcarrigan
|
||||||
|
* @license Naomi's Public License
|
||||||
|
* @author Naomi Carrigan
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { html } from "../src/config/html.ts";
|
||||||
|
|
||||||
|
describe("html", () => {
|
||||||
|
it(`should be a string`, () => {
|
||||||
|
expect.assertions(1);
|
||||||
|
expect(html, "what did you do").toBeTypeOf("string");
|
||||||
|
});
|
||||||
|
});
|
83
test/index.spec.ts
Normal file
83
test/index.spec.ts
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/**
|
||||||
|
* @copyright nhcarrigan
|
||||||
|
* @license Naomi's Public License
|
||||||
|
* @author Naomi Carrigan
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
import { html } from "../src/config/html.ts";
|
||||||
|
import { mommy } from "../src/config/mommy.ts";
|
||||||
|
import { phrases } from "../src/config/phrases.ts";
|
||||||
|
import { main } from "../src/index.ts";
|
||||||
|
|
||||||
|
/* eslint-disable max-nested-callbacks, max-lines-per-function -- Not sure how to better optimise this. */
|
||||||
|
|
||||||
|
describe("fastify Server", () => {
|
||||||
|
it("should return HTML content on /", async() => {
|
||||||
|
expect.assertions(3);
|
||||||
|
const server = await main();
|
||||||
|
const response = await server.inject({
|
||||||
|
method: "GET",
|
||||||
|
url: "/",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response.statusCode, "wrong status").toBe(200);
|
||||||
|
expect(response.headers["content-type"], "wrong content type").
|
||||||
|
toContain("text/html");
|
||||||
|
expect(response.body, "wrong response").toBe(html);
|
||||||
|
await server.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return a formatted phrase on /api", async() => {
|
||||||
|
expect.assertions(3);
|
||||||
|
const server = await main();
|
||||||
|
const response = await server.inject({
|
||||||
|
method: "GET",
|
||||||
|
url: "/api",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response.statusCode, "wrong status").toBe(200);
|
||||||
|
expect(response.headers["content-type"], "wrong content type").
|
||||||
|
toContain("text/plain");
|
||||||
|
|
||||||
|
const possibleResponses = phrases.flatMap((phrase) => {
|
||||||
|
return mommy.map((mom) => {
|
||||||
|
return phrase.
|
||||||
|
replaceAll("{{ name }}", "dear").
|
||||||
|
replaceAll("{{ mommy }}", mom).
|
||||||
|
toLowerCase();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(possibleResponses, "where did it come from").
|
||||||
|
toContain(response.body);
|
||||||
|
await server.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return a formatted phrase with a name query on /api", async() => {
|
||||||
|
expect.assertions(3);
|
||||||
|
const server = await main();
|
||||||
|
const testName = "Naomi";
|
||||||
|
const response = await server.inject({
|
||||||
|
method: "GET",
|
||||||
|
url: `/api?name=${testName}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response.statusCode, "wrong status").toBe(200);
|
||||||
|
expect(response.headers["content-type"], "wrong content type").
|
||||||
|
toContain("text/plain");
|
||||||
|
|
||||||
|
const possibleResponses = phrases.flatMap((phrase) => {
|
||||||
|
return mommy.map((mom) => {
|
||||||
|
return phrase.
|
||||||
|
replaceAll("{{ name }}", testName).
|
||||||
|
replaceAll("{{ mommy }}", mom).
|
||||||
|
toLowerCase();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(possibleResponses, "where did it come from").
|
||||||
|
toContain(response.body);
|
||||||
|
await server.close();
|
||||||
|
});
|
||||||
|
});
|
20
test/mommy.spec.ts
Normal file
20
test/mommy.spec.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* @copyright nhcarrigan
|
||||||
|
* @license Naomi's Public License
|
||||||
|
* @author Naomi Carrigan
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable max-nested-callbacks -- Not sure how to better optimise this. */
|
||||||
|
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { mommy } from "../src/config/mommy.ts";
|
||||||
|
|
||||||
|
describe("mommy", () => {
|
||||||
|
it.each(mommy)(`%s should be unique`, (mom) => {
|
||||||
|
expect.assertions(1);
|
||||||
|
const matches = mommy.filter((m) => {
|
||||||
|
return m === mom;
|
||||||
|
});
|
||||||
|
expect(matches.length, `${mom} is not unique!`).toBeLessThan(2);
|
||||||
|
});
|
||||||
|
});
|
35
test/phrases.spec.ts
Normal file
35
test/phrases.spec.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* @copyright nhcarrigan
|
||||||
|
* @license Naomi's Public License
|
||||||
|
* @author Naomi Carrigan
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable max-nested-callbacks -- Not sure how to better optimise this. */
|
||||||
|
|
||||||
|
import compare from "string-comparison";
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { phrases } from "../src/config/phrases.ts";
|
||||||
|
|
||||||
|
describe("phrases", () => {
|
||||||
|
it("should have enough phrases", () => {
|
||||||
|
expect.assertions(1);
|
||||||
|
expect(phrases.length, "less than 100 phrases").toBeGreaterThan(100);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each(phrases)(`%s should be unique`, (phrase) => {
|
||||||
|
expect.assertions(1);
|
||||||
|
const filtered = phrases.filter((p) => {
|
||||||
|
return p !== phrase;
|
||||||
|
}).map((line) => {
|
||||||
|
return line.
|
||||||
|
replaceAll("{{ mommy }}", "").
|
||||||
|
replaceAll("{{ name }}", "");
|
||||||
|
});
|
||||||
|
|
||||||
|
const matches = compare.levenshtein.sortMatch(phrase.
|
||||||
|
replaceAll("{{ mommy }}", "").
|
||||||
|
replaceAll("{{ name }}", ""), filtered);
|
||||||
|
const closest = matches.reverse()[0];
|
||||||
|
expect(closest?.rating, `${phrase} is not unique! Matches ${closest?.member}`).toBeLessThan(0.8);
|
||||||
|
});
|
||||||
|
});
|
8
tsconfig.json
Normal file
8
tsconfig.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"extends": "@nhcarrigan/typescript-config",
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "./src",
|
||||||
|
"outDir": "./prod",
|
||||||
|
},
|
||||||
|
"exclude": ["./test", "vitest.config.ts"]
|
||||||
|
}
|
18
vitest.config.ts
Normal file
18
vitest.config.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { defineConfig } from "vitest/config";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
coverage: {
|
||||||
|
provider: "istanbul",
|
||||||
|
reporter: ["text", "html"],
|
||||||
|
all: true,
|
||||||
|
allowExternal: true,
|
||||||
|
thresholds: {
|
||||||
|
lines: 100,
|
||||||
|
statements: 100,
|
||||||
|
branches: 100,
|
||||||
|
functions: 100,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user