Giter VIP home page Giter VIP logo

uvu's Introduction

uvu
uvu is an extremely fast and lightweight test runner for Node.js and the browser
Ultimate Velocity, Unleashed

example with suites

Features

  • Super lightweight
  • Extremely performant
  • Individually executable test files
  • Supports async/await tests
  • Supports native ES Modules
  • Browser-Compatible
  • Familiar API

Install

$ npm install --save-dev uvu

Usage

Check out /examples for a list of working demos!

// tests/demo.js
import { test } from 'uvu';
import * as assert from 'uvu/assert';

test('Math.sqrt()', () => {
  assert.is(Math.sqrt(4), 2);
  assert.is(Math.sqrt(144), 12);
  assert.is(Math.sqrt(2), Math.SQRT2);
});

test('JSON', () => {
  const input = {
    foo: 'hello',
    bar: 'world'
  };

  const output = JSON.stringify(input);

  assert.snapshot(output, `{"foo":"hello","bar":"world"}`);
  assert.equal(JSON.parse(output), input, 'matches original');
});

test.run();

Then execute this test file:

# via `uvu` cli, for all `/tests/**` files
$ uvu -r esm tests

# via `node` directly, for file isolation
$ node -r esm tests/demo.js

Note: The -r esm is for legacy Node.js versions. Learn More

View the uvu CLI documentation

Assertions

The uvu/assert module is completely optional.

In fact, you may use any assertion library, including Node's native assert module! This works because uvu relies on thrown Errors to detect failures. Implicitly, this also means that any uncaught exceptions and/or unhandled Promise rejections will result in a failure, which is what you want!

API

Module: uvu

View uvu API documentation

The main entry from which you will import the test or suite methods.

Module: uvu/assert

View uvu/assert API documentation

A collection of assertion methods to use within your tests. Please note that:

  • these are browser compatible
  • these are completely optional

Benchmarks

via the /bench directory with Node v10.21.0

Below you'll find each test runner with two timing values:

  • the took ___ value is the total process execution time – from startup to termination
  • the parenthesis value ((___)) is the self-reported execution time, if known

Each test runner's stdout is printed to the console to verify all assertions pass.
Said output is excluded below for brevity.

~> "ava"   took   594ms  (  ???  )
~> "jest"  took   962ms  (356  ms)
~> "mocha" took   209ms  (  4  ms)
~> "tape"  took   122ms  (  ???  )
~> "uvu"   took    72ms  (  1.3ms)

License

MIT © Luke Edwards

uvu's People

Contributors

agilgur5 avatar ai avatar aldy505 avatar alexvipond avatar andrew0 avatar apfelbox avatar atk avatar bartveneman avatar bgotink avatar hyanmandian avatar lukeed avatar maraisr avatar marvinhagemeister avatar matej21 avatar nohea avatar omgimalexis avatar osdevisnot avatar rdmurphy avatar rictic avatar rschristian avatar ryanatkn avatar zigomir avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

uvu's Issues

Timeout control

With jest it's easy to control the timeout iejest.setTimeout(5000).
Any chance you could implement such a thing ?
Really enjoy uvu so far !

RFC: Suite Context

So I've been thinking about adding "context" or "state" to suites...

In any test runner, the motive behind before, after, before.each, and after.each hooks (and their equivalents) is to setup or tear down individual tests or entire suites. Of course, uvu allows this pattern, but I think we can make it even better.

When setting up or tearing down environment values, you often make the thing(s) you just set up accessible to your tests. For example, this may be a DB table record, a HTTP client, etc – it doesn't matter what the thing is, but with uvu – at least currently – you're forced to share/write into a scope-hoisted variable(s):

Before

const User = suite('User');

let client, user;

User.before(async () => {
  client = await DB.connect();
});

User.before.each(async () => {
  user = await client.insert('insert into users ... returning *');
});

User.after.each(async () => {
  await client.destroy(`delete from users where id = ${user.id}`);
  user = undefined;
});

User.after(async () => {
  client = await client.end();
});

User('should not have Teams initially', async () => {
  const teams = await client.select(`
    select id from users_teams 
    where user_id = ${user.id};
  `);

  assert.is(teams.length, 0);
});

// ...

User.run();

This is fine – and it obviously works; however, it can be messy once you have multiple suites in the same file, or if you've abstracted suite hooks and want to use them across multiple locations.

Instead, I'm thinking that hooks should affect a state or context value (name TBD) that any Suite hooks can affect/mutate. Then the final state value is passed into each of the Suite's tests.

This pattern alone will allow hooks to operate independently and clean up top-level variables. My only concerns are that:

  • it may be too easy to mutate state too freely, which may unintentionally affect later tests
  • it may be less obvious that your side effects need to be cleaned up

After

const User = suite('User');

User.before(async context => {
  context.client = await DB.connect();
});

User.before.each(async context => {
  context.user = await context.client.insert('insert into users ... returning *');
});

User.after.each(async context => {
  await context.client.destroy(`delete from users where id = ${user.id}`);
  context.user = undefined;
});

User.after(async context => {
  context.client = await context.client.end();
});

User('should not have Teams initially', async context => {
  const { client, user } = context;

  const teams = await client.select(`
    select id from users_teams 
    where user_id = ${user.id};
  `);

  assert.is(teams.length, 0);
});

// ...

User.run();

Again, we may want to reuse our DB.connect and DB.destroy helpers – so now we can do that:

import * as $ from './helpers';

const User = suite('User');

User.before($.DB.connect);
User.after($.DB.destroy);

// Still keep User-specific before.each/after.each hooks here

// ...

The last component of this is that suite() itself could accept an initial state/context value.
TypeScript users will also be able to declare the expected Context/State type information this way:

interface Context {
  client?: DB.Client;
}

interface UserContext extends Context {
  user?: IUser;
}

const User = suite<UserContext>('User', {
  client: undefined,
  user: undefined,
});

// ...

// The `context` would be typed
User.before.each(async context => {
  context.user = await context.client.insert('insert into users ... returning *');
});

// ...

// The `context` would also be typed
User('should not have Teams initially', async context => {
  const { client, user } = context;

  const teams = await client.select(`
    select id from users_teams 
    where user_id = ${user.id};
  `);

  assert.is(teams.length, 0);
});

I already have a local branch that fully supports these examples.
AKA, this is done & working. I'm just looking for feedback before committing it.


If you made it this far, thank you! 😅 🙌

Please let me know:

  1. Is this a good idea?
  2. Do we call this "state" or "context"?
  3. With regard to test modifications (accidentally) leaking into subsequent tests, how do we resolve that? Does it suffice to say "that's your fault" or is there something better that can be done?

Thanks 🙇

Add `uvu/spy` package

Hello @lukeed, I'm solving #9 issue, and when doing the tests I discover that your assert library doesn't have a way to test if some function was called. In other libraries like jest we can do it by creating some reference to a mock function (jest.fn()for example) and after that, check if this function was called. What do you think about this feature?

Pad line number values

Loop thru lines early & add it to initial prev argument to figure out if we need to pad() the early numbers with leading zeros.

Without it, larger diffs are printed with off-by-1 alignment issues for some/most of the file:

Screen Shot 2020-05-20 at 12 21 07 PM

Add multi-thread support

Should be behind a CLI flag & should also be an opt-in – not everything is better/faster just because it's spread across more processes.

Having something simple like uvu --parallel is a nice, quick way to determine is it's a good fit for your project.
Similarly, --parallel should optionally accept a number of processes to fork into. This will also be limited by the number of machine cores. Omitting a number defaults to the host's core count (as seen by os.cpus().length).

This will be reserved for a major-version release – whether that's 1.0 or 2.0.
Definitely on the agenda, but it's a nice-to-have for 98% of projects. There are other, more pressing must-have's that much come first.

TypeError: Cannot read property 'push' of undefined

In 0.5.0, there appears to be an issue with how the test queue gets set up, at least when using the uvu -r esm setup with modules.

Full console error:

TypeError: Cannot read property 'push' of undefined
    at Function.test.run (<pathToCWD>/node_modules/uvu/dist/index.js:107:36)
    at Object.<anonymous> (<pathToCWD>/tests/test.js:9:7)
    at Generator.next (<anonymous>)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1112:10)

Reproduction:
https://github.com/AlexVipond/undefined-queue

Just clone the repo, npm i, and uvu -r esm to produce the error.

I'm on Node 15.1.0, and downgrading to [email protected] fixes the problem

Test Results as JSON

Currently there doesn't seem to be a way to get the test result data other then parsing the cli output which is missing some information. Would be great if there either was a way to set a reporter or get an output that is parsable like tap.

The reason this would be useful is to be able to send reports to other tools

Specify a glob pattern

Is there any way to specify a glob instead of a folder that only files ending in spec or test are considered?

uvu's GitHub Action not actually testing different OS

Hello! 👋

I just noticed the os field is present in the matrix for the action but it's not actually being used to set runs-on — it looks like everything is still running on ubuntu-latest.

runs-on: ubuntu-latest
timeout-minutes: 3
strategy:
matrix:
nodejs: [8, 10, 12, 14]
os: [ubuntu-latest, windows-latest, macOS-latest]

(Only noticed this because I'm tweaking an action of mine that uses uvu and was trying to borrow from uvu's action. 🙃 )

Diff of equal objects with different constructor is misleading

equal doesn't treat two objects as equal if their constructor is different, but the diff doesn't take it into account. This can be rather confusing.

Example test

import {test} from 'uvu';
import {equal} from 'uvu/assert';

test('it diffs two objects', () => {
  const blankObject = Object.create(null);
  blankObject.foo = 'bar';

  equal(blankObject, {
    foo: 'bar'
  });
});

Actual result

   FAIL  "it diffs two objects"
    Expected values to be deeply equal:  (equal)

        ··{
        ····"foo":·"bar"
        ··}

Expected result

Something that explained why the values are not considered deeply equal, even though the diff appears to show them being equal.

I'm not sure what would be a good way to show that in a diff like this, since the constructor isn't normally printed. Node does print the name of certain constructors before the value itself, so something like this might be an option:

   FAIL  "it diffs two objects"
    Expected values to be deeply equal:  (equal)

        Actual:
        --··null {
        Expected:
        ++··Object {
        ····"foo":·"bar"
        ··}

ts-node ESM support

Hola,

thanks for the amazing(est!) test runner.

I just moved one of my projects to a TS setup which requires me to use ES modules. ts-node has some preliminary support for that: TypeStrong/ts-node#1007
Unfortunately that doesn't work with the --require flag. I'm not quite sure yet what is needed to make it completely work yet. Maybe just work for ts-node to have a runtime solution that doesn't require calling node --loader ts-node/esm?
Just wanted to start the conversation, as there doesn't seem to be one around this yet.

✌️

Add `failing` tests feature

Ava has failing tests feature:

test.failing('demonstrate some bug', t => {
  t.fail(); // Test will count as passed
});

It behaves like normal test, just with opposite result — failed tests considered passed, i.e. they are expected to be failed.

It is useful when there is known issue, and I plan to fix it later — I can write test for that issue, and expect this test to fail just yet, until I fix issue, and mark test as usual passing test then.

Maybe mark dots for such tests with different color in output.

Don't warn in recursive context settings `toProxy`

Currently Im putting a playwright Browser and Page instances onto the context in a .before into a context:

myTest.before(async (context) => {
        context.browser = await chromium.launch({
		headless: false,
	});
	const browsingContext = await context.browser.newContext({
		bypassCSP: true,
	});
	context.page = await browsingContext.newPage();
});

and then later reading that like:

myTest('open's website', async (context) => {
	await context.page.goto(context.baseUrl); // Note this comes statically when I created the `suite`.
	assert.ok(/test for something/.test((await context.page.content())));
});

but this seems to mutate the page object in someway—probably Playwright internals. And for this my console is littered with:

[WARN] Cannot modify context within tests!

My plan is to still echo that these objects should be immutable but perhaps only on key? Or a config to say "i know what im doing", as I assume these need to stay immutable so tests could be ran in parallel in the future? (but on that, with e2e's you'd want them in-series).

Some node assert functions prevent the rest of a suite from running

This is strange, so maybe I'm doing something wrong. I've created a repo to demonstrate the issue: https://github.com/mwanji/uvu-node-assert-bug

I have a suite that uses node's built-in assert library. It gives the following result:

image

If I modify the third test to the following, only the first two tests are run (or, at least, reported to have run):

tests('Test 1', () => {
  assert.strictEqual('a', 'b');
});

image

So far, I've found that a failing assert.strictEqual or assert.deepStrictEqual, for example, will cause this situation. I experience the same issue when running the file with node ./index.js.

Node version: 12.18.3
OS: MacOS 10.15.6

Feature proposal: teardown function

One of the things I liked best in my days of C++ was RAII, i.e., automatic destruction of resources on scope exit. AVA has something that comes close to that, called t.teardown (https://github.com/avajs/ava/blob/master/docs/02-execution-context.md#tteardownfn). It allows to write utility functions that clearly show what resources are used in which test in the following way:

function renderComponent(t, component) {
  const instance = new component();
  t.teardown(() => instance.destroy());
  return instance;
}

test('my test', t => {
  const component = renderComponent(t, myComponent)
});

This has the benefit over the before.each function that we only take resources that we actually need in this particular test.

I would be willing to implement this, I would just like to get the OK from maintainers.

Don’t use Date to measure test duration

it looks like you fallback to Date if you’re not in Node https://github.com/lukeed/uvu/blob/master/src/index.js#L5

Date is subject to changes in “system time” and can potentially give you negative results, it’s not good to use for measuring. Instead use Performance.now(), it works in both Node and the browser.
You haven’t expressed what browsers or versions of node you’re willing to support for this project so it’s hard for me to say if it will be ideal but you’re better off using that. It’s monotonic, designed for measuring duration and cross platform.

Match a regex in uvu/assert

Is this the best way to match a regex now?

assert.ok(myRegex.test(output));

Would be nice to have:

assert.match(output, myRegex);

API for grouping tests, a la `describe`

Something I often do when using Mocha:

describe('my-library', () => {
  describe('method_one', () => {
    it('returns a string', () => {
     assert.equal(typeof my_library.method_one(), 'string');
    });

    // ...
  });

  describe('method_two', () => {
    it('returns a number', () => {
     assert.equal(typeof my_library.method_two(), 'number');
    });

    // ...
  });
});

This results in neatly indented output...

my-library
  method_one
    ✓ returns a string
    ✓ ...
  method_two
    ✓ returns a number
    ✓ ...

...and makes it easier to identify (and isolate/skip) problematic groups of tests.

It'd be nice to have something equivalent in uvu — perhaps something like this?

test.group('my-library', () => {
  test.group('method_one', () => {
    test('returns a string', () => {
     assert.equal(typeof my_library.method_one(), 'string');
    });

    // ...
  });

  test.group('method_two', () => {
    test('returns a number', () => {
     assert.equal(typeof my_library.method_two(), 'number');
    });

    // ...
  });
});

Plus test.group.only etc. Thoughts?

Finally block silents errors causing false-positive 0 exit code

the finally block in runner function silents every error which is thrown outside the inner try block.

Example:

import { test } from 'uvu'
test.before(() => {
    throw Error()
})
test('foo', () => {

})
test.run()

although the console output correctly shows that 0 tests passed, the process exits with false-positive exit code 0 and prints no error

besides hooks, also internal errors may cause this, e.g. a function for error formatting fails, when a string is passed as an error (throw 'error string')

Bug in array comparison with undefined elements

Reproduction:

import * as assert from 'uvu/assert'
assert.equal([ `foo` ], [ undefined ])

Cause:

val = JSON.stringify(tmp.value[j], null, 2).split(/\r?\n/g);

JSON.stringify(undefined) returns undefined, which causes the .split(/\r?\n/g) to fail with:

Cannot read property 'split' of undefined (undefined)

Circular JSON w/ `print` utility

The print utility is run immediately as part of the assertion setup.

Seen with assert.type and assert.instance (but has to do with print specifically).

Native ESM Support

I have this 98% completed in local branch.

Allows you to run uvu with native ESM purely, making my current usage of -r esm completely optional.
This also has to maintain functionality within browsers, which will come for free.

Generate snapshots?

I couldn't tell from the docs if it's possible to generate a snapshot through the CLI? ie. something similar to Jest's approach. Otherwise, I think manually getting the stringified output to compare against is "fine" but not the nicest DX, and it will make it hard to switch over to using uvu without that functionality.

Great work though with this tool!

Should `suite.run()` return a promise for the test results?

So I am bundling my test suite using rollup to run it in the browser and since v0.3.1 that works lik a treat.

However, I don’t know how to read back the test results (which tests passed, which tests failed etc). I’m trying to read all of that back via pptr. It would make sense (to me, at least) that test.run() returns a promise for some sort of result data structure.

ESM – TypeError [ERR_UNKNOWN_FILE_EXTENSION]

I get this error when trying the typescript example with updated dependencies:

TypeError [ERR_UNKNOWN_FILE_EXTENSION]:
    Unknown file extension ".ts" for /home/tolu/github/uvu/examples/typescript/tests/math.ts

An image for context 😄

image

Single tests files can be run via:

node --loader ts-node/esm test/math.ts

Proposal: Add example for Uvu + Puppeteer

Today I got a really fun setup working: Uvu (0.5.0 using native ES module support) for writing and running tests and assertions, and Puppeteer for evaluating code in the browser during a test.

MySuite('can fetch data!', async ({ page }) => {
  const fetchedData = await page.evaluate(async () => {
    const result = await fetch('https://httpbin.org/get')
    return await result.json()
  })

  assert.ok(fetchedData)
})

I'm enjoying how minimalist it is—I can bundle my code however I want and build my app however I want. When it's time to test, I just need to spin up the app's development server, then I'm free to use Uvu and Puppeteer to visit pages and run test code.

@lukeed I can pull request an example setup if that's fine by you?

There's more than one way to make this work, but before and after hooks probably are best for most cases:

import puppeteer from 'puppeteer-core'

MySuite.before(async context => {
  const browser = await puppeteer.launch(),
        page = await browser.newPage()

  context.browser = browser
  context.page = page
})

MySuite.after(async ({ browser }) => {
  await browser.close()
})

Add `beforeEach` & `afterEach` hooks

Currently, suite.before and suite.after are tied to the suite's lifecycle.
This would be added to run before/after each test block within the suite.

test.before(() => {
  console.log('SETUP');
});

test.after(() => {
  console.log('CLEANUP');
});

test.beforeEach(() => {
  console.log('>> BEFORE');
});

test.afterEach(() => {
  console.log('>> AFTER');
});

// ---

test('foo', () => {
  console.log('>>>> TEST: FOO');
});

test('bar', () => {
  console.log('>>>> TEST: BAR');
});

test.run();

// SETUP
// >> BEFORE
// >>>> TEST: FOO
// >> AFTER
// >> BEFORE
// >>>> TEST: BAR
// >> AFTER
// CLEANUP

Add '--findRelatedTests' to cli

Hello @lukeed,

I love uvu but I think it is missing one of the biggest features, the ability to run tests on a pre-commit hook.

Jest does that with the --findRelatedTests <spaceSeparatedListOfSourceFiles> cli option (here is the doc link)

I'm not sure if this will be an easy thing to implement but sure it will be usefull!

Typescript example: Can't use ES modules imports with Node.js AND uvu

Thanks for the tool @lukeed!

I'm having an issue with the Typescript example:

I'm trying to use ES modules directly, with the latest version of Node.js, but I can't make test modules to work at the same time, when using imports between source modules.

I added the following (which I think it's a pretty common use case), to the typescript example you provided:

  • Added "type": "module" to package.json file, so I can use ES modules with Node.js
  • Added src/main.ts file with the following content:
import { sum } from './math'

export function run() {
    console.log(sum(2, 3))
}

run()
  • Added tests/main.ts file with the following content:
import { test } from 'uvu';
import * as assert from 'uvu/assert';
import * as main from '../src/main';

test('run', () => {
    assert.type(main.run, 'function');
});
  • Build and test:
yarn build && yarn test

Tests work! But when I try to run emmited files with Node.js, got the following error:

node build/main.js
internal/modules/run_main.js:54
    internalBinding('errors').triggerUncaughtException(
                              ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/home/cristian/projects/uvu-typescript-example/build/math' imported from /home/cristian/projects/uvu-typescript-example/build/main.js

This is because ES modules imports need explicit file extension. So I fix the issue adding imports file extensions to src/main.ts (which is supported by Typescript)

import { sum } from './math.js'
...

Now building and running main file works:

yarn build && node build/main.js
yarn run v1.22.4
$ tsc
Done in 2.44s.
5

but tests don't :( (got the following error):

yarn test
yarn run v1.22.4
$ uvu -r ts-node/register tests
(node:28693) UnhandledPromiseRejectionWarning: Error: Cannot find module './math.js'

Tried different tsconfig.json configurations, but can't make the emmited files and test files to work at the same time.

Improve complex Array diffs

Come back to this --> have diff.js locally with few different approaches. Decide on large-scale changes. Keep whitespace character normalization

`uvu` CLI exits with a 0 exit code when test files contain invalid JS

Encountered with [email protected] on [email protected].

If a .mjs test file contains code that would fail at parse-time when imported/run by node, such as:

import './nonexistent-file.mjs'

or

this is invalid syntax

and is executed with the uvu cli:

npx uvu . repro-file.mjs

execution fails, which is expected:

(node:66475) UnhandledPromiseRejectionWarning: Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/private/tmp/wat/nonexistent-file.mjs' imported from /private/tmp/wat/repro.mjs
    at finalizeResolution (internal/modules/esm/resolve.js:275:11)
    at moduleResolve (internal/modules/esm/resolve.js:719:10)
    at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:809:11)
    at Loader.resolve (internal/modules/esm/loader.js:85:40)
    at Loader.getModuleJob (internal/modules/esm/loader.js:229:28)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:51:40)
    at link (internal/modules/esm/module_job.js:50:36)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:66475) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:66475) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

