Giter Club home page Giter Club logo

jest-fp-ts's Introduction

Jest Matchers for the fp-ts ecosystem

Build

Jest matchers for projects using fp-ts and io-ts.

Problem

If your TypeScript project is written in a functional programming style using fp-ts and io-ts, many of the values you'll want to check in your unit tests will come wrapped inside container types like Either, Option, or These. Jest has no awareness of these container types and no built-in matchers to help you to compare wrapped values against un-wrapped values. This leaves you with two options:

  1. Extract the received value from the container type before using a jest matcher.
  2. Lift the expected value into a container of the expected type before using a jest matcher.

Both options work, but tend to make your tests somewhat verbose, adding unnecessary work when writing your tests, and making it harder to read and maintain them.

Solution

@relmify/jest-fp-ts adds additional matchers to Jest's default ones, making it easier to test code that makes use of fp-ts functional containers.

Installation

With npm:

npm install -D @relmify/jest-fp-ts

With yarn:

yarn add -D @relmify/jest-fp-ts

You also need both fp-ts and io-ts installed in your project. If you're here, presumably you're already using fp-ts. Not every fp-ts project uses io-ts though. If you aren't using io-ts in your project, simply install it as a development dependency.

With npm:

npm install -D io-ts

With yarn:

yarn add -D io-ts

Setup

To make all @relmify/jest-fp-ts matchers globally available in your test files, add @relmify/jest-fp-ts to your Jest setupFilesAfterEnv configuration.

See jest documentation for additional help.

Setup with package.json

In your package.json file add:

"jest": {
  "setupFilesAfterEnv": ["@relmify/jest-fp-ts"]
}

Setup with jest.config.js

// jest.config.js
module.exports = {
  setupFilesAfterEnv: ['@relmify/jest-fp-ts'],
};

Setup with vite.config.ts (for vitest)

// vite.config.ts
export default defineConfig({
  test: {
    // ...
    setupFiles: ['@relmify/jest-fp-ts'],
    // ...
  },
});

Typescript Editor Support

If your editor does not recognize the custom @relmify/jest-fp-ts matchers, add a global.d.ts file to your project with:

import '@relmify/jest-fp-ts';

If you've added a global.d.ts file and your editor still has problems recognizing these matchers, you may need to specifically include the global.d.ts file in your Typescript configuration using the "include" or "files" property. For example, in tsconfig.json:

{
  "compilerOptions": {
    "module": "commonjs",
    "strict": true,
    ...
  },
  "include": ["**/*", "global.d.ts"],
  "exclude": ["node_modules", "**/__tests__/*"]
}

Alternatively, you can resolve this issue by adding import '@relmify/jest-fp-ts'; to each test file that makes use of @relmify/jest-fp-ts matchers.


Matchers

Either Matchers

.toBeEither()

Use .toBeEither() to check if a value is consistent with an Either. In other words, this matcher confirms that the value is a Left or a Right.

Note that a Left or a Right value is also consistent with a These and would also pass a .toBeThese() test.

Either or These Matchers

The matchers below can be used for Left and Right values from an Either or a These.

.toBeLeft()

Use .toBeLeft() to check if a value is a Left.

.toBeLeftErrorMatching(string | RegExp)

Use .toBeLeftErrorMatching(string | RegExp) to check if a value is a Left whose value is an instance of Error with a message property that contains the supplied string or matches the supplied RegExp.

.toBeRight()

Use .toBeRight() to check if a value is a Right.

.toEqualLeft(value)

Use .toEqualLeft(value) to check if a value is a Left whose value equals an expected value. See Jest's toEqual(value) documentation for information about how the .toEqual() comparison works.

.toEqualRight(value)

Use .toEqualRight(value) to check if a value is a Right whose value equals an expected value. See Jest's toEqual(value) documentation for information about how the .toEqual() comparison works.

.toStrictEqualLeft(value)

