Skip to content

Commit

Permalink
Merge pull request #7 from trueberryless-org/tests
Browse files Browse the repository at this point in the history
Write tests
  • Loading branch information
trueberryless authored Jan 16, 2025
2 parents e39cb3f + 034a0bd commit f5b6ab7
Show file tree
Hide file tree
Showing 268 changed files with 5,946 additions and 388 deletions.
20 changes: 11 additions & 9 deletions packages/starlight-spell-checker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import {
type StarlightSpellCheckerConfig,
type StarlightSpellCheckerUserConfig,
} from "./libs/config";
import { logErrors, logWarnings, validateTexts } from "./libs/validation";
import {
logErrors,
logUnsupportedLanguages,
logWarnings,
validateTexts,
} from "./libs/validation";
import { clearContentLayerCache } from "./libs/astro";
import { remarkStarlightSpellChecker } from "./libs/remark";
import { green } from "kleur/colors";
Expand Down Expand Up @@ -43,20 +48,17 @@ export default function starlightSpellChecker(
},
],
],
smartypants: false,
},
});
},
"astro:build:done": async ({ dir, pages }) => {
const { warnings, errors } = await validateTexts(
pages,
dir,
astroConfig,
starlightConfig,
config
);
"astro:build:done": async () => {
const { warnings, errors, unsupportedLanguages } =
await validateTexts(config);

logWarnings(logger, warnings);
logErrors(logger, errors);
logUnsupportedLanguages(logger, unsupportedLanguages);

if (warnings.size <= 0 && errors.size <= 0) {
logger.info(green("✓ All words spelled correctly.\n"));
Expand Down
170 changes: 170 additions & 0 deletions packages/starlight-spell-checker/libs/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ const configSchema = z
* @default false
*/
throwError: z.boolean().default(false),

/**
* Defines a list of words that should be ignored by the case police checker.
*
* The words in this list will be ignored by the case police checker and will not be considered as misspelled.
*
* @default []
*/
ignore: z.array(z.string()).default([]),
})
.default({}),

Expand All @@ -104,6 +113,23 @@ const configSchema = z
* @default false
*/
throwError: z.boolean().default(false),

/**
* Whether to ignore [literal words](https://github.com/syntax-tree/nlcst-is-literal).
*
* @default true
*/
ignoreLiterals: z.boolean().default(true),

/**
* Whether to suggest straight (') or smart (’) apostrophes.
*
* @default "smart"
*/
mode: z
.enum(["smart", "straight"])
.default("smart")
.transform((value) => value === "straight"),
})
.default({}),

Expand Down Expand Up @@ -152,6 +178,22 @@ const configSchema = z
* @default false
*/
throwError: z.boolean().default(false),

/**
* Defines a list of words that should be ignored by the equality checker.
*
* The words in this list will be ignored by the equality checker and will not be considered as inconsiderate.
*
* @default []
*/
ignore: z.array(z.string()).default([]),

/**
* Whether to allow "he or she", "garbagemen and garbagewomen", etc.
*
* @default false
*/
binary: z.boolean().default(false),
})
.default({}),

Expand Down Expand Up @@ -200,6 +242,15 @@ const configSchema = z
* @default false
*/
throwError: z.boolean().default(false),

/**
* Defines a list of words that should be ignored by the intensify checker.
*
* The words in this list will be ignored by the intensify checker and will not be considered as weak.
*
* @default []
*/
ignore: z.array(z.string()).default([]),
})
.default({}),

Expand Down Expand Up @@ -248,6 +299,15 @@ const configSchema = z
* @default false
*/
throwError: z.boolean().default(false),

/**
* Defines a list of words that should be ignored by the passive checker.
*
* The words in this list will be ignored by the passive checker and will not be considered as passive.
*
* @default []
*/
ignore: z.array(z.string()).default([]),
})
.default({}),

Expand All @@ -272,11 +332,36 @@ const configSchema = z
* @default false
*/
throwError: z.boolean().default(false),

/**
* Defines a list of words that should be ignored by the profanity checker.
*
* The words in this list will be ignored by the profanity checker and will not be considered as vulgar.
*
* @default []
*/
ignore: z.array(z.string()).default([]),

/**
* Minimum sureness to warn about, see [cuss](https://github.com/words/cuss)
*
* @default 0
*/
sureness: z
.number()
.refine((val) => [0, 1, 2].includes(val), {
message: "Number must be 0, 1, or 2",
})
.default(0),
})
.default({}),

/**
* Configuration for the readability plugin.
*
* It applies [Dale—Chall](https://github.com/words/dale-chall-formula),
[Automated Readability](https://github.com/words/automated-readability), [Coleman-Liau](https://github.com/words/coleman-liau), [Flesch](https://github.com/words/flesch),
[Gunning-Fog](https://github.com/words/gunning-fog), [SMOG](https://github.com/words/smog-formula), and [Spache](https://github.com/words/spache-formula).
*/
readability: z
.object({
Expand All @@ -296,6 +381,33 @@ const configSchema = z
* @default false
*/
throwError: z.boolean().default(false),

/**
* Defines the target age group.
*
* @default 22
*/
age: z.number().default(22),

/**
* Defines the minimum number of words.
*
* Evaluate sentences containing at least this number of words. While most algorithms assess the reading level of an entire text, this plugin analyzes each sentence individually. Short sentences, however, can be disproportionately influenced by a single long or complex word.
*
* @default 5
*/
minWords: z.number().default(5),

/**
* Defines how many algorithms (out of 7) need to agree that something is hard to read.
*
* The algorithms are: [Dale—Chall](https://github.com/words/dale-chall-formula),
[Automated Readability](https://github.com/words/automated-readability), [Coleman-Liau](https://github.com/words/coleman-liau), [Flesch](https://github.com/words/flesch),
[Gunning-Fog](https://github.com/words/gunning-fog), [SMOG](https://github.com/words/smog-formula), and [Spache](https://github.com/words/spache-formula)
*
* @default 4/7
*/
threshold: z.number().default(4 / 7),
})
.default({}),

