npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

under-the-sun

v2.1.1

Published

A nothing-new-under-the-sun testing framework.

Downloads

174

Readme

Under the Sun

A nothing-new-under-the-sun testing framework.

This testing framework was inspired by the likes of uvu. It is intended to be as fast as possible yet as simple as possible.

Installation

npm install --save-dev under-the-sun

Usage

// examples/my.test.js
import assert from "node:assert"
import { test } from "under-the-sun"

test("something synchronous", () => {
  assert(2 === 2, "2 should be 2")
})

test("something asynchronous", async () => {
  await new Promise((resolve) => setTimeout(resolve, 1000))
  assert(2 === 3, "2 should still be...2")
})

Execute tests in a directory via CLI:

npx under-the-sun examples
# or with alias
npx uts examples

Execute a filtered set of tests via CLI:

npx under-the-sun examples my asynchronous

In this case, only files in the examples directory matching the regex my will be considered. Within those files, only tests whose descriptions match the regex asynchronous will be executed.

Output

If you're unsatisfied with the default test reporter, you can override it.

// examples/test-reporter.js
import { setTestReporter } from "under-the-sun"

let failure = false
setTestReporter({
  reportResult(testDescription, result) {
    if (!result.error) {
      // Do something about test success.
      return
    }

    // Do something about test failure.
    failure = true
    console.error("FAIL: " + testDescription)
  },
  reportFinish() {
    // Finalize the test run.
    process.exit(failure ? 1 : 0)
  },
})

Then just load this file alongside your tests:

uts -r examples/test-reporter.js examples

You can check out the default implementation for ideas.

CLI

The CLI is available via under-the-sun or uts.

uts [-p <file pattern>] [-i <ignore pattern>] [options] [<dir> [<file filter> [<description filter>]]]

Tests will be discovered automatically within the dir directory. Test files must match both file pattern and file filter to be executed. Only tests within those files matching description filter will be executed.

  • dir is the current directory by default.
  • file pattern is /\.test\.(j|t)s$/ by default.
  • ignore pattern is /(^|\/)(node_modules($|\/)|\.)/ by default.
    • i.e. ignores node_modules/ and dot files
  • file filter matches all files by default.
  • description filter matches all tests by default.

The file pattern, file filter, and description filter CLI arguments are passed directly to new RegExp(<pattern>).

If this seems confusing, start by just running uts without any arguments.

Options

  • -r/--require - Load a module/script prior to test execution.
  • -m/--magic - Make test and defineTestGroup globally available (no need to import/require).
  • -s/--serial - Run tests sequentially rather than in parallel (default). Note: This is only intended as a debugging mechanism for when your tests are failing intermittently in parallel. Tests will not run in deterministic order even with this flag.

API

The library exposes a couple items for programmatic usage, but it's a small enough surface area it will just be easier for you to check them out on your own.

Examples

See the examples/ directory for specific working examples.

Why should I use this?

You probably don't want to. That being said, here are some aims of this library:

  • Fast - This library pretty much just runs your JavaScript with as much async as possible. There's nothing fancy that could possibly slow things down. The only way make it meaningfully faster would be to use some alternative runtime (e.g. native code, process-level multithreading, caching).
  • Simple - This library doesn't provide a large API, so you're not tightly coupling your code to it in a way you can't easily change later.

I think this testing library is best for pure JavaScript/TypeScript Node.js libraries.

It's entirely possible someone has already written a library that does exactly what this does, better and with more features. I didn't find it though.

Why Not uvu?

You said this is like uvu. Why not just use that?

uvu doesn't do any kind of parallelization.

This library is still single-threaded, but it leverages the asynchronous concurrency built into JavaScript. This strategy is particularly helpful when you have a lot of tests with a significant I/O-bound component.

Why Not Jest?

You reference Jest's assertion library. Why not use it wholesale?

Jest is slow. It's pretty great to work with, but my experience has shown that it takes multiple seconds to run basic tests.

Why Not Vitest?

Vitest is focused on the web application ecosystem, not so much the Node library ecosystem.

Why Not AVA?

AVA has fallen out of favor, and I didn't want to waste time figuring out why. I'm guessing it has something to do with the opinionated-ness of it. Also, uvu's author claims that uvu is faster.

Why Not Mocha?

Mocha has also fallen out of favor. I've never used it, so maybe it's completely superior. ¯\(ツ)

Why Not Tape?

Also never used it.

TypeScript

If you're using TypeScript, you may want to run your tests with some kind of TypeScript module loader like esbuild-register, @swc-node/register, or ts-node.

under-the-sun -r esbuild-register examples
under-the-sun -r @swc-node/register examples
under-the-sun -r ts-node/register examples

Assertions

This library does not ship with any assertions. You'll have to find your own.

Here are some options for you:

Node's assert Module

Node's assert module comes with Node out of the box, so you don't have to install anything. It has a little bit of flexibility, but the reporting may not be as nice as you're used to.

import assert from "node:assert"

test("...", async () => {
  assert(2 === 2, "2 should be 2")
  assert.strictEqual(2, 3, "2 should still be 2")
  assert.deepStrictEqual({}, {}, "More complex equality")
})

Jest's expect Library

If you're coming from Jest, you may feel most comfortable picking up it's expect library.

import { expect } from "expect"

test("...", async () => {
  expect(2).toBe(2)
  expect({}).toStrictEqual({})
})

Chai

For a more traditional JS approach, you may want to use Chai.

import { assert } from "chai"

test("...", async () => {
  assert.equal(2, 3, "2 should still be 2")
})

Watching

To run tests in watch mode, follow a strategy like uvu's.

{
  "scripts": {
    "test:watch": "watchlist src -- uts examples"
  },
  "devDependencies": {
    "under-the-sun": "^1.0.0",
    "watchlist": "^0.2.1"
  }
}