Use .toStrictEqualLeft(value) to check if a value is a Left that contains a value that strictly equals an expected value. See Jest's toStrictEqual(value) documentation for information about how .toStrictEqual() differs from toEqual().

.toStrictEqualRight(value)

Use .toStrictEqualRight(value) to check if a value is a Right that contains a value that strictly equals an expected value. See Jest's toStrictEqual(value) documentation for information about how .toStrictEqual() differs from toEqual().

.toSubsetEqualLeft(value)

Use .toSubsetEqualLeft(value) to check if a value is a Left whose value equals or subset matches the expected value. A subset match passes when the received value is a Left whose value is an object with a subset of properties that match the expected object. The received value must contain all of the expected properties, and may contain more than the expected properties.

You can also pass an array of values to match against a received Left value that is an array of values. In this case, each value in the expected array is compared against the corresponding value in the array contained in the received Left. Both arrays must be the same length or the match will fail.

Note that an empty expected object will match against any received Left whose value is an object.

.toSubsetEqualRight(value)

Use .toSubsetEqualRight(value) to check if a value is a Right whose value equals or subset matches the expected value. A subset match passes when the received value is a Right whose value is an object with a subset of properties that match the expected object. The received value must contain all of the expected properties, and may contain more than the expected properties.

You can also pass an array of values to match against a received Right value that is an array of values. In this case, each value in the expected array is compared against the corresponding value in the array contained in the received Right. Both arrays must be the same length or the match will fail.

Note that an empty expected object will match against any received Right whose value is an object.

These Matchers

.toBeBoth()

Use .toBeBoth() to check if a value is a Both.

.toBeThese()

Use .toBeThese() to check if a value is consistent with a These. In other words, this matcher confirms that the value is a Left, a Right, or a Both.

Note that a Left or a Right value is also consistent with an Either and would also pass a .toBeEither() test.

.toEqualBoth(leftValue, rightValue)

Use .toEqualBoth(leftValue, rightValue) to check if a value is a Both that contains a left value that equals an expected value, and a right value that equals an expected value. See Jest's toEqual(value) documentationfor information about how the .toEqual() comparison works.

.toStrictEqualBoth(leftValue, rightValue)

Use .toStrictEqualBoth(leftValue, rightValue) to check if a value is a Both that contains a left value that strictly equals an expected value, and a right value that strictly equals an expected value. See Jest's toStrictEqual(value) documentation for information about how .toStrictEqual() differs from toEqual().

.toSubsetEqualBoth(leftValue, rightValue)

Use .toSubsetEqualBoth(leftValue, rightValue) to check if a value is a Both whose left and right values equal or subset match the expected leftValue and rightValue. A subset match passes when a received value is an object with a subset of properties that match the expected object. The received value must contain all of the expected properties, and may contain more than the expected properties.

You can also pass arrays of values to match against received values that contain arrays of values. In this case, each value in the expected array is compared against the corresponding value in the array contained in the received. Both arrays must be the same length or the match will fail.

Note that an empty expected object will match against any received object.

Option Matchers

.toBeNone()

Use .toBeNone() to check if a value is a None.

.toBeOption()

Use .toBeOption() to check if a value is an Option (either a Some or a None).

.toBeSome()

Use .toBeSome() to check if a value is a Some.

.toEqualSome(value)

Use .toEqualSome(value) to check if a value is a Some that contains a value that equals an expected value. See Jest's toEqual(value) documentationfor information about how the .toEqual() comparison works.

.toStrictEqualSome(value)

Use .toStrictEqualSome(value) to check if a value is a Some that contains a value that strictly equals an expected value. See Jest's toStrictEqual(value) documentation for information about how .toStrictEqual() differs from toEqual().

.toSubsetEqualSome(value)

Use .toSubsetEqualSome(value) to check if a value is a Some that contains an object with a subset of properties that match the expected object properties. The received value must contain all of the expected properties, and may contain more than the expected properties.

Decode Matchers

.toBeLeftWithErrorsMatching(Array<string | RegExp>)

Use .toBeLeftWithErrorsMatching(Array<string | RegExp>) when testing validation errors returned by io-ts decode() operations.

Note that a ValidationError is NOT a standard javascript Error object. See .toBeLeftErrorMatching(string | RegExp) for a matcher that works with standard Error objects.

An io-ts decode() method will return a Left with an array of ValidationError objects if the supplied value can not be successfully validated and decoded to the specified io-ts type. For codecs that are composed from multiple codecs, multiple errors may be returned as each sub-codec is applied to the values it is charged with validating.

This matcher provides an easy way to check if expected validation errors are present. To do this, it makes use of the io-ts PathReporter module.

To use this matcher, supply an array of strings that you expect to be present in the array of strings returned by PathReporter.report(). You can supply either regular expressions or substrings. The matcher will try to match each array entry against the array of Pathreporter.report() strings.

If the supplied object is not a Left that contains an array of ValidationError objects, or if any of the strings you supply cannot be matched to one of the ValidationError objects, the matcher will return false. If all of the strings you supply are matched, it will return true.

Example:

const Name = t.type({
  first: t.string,
  last: t.string,
});
type Name = t.TypeOf<typeof Name>;
const numberName = { first: 404, last: 401 };
test('if the received is a Left that contains errors matching the expected values', () => {
  expect(Name.decode(numberName)).toBeLeftWithErrorsMatching([/404/, '401']);
});

Note:

This matcher supports the current (stable) io-ts interface. There is a new experimental io-ts decoder interface that returns Either<DecodeError, A> results instead. This matcher does not support that interface.

Asymmetric Matchers

All of the provided matchers are asymmetric matchers, which means that they can be called from any other matcher that accepts asymmetric matchers like so:

test('works if called as an asymmetric matcher', () => {
  expect(left('Any sufficiently advanced technology is equivalent to magic.')).toEqual(
    expect.toEqualLeft('Any sufficiently advanced technology is equivalent to magic.'),
  );
});

The provided toEqual*(value), toStrictEqual*(value) and toSubsetEqual*(value)matchers also accept asymmetric matchers which means you can pass in any of the standard Jest asymmetric matchers, or any of the jest-extended matchers. This can be especially handy when you don't want to check against a literal value.

test('works if called with an asymmetric matcher', () => {
  expect(both(['error 1', 'error 2'], { first: 'Albert', last: 'Einstein' })).toEqualBoth(
    expect.anything(),
    { first: expect.any(String), last: expect.any(String) },
  );
});

The .toBeLeftWithErrorsMatching(Array<string | RegExp>) matcher does not accept asymmetric matchers. You can use standard jest matchers to achieve similar results like so:

import * as t from 'io-ts';
import { PathReporter } from 'io-ts/lib/PathReporter';
import { toBeLeftWithErrorsMatching } from '@relmify/jest-fp-ts';

expect.extend({ toBeLeftWithErrorsMatching });

const Name = t.type({
  first: t.string,
  last: t.string,
});
type Name = t.TypeOf<typeof Name>;

const receivedName = { first: 1, last: undefined };
const validation = Name.decode(receivedName);
const errorStrings = PathReporter.report(validation);