Expand Down Expand Up @@ -368,6 +480,15 @@ const configSchema = z
* @default false
*/
throwError: z.boolean().default(false),

/**
* Defines a list of words that should be ignored by the simplify checker.
*
* The words in this list will be ignored by the simplify checker and will not be considered as simplifiable.
*
* @default []
*/
ignore: z.array(z.string()).default([]),
})
.default({}),

Expand Down Expand Up @@ -416,6 +537,55 @@ const configSchema = z
* @default false
*/
throwError: z.boolean().default(false),

/**
* Whether to suggest straight (') or smart (’) apostrophes.
*
* @default "smart"
*/
mode: z.enum(["smart", "straight"]).default("smart"),

smart: z
.union([
z.array(
z.string().refine((str) => str.length === 1 || str.length === 2, {
message:
"Each quote must be either one or two characters long.",
})
),
z.record(
z.array(
z
.string()
.refine((str) => str.length === 1 || str.length === 2, {
message:
"Each quote must be either one or two characters long.",
})
)
),
])
.default(["“”", "‘’"]),

straight: z
.union([
z.array(
z.string().refine((str) => str.length === 1 || str.length === 2, {
message:
"Each quote must be either one or two characters long.",
})
),
z.record(
z.array(
z
.string()
.refine((str) => str.length === 1 || str.length === 2, {
message:
"Each quote must be either one or two characters long.",
})
)
),
])
.default(['"', "'"]),
})
.default({}),

Expand Down
6 changes: 4 additions & 2 deletions packages/starlight-spell-checker/libs/i18n.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ensureLeadingSlash, ensureTrailingSlash } from "./path";
import type { StarlightUserConfig } from "./validation";

import dictionaryDa from "dictionary-da";
import dictionaryDe from "dictionary-de";
import dictionaryEn, { type Dictionary } from "dictionary-en";
import dictionaryEs from "dictionary-es";
Expand Down Expand Up @@ -38,8 +39,9 @@ export function getLocaleConfig(config: StarlightUserConfig): LocaleConfig {
};
}

const dictionaryMapper: Record<string, any> = {
const dictionaryMapper: Record<string, Dictionary | undefined> = {
ar: undefined,
da: dictionaryDa,
de: dictionaryDe,
en: dictionaryEn,
es: dictionaryEs,
Expand All @@ -55,7 +57,7 @@ const dictionaryMapper: Record<string, any> = {
"zh-tw": undefined,
};

export function getLocaleDictionary(path: string): Dictionary {
export function getLocaleDictionary(path: string): Dictionary | undefined {
return dictionaryMapper[path];
}

Expand Down
33 changes: 29 additions & 4 deletions packages/starlight-spell-checker/libs/remark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@ import "mdast-util-mdx-jsx";
import nodePath from "node:path";
import { fileURLToPath } from "node:url";

import { hasProperty } from "hast-util-has-property";
import type { Nodes } from "hast";
import { fromHtml } from "hast-util-from-html";
import { slug } from "github-slugger";
import type { Root } from "mdast";
import { unified, type Plugin } from "unified";
import { type Plugin } from "unified";
import { visit } from "unist-util-visit";

import { ensureTrailingSlash, stripLeadingSlash } from "./path";
import { getLocaleConfig, getLocale } from "./i18n";
import type { StarlightUserConfig } from "./validation";

import { unified } from "unified";
import rehypeParse from "rehype-parse";
import { toText } from "hast-util-to-text";

// All the text content keyed by locale, then keyed by file path.
const contents: Contents = new Map();

Expand All @@ -33,6 +34,30 @@ export const remarkStarlightSpellChecker: Plugin<

let fileContent: string = "";

// Extract all string values from frontmatter (recursively, with HTML parsing)
const frontmatter = file.data.astro?.frontmatter;
if (frontmatter) {
const extractStrings = (obj: any): string[] => {
const strings: string[] = [];
for (const value of Object.values(obj)) {
if (typeof value === "string") {
// Parse HTML and extract text content
const htmlTree = unified()
.use(rehypeParse, { fragment: true })
.parse(value);
const textContent = toText(htmlTree);
strings.push(textContent);
} else if (typeof value === "object" && value !== null) {
strings.push(...extractStrings(value));
}
}
return strings;
};

fileContent += extractStrings(frontmatter).join("\n");
fileContent += "\n"; // Separate frontmatter from the Markdown content
}

// https://github.com/syntax-tree/mdast#nodes
// https://github.com/syntax-tree/mdast-util-mdx-jsx#nodes
visit(
Expand Down
Loading

0 comments on commit f5b6ab7

Please sign in to comment.