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

In source / inline tests #48956

Closed
olalonde opened this issue Jul 28, 2023 · 7 comments
Closed

In source / inline tests #48956

olalonde opened this issue Jul 28, 2023 · 7 comments
Labels
feature request Issues that request new features to be added to Node.js. test_runner Issues and PRs related to the test runner subsystem.

Comments

@olalonde
Copy link
Contributor

What is the problem this feature will solve?

Sometimes you want to test a small utility function and would like to colocate the tests inside the same file as the library instead of using a separate file.

import assert from "node:assert/strict";
import test from "node:test";

export const ping = () => "pong";

// ping implementation and its tests live in the same file
test("ping", (_t) => {
  assert.equal(ping(), "pong");
});

What is the feature you are proposing to solve the problem?

vitest solves this problem by having the test runner add a property to import.meta and using it to conditionally run tests.

https://vitest.dev/guide/in-source.html

// src/index.js

// the implementation
export function add(...args) {
  return args.reduce((a, b) => a + b, 0)
}

// in-source test suites
if (import.meta.vitest) {
  const { it, expect } = import.meta.vitest
  it('add', () => {
    expect(add()).toBe(0)
    expect(add(1)).toBe(1)
    expect(add(1, 2, 3)).toBe(6)
  })
}

I am not sure if it's the best way to achieve this but it's one way.

What alternatives have you considered?

No response

@olalonde olalonde added the feature request Issues that request new features to be added to Node.js. label Jul 28, 2023
@cjihrig
Copy link
Contributor

cjihrig commented Jul 28, 2023

This has come up before and did not get an enthusiastic response: #45771.

You can already do the same thing like this:

if (process.env.NODE_ENV === 'test') {
  const test = require('node:test');
  // test things
}

@atlowChemi atlowChemi added the test_runner Issues and PRs related to the test runner subsystem. label Jul 31, 2023
@Lucas-Levandoski
Copy link

Code coverage may not easily reflect how much it is covered this way, the percentage will be misleading.

@cjihrig
Copy link
Contributor

cjihrig commented Aug 1, 2023

Fair enough. You're welcome to open a PR and see how it is received. Just to warn you ahead of time, I think you'll need to add a new CLI flag to support this in the way you're asking for, and I can envision people pushing back on that for such a niche feature.

Copy link
Contributor

There has been no activity on this feature request for 5 months and it is unlikely to be implemented. It will be closed 6 months after the last non-automated comment.

For more information on how the project manages feature requests, please consult the feature request management document.

@github-actions github-actions bot added the stale label Jan 29, 2024
@MadLittleMods
Copy link
Contributor

I solved this by using/abusing process.env.NODE_TEST_CONTEXT so the inline tests only run when --test is used. Is there a better condition to use? Out of the box, process.env.NODE_ENV is undefined when using --tests so you can't switch on it.

  • node ping.js: Does nothing (as expected)
  • node --test ping.js: Runs the tests (as expected)

ping.js

const test = require('node:test');
const assert = require('assert');

function ping() {
  return 'pong';
}

// Only run tests when using `--test` flag
if (process.env.NODE_TEST_CONTEXT) {
  test('ping', () => {
    assert.strictEqual(ping(), 'pong');
  });
}

module.exports = ping;

@pongo
Copy link

pongo commented Feb 14, 2024

I use if (process.env.NODE_ENV === "test" && require.main === module) {

"use strict";

function addTwo(a) {
  return internalAdder(a, 2);
}

if (process.env.NODE_ENV === "test" && require.main === module) {
  const assert = require("node:assert/strict");
  const { test } = require("node:test");

  test("addTwo()", () => {
    assert.equal(addTwo(4), 6);
  });
}

function internalAdder(a, b) {
  return a + b;
}

if (process.env.NODE_ENV === "test" && require.main === module) {
  const assert = require("node:assert/strict");
  const { test } = require("node:test");

  test("internal", () => {
    assert.equal(internalAdder(2, 2), 4);
  });

  test("float magic", () => {
    assert.equal(internalAdder(0.1, 0.2), 0.30000000000000004);
  });
}

module.exports = { addTwo };

And run the tests using test_runner.js

"use strict";

const fg = require("fast-glob").sync;
const { spec } = require("node:test/reporters");
const { run } = require("node:test");

process.env.NODE_ENV = "test";

const source = ["src/**/*.js", "test/**/*.test.js"];
const ignore = [];
const files = fg(source, { ignore })

files = fg(source, { ignore });
// console.log(files);

run({ files })
  .on("test:fail", () => {
    process.exitCode = 1;
  })
  .compose(new spec())
  .pipe(process.stdout);

@github-actions github-actions bot removed the stale label Feb 15, 2024
@cjihrig
Copy link
Contributor

cjihrig commented Mar 24, 2024

It doesn't seem like this has gained any traction (for the second time - #45771), so I'm going to close this. Anyone is free to open a PR implementing this though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Issues that request new features to be added to Node.js. test_runner Issues and PRs related to the test runner subsystem.
Projects
None yet
Development

No branches or pull requests

6 participants