// Snapshots below use `@relmify/jest-serializer-strip-ansi` and `jest-snapshot-serializer-raw` to produce
// more readable snapshot output.
describe('Alternative ways to test validation errors', () => {
  test('Standard asymmetric matchers can be used to test for strings within pathReporter output', () => {
    expect(errorStrings).toEqual(
      expect.arrayContaining([expect.stringMatching('1'), expect.stringMatching(/undefined/)]),
    );
  });
  test('Standard snapshot tests can be used to test full pathReporter output', () => {
    expect(errorStrings).toMatchInlineSnapshot(`
      [
        Invalid value 1 supplied to : { first: string, last: string }/first: string,
        Invalid value undefined supplied to : { first: string, last: string }/last: string,
      ]
    `);
  });
  test('Standard snapshot tests can be used to test the raw array of validation errors (verbose!)', () => {
    expect(validation).toMatchInlineSnapshot(`
      {
        _tag: Left,
        left: [
          {
            context: [
              {
                actual: {
                  first: 1,
                  last: undefined,
                },
                key: ,
                type: InterfaceType {
                  _tag: InterfaceType,
                  decode: [Function],
                  encode: [Function],
                  is: [Function],
                  name: { first: string, last: string },
                  props: {
                    first: StringType {
                      _tag: StringType,
                      decode: [Function],
                      encode: [Function],
                      is: [Function],
                      name: string,
                      validate: [Function],
                    },
                    last: StringType {
                      _tag: StringType,
                      decode: [Function],
                      encode: [Function],
                      is: [Function],
                      name: string,
                      validate: [Function],
                    },
                  },
                  validate: [Function],
                },
              },
              {
                actual: 1,
                key: first,
                type: StringType {
                  _tag: StringType,
                  decode: [Function],
                  encode: [Function],
                  is: [Function],
                  name: string,
                  validate: [Function],
                },
              },
            ],
            message: undefined,
            value: 1,
          },
          {
            context: [
              {
                actual: {
                  first: 1,
                  last: undefined,
                },
                key: ,
                type: InterfaceType {
                  _tag: InterfaceType,
                  decode: [Function],
                  encode: [Function],
                  is: [Function],
                  name: { first: string, last: string },
                  props: {
                    first: StringType {
                      _tag: StringType,
                      decode: [Function],
                      encode: [Function],
                      is: [Function],
                      name: string,
                      validate: [Function],
                    },
                    last: StringType {
                      _tag: StringType,
                      decode: [Function],
                      encode: [Function],
                      is: [Function],
                      name: string,
                      validate: [Function],
                    },
                  },
                  validate: [Function],
                },
              },
              {
                actual: undefined,
                key: last,
                type: StringType {
                  _tag: StringType,
                  decode: [Function],
                  encode: [Function],
                  is: [Function],
                  name: string,
                  validate: [Function],
                },
              },
            ],
            message: undefined,
            value: undefined,
          },
        ],
      }
    `);
  });
});

LICENSE

MIT

Contributing

If you've come here to help contribute - Thanks! Take a look at CONTRIBUTING to see how to get started.

jest-fp-ts's People

Contributors

leilapearson avatar dearlordylord avatar

Stargazers

Vicente Manriquez  avatar TANIGUCHI Takaki avatar Andrejs Agejevs avatar Askar Yusupov avatar Jan Schulte avatar Frédéric Vilcot avatar Saúl Ernesto avatar Nathan Argetsinger avatar Martin avatar Vassiliy Kuzenkov avatar Victor Korzunin avatar Andrey Konopkov avatar Boyd Dames avatar holypanda avatar Leechael avatar Tori Hedden avatar Yaroslav Kukytsyak avatar Yusuke Ohta avatar Adam Recvlohe avatar Dan Minshew avatar Jamie Mason avatar Enrico Polanski avatar Mike Yim avatar John Gosset avatar Ethan Kent avatar Darren avatar Rich avatar Stasiv  Bogdan avatar JP Shilton avatar dudu1 avatar Alex avatar Patryk Dwórznik avatar Isabella Martinez avatar Federico Moretti avatar William Calderipe avatar  avatar Wouter Hager avatar Deepanshu Dhruw avatar Woodson Delhia avatar Tim Wardle avatar Evgeniy Talko avatar Gianluca Carucci avatar Andreas Krut avatar Oliver Joseph Ash avatar Malte Legenhausen avatar Wayne Van Son avatar Artem Golovin avatar Vincent Schramer avatar Attila Beregszaszi avatar Vitor Leal avatar Alexandre Balhier avatar andrew jarrett avatar Andreas Kollegger avatar David Lonyai avatar Mateusz Kocz avatar Janusz Dziurzyński avatar JmQu avatar Senthil Ramalingam avatar Stefano Regosa deel avatar Webber Wang avatar Jesse Kelly avatar Tobi Binna avatar Artem Aginskiy avatar Doug DiFilippo avatar Wang Guan avatar

Watchers

James Cloos avatar  avatar

jest-fp-ts's Issues

Monoid and Semigroup for project settings

Is your feature request related to a problem? Please describe.
Extend beyond matchers with jest related monoids and semigroups!

Describe the solution you'd like

Add Monoid and Semigroup instances for @jest/types#Config#*

Describe alternatives you've considered
This lib has some traction, so I think this repo is the best place to put something like this.

Additional context

I use a substantial amounts of JS in my jest config. I like being able to use fp-ts to help create configuration. It's currently more painful than it should be. I used config#projects in the more complex repos.

Appendix

Semigroup for Config.InitialProjectConfig:

function partial<T extends Record<string, unknown>>(struct: {
  [P in keyof Required<T>]: S.Semigroup<Required<T>[P]>;
}): S.Semigroup<Partial<T>> {
  return {
    concat: (x, y) =>
      pipe(
        Object.keys(struct) as ReadonlyArray<keyof T>,
        A.reduce({} as Partial<T>, (b, key) =>
          pipe(
            [x[key], y[key]],
            A.map(O.fromNullable),
            S.concatAll(O.getMonoid(struct[key]))(O.none),
            O.map((value) => ({ ...b, [key]: value })),
            O.getOrElseW(() => b)
          )
        )
      ),
  };
}

type Ommiited =
  | "globals"
  | "haste"
  | "moduleNameMapper"
  | "testEnvironmentOptions"
  | "testRegex"
  | "timers"
  | "transform";

const ss: S.Semigroup<Omit<Config.InitialOptions, Ommiited>> = partial<
  Required<Omit<Config.InitialProjectOptions, Ommiited>>
>({
  automock: Boolean.MonoidAny,
  cache: Boolean.MonoidAny,
  cacheDirectory: S.first(),
  clearMocks: Boolean.MonoidAny,
  coveragePathIgnorePatterns: MA.getSemigroup(),
  cwd: S.first(),
  dependencyExtractor: S.first(),
  detectLeaks: Boolean.MonoidAny,
  detectOpenHandles: Boolean.MonoidAny,
  displayName: S.first(),
  errorOnDeprecated: Boolean.MonoidAny,
  extensionsToTreatAsEsm: MA.getSemigroup(),
  extraGlobals: MA.getSemigroup(),
  filter: S.first(),
  forceCoverageMatch: MA.getSemigroup(),
  globalSetup: S.first(),
  globalTeardown: S.first(),
  injectGlobals: Boolean.MonoidAny,
  moduleDirectories: MA.getSemigroup(),
  moduleFileExtensions: MA.getSemigroup(),
  moduleLoader: S.first(),
  modulePathIgnorePatterns: MA.getSemigroup(),
  modulePaths: MA.getSemigroup(),
  name: S.first(),
  prettierPath: S.first(),
  resetMocks: Boolean.MonoidAny,
  resetModules: Boolean.MonoidAny,
  resolver: S.first(),
  restoreMocks: Boolean.MonoidAny,
  rootDir: S.first(),
  roots: MA.getSemigroup(),
  runner: S.first(),
  setupFiles: MA.getSemigroup(),
  setupFilesAfterEnv: MA.getSemigroup(),
  skipFilter: Boolean.MonoidAny,
  skipNodeResolution: Boolean.MonoidAny,
  slowTestThreshold: S.first(),
  snapshotFormat: S.struct({}),
  snapshotResolver: S.first(),
  snapshotSerializers: MA.getSemigroup(),
  testEnvironment: S.last(),
  testLocationInResults: Boolean.MonoidAny,
  testMatch: MA.getSemigroup(),
  testPathIgnorePatterns: MA.getSemigroup(),
  testRunner: S.last(),
  testURL: S.last(),
  transformIgnorePatterns: S.last(),
  unmockedModulePathPatterns: MA.getSemigroup(),
  watchPathIgnorePatterns: MA.getSemigroup(),
});

Error when only using `fp-ts`, not `io-ts`

Hi! Thanks for creating this library, it is a lot more extensive than my fp-ts-jest-matchers, so I plan to phase that out and point people over to here.

I did run into one issue however: my project only uses fp-ts as a dependency, not io-ts. It appears however that this library requires io-ts to also be present, because I get this error:

Test suite failed to run

    Cannot find module 'io-ts' from 'isEither.js'

    However, Jest was able to find:
        './isEither.d.ts'
        './isEither.js'

    You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['web.js', 'js', 'web.ts', 'ts', 'web.tsx', 'tsx', 'json', 'web.jsx', 'jsx', 'node'].

    See https://jestjs.io/docs/en/configuration#modulefileextensions-array-string

    However, Jest was able to find:
        './toBeEither.d.ts'
        './toBeEither.js'

    You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['web.js', 'js', 'web.ts', 'ts', 'web.tsx', 'tsx', 'json', 'web.jsx', 'jsx', 'node'].

    See https://jestjs.io/docs/en/configuration#modulefileextensions-array-string

That's a lot of partially confusing output, but I think the important bit is Cannot find module 'io-ts' from 'isEither.js'.

Vitest Does Not Work Without Globals

Describe the issue

vitest by default operates without "globals". In terms of how it impacts this library, it means that simply calling:

expect.extend(...);

will fail because expect is not defined. Instead, you need to do this:

import { expect } from 'vitest';

expect.extend(...);

The instructions in this repo for vitest will always fail due to requiring expect to be a global, rather than something that must be imported directly.

To Reproduce

Setup a new project, add the latest vitest and this library, and try to run any test.

Expected behavior

There needs to be a proper way to add these matchers to vitest that will consistently work.

Suggested fix

The following code will properly configure vitest without any failure:

import decodeMatchers from '@relmify/jest-fp-ts/dist/decodeMatchers';
import eitherMatchers from '@relmify/jest-fp-ts/dist/eitherMatchers';
import optionMatchers from '@relmify/jest-fp-ts/dist/optionMatchers';
import theseMatchers from '@relmify/jest-fp-ts/dist/theseMatchers';
import eitherOrTheseMatchers from '@relmify/jest-fp-ts/dist/eitherOrTheseMatchers';
import { expect } from 'vitest';

expect.extend(decodeMatchers.matchers);
expect.extend(eitherMatchers.matchers);
expect.extend(optionMatchers.matchers);
expect.extend(theseMatchers.matchers);
expect.extend(eitherOrTheseMatchers.matchers);

Creating a file in this project with this code, and updating the readme to reference the new file, should work:

// vite.config.ts
export default defineConfig({
  test: {
    // ...
    setupFiles: ['@relmify/jest-fp-ts/dist/vitest.setup.ts'],
    // ...
  },
});

There are additional changes that can clean stuff up. For example, using package.json exports may be able to avoid having dist in the file path above. But this is all the core of the fix.

Additional context

I hope this information helps make it a quick fix.

Jest 28 Support

Describe the issue
Jest version 28 has been released and provides several improvements. Yet, because of the dependencies removed from jest, this library becomes incompatible with it.

To Reproduce
Simply upgrade your Jest to version 28.

Expected behavior
The library would be compatible with Jest 28.

Suggested fix
Removing unused dependencies by Jest 28.

Additional context
The error returned is similar to this:

Cannot find module 'expect/build/jasmineUtils' from '@relmify/jest-fp-ts/dist/util/index.js

Installation instructions do not work (simple repository included)

I've created a repository attempting to use this package here, following your instructions to a T:
https://github.com/JVMartin/jest-fp-ts-broken