but the process exits with status code 0, which is not expected.

If the run promise is rejected, uvu should exit with a non-zero status code.

Context proxying doesn't work with Date

Not sure the reason, stepped through the code briefly. Something like this doesn't work:

test('whatever', context => {
  let { date } = context;

  date.getTime(); // throws.
});

I think getTime() doesn't like it when the receiver is a proxy.

Assertion error when comparing non-string vs string values in uvu/assert

Hello 👋!

I think I found an issue in uvu/assert. Let me know how I can help!

Summary

When using the assert.equal method for testing that an arbitrary value equals a string, an unexpected error happens:

Cannot read property 'split' of <value>

Reproduction

Module version: [email protected]:

import { test } from 'uvu';
import * as assert from 'uvu/assert';

test('failing test', function () {
  const myValue = null;
  assert.equal(myValue, 'mahstring');
});

test.run();

Produces this error:

Cannot read property 'split' of null

  at Diff.tokenize ([CWD]/node_modules/diff/lib/diff/base.js:234:18)
  at Diff.diff ([CWD]/node_modules/diff/lib/diff/base.js:45:39)
  at Object.diffChars ([CWD]/node_modules/diff/lib/diff/character.js:35:24)
  at chars ([CWD]/node_modules/uvu/diff/index.js:79:17)
  at compare ([CWD]/node_modules/uvu/diff/index.js:202:10)

  at assert ([CWD]/node_modules/uvu/assert/index.js:30:28)
  at Object.equal ([CWD]/node_modules/uvu/assert/index.js:43:2)

  at Object.handler ([CWD]/test/index.js:22:10)

  at Number.runner ([CWD]/node_modules/uvu/dist/index.js:70:16)
  at exec ([CWD]/node_modules/uvu/dist/index.js:124:39)

