Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write tests #7

Merged
merged 30 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1550945
update config with all configurations from plugins and write 2 tests …
trueberryless Jan 10, 2025
32ee3ea
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 10, 2025
28dddb8
write some more tests
trueberryless Jan 10, 2025
fe767e9
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 10, 2025
ef677b9
write tests for contractions
trueberryless Jan 10, 2025
0a59a63
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 10, 2025
a4e9261
new unsupported language log + tests
trueberryless Jan 10, 2025
9925f3a
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 10, 2025
4bccab1
no comment
trueberryless Jan 10, 2025
c835e2a
new tests
trueberryless Jan 11, 2025
e3bac4f
new tests for equality binary and intensify
trueberryless Jan 12, 2025
3304490
passive and profanities
trueberryless Jan 13, 2025
2646690
frontmatter adjustments + test
trueberryless Jan 13, 2025
7df3883
change indefinite article plugin to own
trueberryless Jan 13, 2025
a5777eb
redundant acronyms
trueberryless Jan 13, 2025
f8a0d5d
repeated words
trueberryless Jan 13, 2025
40c2be3
simplify
trueberryless Jan 13, 2025
e7f1f2b
udpate usage and write tests
trueberryless Jan 13, 2025
14bf167
fix case police package https://github.com/trueberryless-org/retext-c…
trueberryless Jan 14, 2025
63f2050
smartypants false; adjust contraction tests
trueberryless Jan 14, 2025
a2f6609
some quotes tests
trueberryless Jan 14, 2025
4560e21
more quotes tests
trueberryless Jan 14, 2025
a5749db
fix
trueberryless Jan 14, 2025
cf0dd45
fix assuming
trueberryless Jan 15, 2025
3f7a3d8
smart straight tests
trueberryless Jan 15, 2025
7da4a30
prepare last quotes tests
trueberryless Jan 15, 2025
2470baa
Update quotes and this fixes tests
trueberryless Jan 15, 2025
c1d991d
test cases
trueberryless Jan 15, 2025
664a870
v6.0.2 fix quote tests
trueberryless Jan 16, 2025
034a0bd
and the package files...
trueberryless Jan 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading