Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ npm run smoke # load the ESM, CJS, and IIFE builds; requires dist/
npm run check # format, lint, typecheck, build, test, smoke, publint
```

Node.js **24+**. Run `npm run check` before handing work back. Run `npm run test:coverage` when you add or change an executable `src/` file. `src/index.ts`, `src/runtime/types.ts`, and `src/templates/email/types.ts` are excluded: v8 reports 0% on files with no runtime code.
Node.js **24+**. Run `npm run check` before handing work back. Run `npm run test:coverage` when you add or change an executable `src/` file. `src/index.ts`, `src/runtime/types.ts`, `src/templates/email/types.ts`, and `src/templates/document/index.ts` are excluded: v8 reports 0% on files with no runtime code.

ESLint and Prettier both run in CI. Tests are Vitest, not Jest. `markup-generator` is a devDependency used to write rendered HTML in `test/write.test.ts` and `npm run generate`. It is not a runtime dependency.

Expand Down
13 changes: 9 additions & 4 deletions test/email.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,15 @@ describe('renderEmail', () => {
bodyAttributes: 'style="margin:0"',
},
});
const html = renderEmail(template, { title: 'Hi', bodyAttributes: 'style="padding:0"' }).html;
expect(html).toMatch(/^<!DOCTYPE html PUBLIC/);
expect(html).toContain('<html xmlns="http://www.w3.org/1999/xhtml">');
expect(html).not.toContain('lang=');
const html = renderEmail(template, {
title: 'Hi',
doctype: '<!DOCTYPE html>',
lang: 'fr',
htmlAttributes: 'class="override"',
bodyAttributes: 'style="padding:0"',
}).html;
expect(html).toMatch(/^<!DOCTYPE html>/);
expect(html).toContain('<html lang="fr" class="override">');
expect(html).toContain('<body style="padding:0">');
});

Expand Down
7 changes: 4 additions & 3 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,13 @@ describe('document', () => {
it('accepts structured attributes on html and body', () => {
const html = document({
lang: false,
htmlAttributes: { xmlns: 'http://www.w3.org/1999/xhtml', class: 'email' },
bodyAttributes: { style: 'margin:0', 'data-theme': 'light' },
htmlAttributes: { xmlns: 'http://www.w3.org/1999/xhtml', class: 'email', hidden: true },
bodyAttributes: { style: 'margin:0', 'data-theme': 'light', disabled: false },
mainHtml: '<p>Hi</p>',
});
expect(html).toContain('<html xmlns="http://www.w3.org/1999/xhtml" class="email">');
expect(html).toContain('<html xmlns="http://www.w3.org/1999/xhtml" class="email" hidden>');
expect(html).toContain('<body style="margin:0" data-theme="light">');
expect(html).not.toContain('disabled');
});

it('supports body attributes and omitting lang (good-news style)', () => {
Expand Down
7 changes: 6 additions & 1 deletion vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ export default defineConfig({
provider: 'v8',
reporter: ['text', 'html'],
include: ['src/**/*.ts'],
exclude: ['src/index.ts', 'src/runtime/types.ts', 'src/templates/email/types.ts'],
exclude: [
'src/index.ts',
'src/runtime/types.ts',
'src/templates/email/types.ts',
'src/templates/document/index.ts',
],
thresholds: {
statements: 100,
branches: 100,
Expand Down
Loading