Note I've included the package:
https://github.com/JVMartin/jest-fp-ts-broken/blob/master/package.json#L46

Added it to Jest config:
https://github.com/JVMartin/jest-fp-ts-broken/blob/master/jest.config.js#L6

Added it to global:
https://github.com/JVMartin/jest-fp-ts-broken/blob/master/global.d.ts

Included global:
https://github.com/JVMartin/jest-fp-ts-broken/blob/master/tsconfig.json#L19

Here is the test:
https://github.com/JVMartin/jest-fp-ts-broken/blob/master/src/main.spec.ts

Result of npm run test:

> [email protected] test
> npm run test:unit


> [email protected] test:unit
> jest -c jest.unit.config.js

 FAIL  src/main.spec.ts
  ● Test suite failed to run

    src/main.spec.ts:8:18 - error TS2339: Property 'toBeEither' does not exist on type 'JestMatchers<Validation<{ name: string; }>>'.

    8   expect(either).toBeEither();
                       ~~~~~~~~~~

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        1.255 s
Ran all test suites.

Expect Either.Left error matching string/regex

Is your feature request related to a problem? Please describe.
I'm trying to comfortably express that an Either.Left should be an error with a message string defined as one of the expected values.

Describe the solution you'd like
I'd like to have a .isLeftErrorMatching(string | RegExp) as jest does with normal strings without having to extract the left error message string from the Either result

Describe alternatives you've considered
I can always check if the result is an Either.Left and then access the error message property, but this way I have to use assertions or conditionals during a test, things that in some eslint scenarios are forbidden / discouraged

Additional context
I couldn't find a working method to have what I needed with the current exposed matchers, but if you know how to achieve the same thing, I'm open to anything

Publish files to NPM

Describe the issue
Hello,

It seems like there aren't any files when adding jest-fp-ts as a dependency :(
Looking into my node_modules there's only a package.json referring to thebrodmann/jest-fp-ts
It might be the case that I'm doing something wrong, but at this point I'm not sure of what...

To Reproduce

yarn add --dev jest-fp-ts
# In jest.setup.ts
import 'jest-fp-ts';

Running any test will then fail with

Cannot find module 'jest-fp-ts' from 'jest.setup.ts'

Expected behavior
Being able to use the jest-fp-ts matchers

Suggested fix
I presume (hope) it's a matter of publishing the files

These matchers

Great work, this library works as expected (lol)

I'm using these and would love to see matchers for both.

Will you accept a PR?

TS2305: Module '"@jest/expect-utils"' has no exported member 'TesterContext'.

Describe the issue
Package.json used in my project

    "@relmify/jest-fp-ts": "^2.0.2",
    "@types/jest": "29.0.3",
    "@typescript-eslint/eslint-plugin": "5.40.0",
    "eslint": "8.25.0",
    "eslint-config-prettier": "8.5.0",
    "eslint-config-standard-with-typescript": "23.0.0",
    "eslint-plugin-import": "2.26.0",
    "eslint-plugin-jest": "27.1.3",
    "eslint-plugin-n": "15.3.0",
    "eslint-plugin-prettier": "4.2.1",
    "eslint-plugin-promise": "6.0.1",
    "jest": "^29.0.3",
    "prettier": "2.7.1",
    "ts-jest": "29.0.5",
    "ts-node": "10.9.1",
    "typescript": "4.9.5"

To Reproduce
Install latest version of jest, when try to build the project, it will throw the error TS2305: Module '"@jest/expect-utils"' has no exported member 'TesterContext'.

Remove the "@relmify/jest-fp-ts": "^2.0.2" fixes the issue.

Expected behavior
Project can build successfully

Suggested fix
Upgrade the dependency of the project to latest version of jests

Additional context
Checking in the yarn-lock.json, the library depends on the follow library:

    "@jest/expect-utils" "^28.0.2",
    expect "^28.0.2",
    jest-get-type "^28.0.2",
    jest-matcher-utils "^28.0.2",

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.