Thank you for your interest in contributing to the @nodejs/doc-kit project! We welcome contributions from everyone, and we appreciate your help in making this project better.
- Getting Started
- Development Workflow
- Writing Tests
- Code Quality
- Commit Guidelines
- Developer's Certificate of Origin 1.1
The steps below will give you a general idea of how to prepare your local environment for the @nodejs/doc-kit project and general steps for getting things done and landing your contribution.
- Node.js (latest LTS version, check the
.nvmrcfile) - Git
- A GitHub account
-
Fork the repository
Click the fork button in the top right, or the link in this paragraph, to clone the Node.js
doc-kitRepository -
Clone your fork
git clone git@github.com:<YOUR_GITHUB_USERNAME>/doc-kit.git # SSH git clone https://github.com/<YOUR_GITHUB_USERNAME>/doc-kit.git # HTTPS gh repo clone <YOUR_GITHUB_USERNAME>/doc-kit # GitHub CLI
-
Navigate to the project directory
cd doc-kit -
Set up upstream remote
git remote add upstream git@github.com:nodejs/doc-kit # SSH git remote add upstream https://github.com/nodejs/doc-kit # HTTPS gh repo sync nodejs/doc-kit # GitHub CLI
-
Install dependencies
npm install
-
Create a new branch for your work
git checkout -b <name-of-your-branch>
-
Perform your changes
Make your code changes, add features, fix bugs, or improve documentation.
-
Keep your branch up-to-date
git fetch upstream git merge upstream/main
-
Test your changes
node --run test node --run test:coverage # To check code coverage
-
Check code quality
node --run format node --run lint
-
Add and commit your changes
git add . git commit -m "describe your changes"
-
Push to your fork
git push -u origin <name-of-your-branch>
-
Create a Pull Request
Go to your fork on GitHub and create a Pull Request to the main repository.
Important
Before committing and opening a Pull Request, please go through our Commit Guidelines and ensure your code passes all tests and quality checks.
Testing is a crucial part of maintaining code quality and ensuring reliability. All contributions should include appropriate tests.
- Patches (PRs) are required to maintain 80% coverage minimum
- Contributors are encouraged to strive for 95-100% coverage
- New features and bug fixes should include corresponding tests
- Tests should cover both happy path and edge cases
Tests should be organized to mirror the source code structure:
-
For a source file at
/src/index.mjs, create a test file at/src/__tests__/index.test.mjs -
For a source file at
/src/utils/parser.mjs, create a test file at/src/utils/__tests__/parser.test.mjs -
Test files should use the
.test.mjsextension -
For a fixture used in
/src/__tests__/some.test.mjs, place the fixture at/src/__tests__/fixtures/some-fixture.mjs. -
When fixtures are used in multiple tests, place them in the test directory of the closest shared ancestor. For instance, if a fixture is used by both
/src/__tests__/some.test.mjs, and/src/utils/__tests__/parser.test.mjs, the fixture belongs in/src/__tests__/fixtures/.
Tests should follow these guidelines:
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';Use describe and it syntax for organizing tests:
describe('MyModule', () => {
describe('myFunction', () => {
it('should return expected result for valid input', () => {
// Test implementation
assert.strictEqual(actual, expected);
});
it('should throw error for invalid input', () => {
assert.throws(() => {
// Code that should throw
});
});
});
});- Use strict assertions: Always use
node:assert/strictovernode:assert. - Focused testing: Tests should ideally only test the specific file they are intended for
- Use mocking: Mock external dependencies to isolate the code under test
- Code splitting: Encourage breaking down complex functionality for easier testing
// tests/index.test.mjs
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import { myFunction } from '../index.mjs';
describe('index.mjs', () => {
describe('myFunction', () => {
it('should process valid input correctly', () => {
const input = 'test input';
const result = myFunction(input);
assert.strictEqual(result, 'expected output');
});
it('should handle edge cases', () => {
assert.strictEqual(myFunction(''), '');
assert.strictEqual(myFunction(null), null);
});
it('should throw for invalid input', () => {
assert.throws(() => myFunction(undefined), {
name: 'TypeError',
message: 'Input cannot be undefined',
});
});
});
});# Run all tests
node --run test
# Run tests with coverage
node --run test:coverage
# Run specific test file
node --test src/test/index.test.mjsThis project uses automated code quality tools:
# Format code
node --run format # To apply changes, use `format:write`
# Lint code
node --run lint # To apply changes, use `lint:fix`This project uses Husky for Git pre-commit hooks that automatically lint and format your code before committing.
You can bypass pre-commit hooks if necessary (not recommended):
git commit -m "describe your changes" --no-verifyThis project follows the Conventional Commits specification.
By contributing to this project, I certify that:
- (a) The contribution was created in whole or in part by me and I have the right to
submit it under the open source license indicated in the file; or
- (b) The contribution is based upon previous work that, to the best of my knowledge,
is covered under an appropriate open source license and I have the right under that
license to submit that work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am permitted to submit under a
different license), as indicated in the file; or
- (c) The contribution was provided directly to me by some other person who certified
(a), (b) or (c) and I have not modified it.
- (d) I understand and agree that this project and the contribution are public and that
a record of the contribution (including all personal information I submit with it,
including my sign-off) is maintained indefinitely and may be redistributed consistent
with this project or the open source license(s) involved.