Skip to content

[WIP] Add unit tests using built-in Node.js test library#131

Draft
Copilot wants to merge 1 commit intomasterfrom
copilot/add-unit-tests-module
Draft

[WIP] Add unit tests using built-in Node.js test library#131
Copilot wants to merge 1 commit intomasterfrom
copilot/add-unit-tests-module

Conversation

Copy link

Copilot AI commented Feb 10, 2026

Unit Tests Implementation Plan

  • Create tests/ directory structure
  • Add test script to package.json
  • Create unit tests for AdaptFrameworkUtils.js
    • Test inferBuildAction() method
    • Test getPluginUpdateStatus() method
    • Test getImportContentCounts() method
    • Test toBoolean() method
  • Create unit tests for AdaptFrameworkImport.js
    • Test typeToSchema() static method
  • Add GitHub Actions workflow for running tests
  • Run tests to ensure they pass
  • Run linter to ensure code quality
Original prompt

This section details on the original issue you should resolve

<issue_title>Add unit tests</issue_title>
<issue_description># Writing tests

Instructions for writing tests in this module.

Stack

No external test dependencies are needed. Do not introduce Mocha, Jest, or other test frameworks.

Note: Some older modules in the project use Mocha + Should.js. New tests in this module use the built-in Node.js test library instead.

File placement and naming

  • Tests live in a tests/ directory at the module root
  • One test file per source module, named <moduleName>.spec.js
  • Test data/fixtures go in tests/data/
my-module/
├── lib/
│   ├── myModule.js
│   └── myUtils.js
└── tests/
    ├── data/
    │   └── fixtures.json
    ├── myModule.spec.js
    └── myUtils.spec.js

File structure

Every test file follows this structure:

import { describe, it, before } from 'node:test'
import assert from 'node:assert/strict'
import MyModule from '../lib/myModule.js'

describe('My Module', () => {
  let instance

  before(() => {
    instance = new MyModule()
  })

  describe('#methodName()', () => {
    it('should describe expected behaviour', () => {
      assert.equal(instance.methodName(), 'expected')
    })
  })
})

Key rules:

  • Import describe, it, before, after etc. from node:test
  • Import assert from node:assert/strict (strict mode uses deepStrictEqual by default)
  • Use ES module import syntax — this project is "type": "module"
  • Group tests by method using nested describe blocks, prefixed with # for instance methods
  • Store shared state in let variables scoped to the describe block

Assertions

Use node:assert/strict. Common patterns:

// equality (uses Object.is)
assert.equal(actual, expected)

// deep equality (objects/arrays)
assert.deepEqual(actual, { key: 'value' })

// booleans
assert.equal(result, true)
assert.equal(result, false)

// truthy / falsy
assert.ok(value)
assert.ok(!value)

// type checks
assert.equal(typeof value, 'object')
assert.ok(Array.isArray(value))
assert.ok(value instanceof MyClass)

// expected errors (sync)
assert.throws(() => dangerousCall(), { name: 'TypeError' })

// expected errors (async)
await assert.rejects(asyncCall(), { name: 'Error' })

// not equal
assert.notEqual(a, b)
assert.notDeepEqual(obj1, obj2)

Dynamic test generation

When testing a function against multiple inputs, generate tests in a loop:

const validInputs = ['a@b.com', 'test@example.org']
const invalidInputs = ['not-an-email', '@missing.user']

validInputs.forEach((input) => {
  it(`should accept ${input}`, () => {
    assert.equal(validate(input), true)
  })
})

invalidInputs.forEach((input) => {
  it(`should reject ${input}`, () => {
    assert.equal(validate(input), false)
  })
})

Async tests

node:test supports async/await directly:

it('should connect successfully', async () => {
  const result = await instance.connect()
  assert.equal(typeof result, 'object')
})

Test data

Place fixture files in tests/data/. Use import or fs to load them:

import { readFileSync } from 'node:fs'
import { join, dirname } from 'node:path'
import { fileURLToPath } from 'node:url'

const __dirname = dirname(fileURLToPath(import.meta.url))
const fixtures = JSON.parse(readFileSync(join(__dirname, 'data', 'fixtures.json')))

What to test

  • All public methods on exported classes and utilities
  • Both success and error paths
  • Edge cases (empty input, missing arguments, invalid types)
  • That errors are thrown or returned where expected (use assert.throws / assert.rejects)

What NOT to do

  • Don't test private/internal methods (prefixed with _)
  • Don't add external test dependencies — node:test and node:assert are sufficient
  • Don't write tests that depend on execution order between describe blocks
  • Don't mock more than necessary — prefer testing real behaviour

Add script to package.json

The tests should be accessible via an npm script in package.json:

"scripts": {
  "test": "node --test tests/"
}

Add GitHub workflow

The following workflow should be added to /.github:

name: Tests
on: push
jobs:
  default:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - uses: actions/setup-node@master
        with:
          node-version: 'lts/*'
          cache: 'npm'
      - run: npm ci
      - run: npm test

Running tests

# run the test suite
npm test

# run the linter
npx standard

Both must pass before submitting a pull request.
</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add unit tests

2 participants