Potential Solution

It seems to be happening when the diff library attempts to tokenize a non-string value.

I believe that the uvu code that triggers this diff.diffChars() (and therefore the tokenizer) on a non-string is:

uvu/src/diff.js

Lines 201 to 203 in 94e541c

if (typeof expect == 'string') {
return chars(input, expect);
}

This modification – additional condition is added – seems to fix the issue.

-  if (typeof expect == 'string') {
+  if (typeof expect == 'string' && typeof input == 'string') {
 	return chars(input, expect);
  }

But I am not sure of the implications of this change.


I hope this helps. Thanks for this awesome project 👋

svelte tests (prop change)

I was able to implement tests using the example in the svelte folder. However, I am struggling with one scenario.

A component with property that can be changed from a parent component. The tests I wanted to do was checking that when the property value is updated, the rendered object changes. I think the svelte marks the property as dirty and the fragment is rerendered.

Any suggestions on how to achieve this using uvu. What should a helper function to modify props and rerender the component look like?

"Migration from Jest" section in the docs / readme

Hi, I want to try to migrate some of my projects to uvu - would be cool to have some kind a of a docs page describing the process of migrating from Jest (the most popular testing lib) to uvu.

e.g. what I should install, how I do same-style coverage, syntax replacements - etc

I can ofc just go thru examples and migrate myself but I can miss something

so would be cool to have it :D

-r esm not working with uvu CLI

Playing around with uvu tonight, I have a command that works with node, but doesn't work with the uvu CLI:

  • Works: node -r esm -r ../app-scripts-svelte/test/register.js ./src/App.test.js
  • Doesn't work: yarn run uvu -r esm -r ../app-scripts-svelte/test/register.js src
  • Doesn't work: ../../node_modules/.bin/uvu -r esm -r ../app-scripts-svelte/test/register.js src (run in a monorepo, if that matters)

Error:

... app-template-svelte/src/App.test.js:1
(function (exports, require, module, __filename, __dirname) { import { test } from 'uvu';
                                                              ^^^^^^

SyntaxError: Cannot use import statement outside a module

Can confirm that putting random string in place of esm (-r eawegiawingeawniegain) causes a different error, so esm seems to be running but having no effect.

This is on the latest version from npm

Based loosly on https://github.com/lukeed/uvu/tree/master/examples/svelte

--grep

I find this flag in mocha to be incredibly useful:

npm test -- -g "some test description"

What do you think about having something similar in uvu?

`assert.throws()` with async argument

Hi 👋,

Is assert.throws() currently supposed to work with async functions?

For example, this fails:

assert.throws(async () => {
    await asyncFnThatThrows();
});

While this passes:

assert.throws(() => {
    syncFnThatThrows();
});

What is the recommended way to test that an async function throws?

Thought of something like this, but there's no .pass() or .fail():

try {
   await asyncFnThatThrows();
   test.fail('did not throw');
} catch (err) {
   test.pass();
}

Edit: currently using this hack:

async function throwsAsync(
    asyncFn,
    failMessage = 'did not throw',
    passMesage = 'did throw',
) {
    try {
        await asyncFn();
        assert.equal(false, true, failMessage);
    } catch (err) {
        assert.equal(true, true, passMesage);
    }
}

Add support for focused tests

When developing code I tend to focus on single tests one by one. As an avid console.log debugger type of person I quickly get overwhelmed when logging statements from unrelated test cases litter stdout. For that reason I wonder if it may be feasible to add something like that to uvu.

Example from Mocha/Jest:

// Whole suites or single tests can be focused
describe.only("suite", () => {
  it.only("single test", () => {
    // ...
  });
});

Example from Jasmine:

// Whole suits or single tests can be focused
fdescribe("suite", () => {
  fit("single test", () => {
    // ...
  });
});

Move dot-progress to flag?

When you have suites with lots of tests, the dots can wrap around and make for odd/unpredictable layouts.

Idea is to hide the current PASS and FAIL icons ( and ) to --progress flag only.
This would disable them by default.

Although, I think running a test file on its own would show progress by default since that workflow is tuned for debugging.

//cc @pngwn

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.