Giter Site home page Giter Site logo

typescript-tdd / ts-auto-mock Goto Github PK

View Code? Open in Web Editor NEW
592.0 6.0 15.0 35.82 MB

Typescript transformer to unlock automatic mock creation for interfaces and classes

Home Page: https://typescript-tdd.github.io/ts-auto-mock

License: MIT License

JavaScript 7.54% TypeScript 86.20% Shell 0.02% SCSS 0.81% MDX 5.43%
typescript-transformer mock testing fake typescript automatic mocking

ts-auto-mock's Introduction

TS auto mock

Test npm version Downloads semantic-release Commitizen friendly GitHub Sponsor

All Contributors

Slack Need help? Join us on Slack

⚠️ This repository is now no longer maintained for new features development ⚠️

A few years ago we've created this project with the idea in mind that typescript transformers would be easier to configure.

Unfortunately the typescript team has no intention to improve the developer experience. You can see more information at this link.

We believe that stop developing new features is the best decision to inform who is currently using it and who find it for the first time.

We will keep fixing bugs and vulnerability.

Other reasons why this library might not be for you:

  • Typescript transformers works only when using the tsc typescript compiler. If you are using esbuild or swc you will not be able to use this library.
  • Test double are a double-edge sword. They have to be used carefully and at the right time. Increasing the number of test doubles could decrease the value of your tests. The amount of configuration required by this library might not justify the amount of test doubles that your application requires.

A TypeScript transformer that will allow you to create mocks for any types (interfaces, classes, etc.) without the need to create manual fakes/mocks.

Quick overview

import { createMock } from 'ts-auto-mock';

interface Person {
    id: string;

    getName(): string;

    details: {
        phone: number
    }
}

const mock = createMock<Person>();
mock.id // ""
mock.getName() // ""
mock.details // "{ phone: 0 }"

Changelog

Find the changelog here: Changelog.

Roadmap

You can find the roadmap of this project on the Wiki page: Roadmap.

Do you want to contribute?

Authors

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Artem Kornev

🐛 💻

Fabian

🐛 💻

Geoffrey 'C0ZEN' Testelin

🐛 💻 🤔 🔧

Giulio Caprino

💬 💻 📖 🤔 🚇 🚧 📆

Marc

🐛 💻

Martin Jesper Low Madsen

🐛 💻 🤔

Vittorio Guerriero

💬 💻 🤔 🚇 🚧 📆 🔧

This project follows the all-contributors specification. Contributions of any kind welcome!

Sponsor ✨

Thanks to these people


Kenta Mukai

License

This project is licensed under the MIT License

ts-auto-mock's People

Contributors

artem1458 avatar c0zen avatar dependabot[bot] avatar github-actions[bot] avatar greenkeeper[bot] avatar marcmrf avatar martinjlowm avatar pmyl avatar snyk-bot avatar typescripttdd avatar uittorio avatar wassy92x 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

ts-auto-mock's Issues

multiple usage of typescript libs breaks the name of the spy

interface Mock {
a: Function;
b: Function;
}
const mock: Mock = createMock<Mock>()

expect((mock.a as jasmine.Spy).and.identity).toBe('a');

expect((mock.b as jasmine.Spy).and.identity).toBe('b'); // this fail it returns 'a'

I'm not sure if the issue is just the name or the entire spy created that refer to a instead of b

types key of with index type

When trying to mock this type it will correctly returns the properties of Class but not the value of it

class Class {
 a: string
}

type KeyOf = {[key in keyof Class]: Class[key]};
const mock = createMock<KeyOf>();
mock.a // null. Should be ""

An in-range update of @typescript-eslint/eslint-plugin is breaking the build 🚨

The devDependency @typescript-eslint/eslint-plugin was updated from 2.19.0 to 2.19.1.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

@typescript-eslint/eslint-plugin is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • test (10.x): There are 1 failures, 0 warnings, and 0 notices.

Release Notes for v2.19.1

2.19.1 (2020-02-10)

Bug Fixes

  • eslint-plugin: [unbound-method] blacklist a few unbound natives (#1562) (4670aab)
  • typescript-estree: ts returning wrong file with project references (#1575) (4c12dac)
Commits

The new version differs by 5 commits.

  • 1c8f0df chore: publish v2.19.1
  • 4c12dac fix(typescript-estree): ts returning wrong file with project references (#1575)
  • e9cf734 docs(eslint-plugin): fix typo in readme
  • 10d86b1 docs(eslint-plugin): [no-dupe-class-members] fix typo (#1566)
  • 4670aab fix(eslint-plugin): [unbound-method] blacklist a few unbound natives (#1562)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Indexed access type with generics

I've found a couple of issues related to indexed access type

NOTE: in definitely typed test results this may be references as
Cannot read property 'declarations' of undefined

Class[T]

Example 1

interface WithKeyGeneric<R> {
  test<U extends keyof R>(): WithGeneric<R[U]>
}

class WithGeneric<T> {
  public a: T;
}

const type = createMock<WithKeyGeneric();

This will fail to get R[U] for 2 reasons;

  • the generic is not provided
  • the type parameter used to find a type R is using currently PropertySignatureCache that is meant to be used to store properties name. (I'm not sure if can always work). Example 2 give more explanation about this

Example 2

class Normal {
  public a: number;
  public b: string;
}

interface Test<T extends keyof Normal> {
  prop: Normal[T]
}

const type = createMock<Test<'a'>>();
const type2 = createMock<Test<'b'>>();

type should have a prop with number 0 /// it works
type2 should have a prop with string '' // it doesn't work

The reason is failing is because we are not storing the generic correctly from Test<'a'> or Test<'b'> and we are not getting the correct property T because of the same reason of Example 1

extends typescript libs

I wrote some test scenario with jasmine to simplify the explanation

describe('extends typescript libs', () => {
	interface Interface extends Array<string> {
		b: string;
	}
		
	it('should work', () => {
		const properties: Mock<Interface> = createMock<Interface>();
		expect(properties).toBe(""); // it does not
	});
});

An in-range update of @typescript-eslint/parser is breaking the build 🚨

The devDependency @typescript-eslint/parser was updated from 2.19.0 to 2.19.1.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

@typescript-eslint/parser is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • test (10.x): There are 1 failures, 0 warnings, and 0 notices.

Release Notes for v2.19.1

2.19.1 (2020-02-10)

Bug Fixes

  • eslint-plugin: [unbound-method] blacklist a few unbound natives (#1562) (4670aab)
  • typescript-estree: ts returning wrong file with project references (#1575) (4c12dac)
Commits

The new version differs by 5 commits.

  • 1c8f0df chore: publish v2.19.1
  • 4c12dac fix(typescript-estree): ts returning wrong file with project references (#1575)
  • e9cf734 docs(eslint-plugin): fix typo in readme
  • 10d86b1 docs(eslint-plugin): [no-dupe-class-members] fix typo (#1566)
  • 4670aab fix(eslint-plugin): [unbound-method] blacklist a few unbound natives (#1562)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Performance test

As a developer I would like to make sure that after any changes tsAutoMock will not impact too much the tests suite.

Acceptance criteria

  • Specific test performance project should exist in tsAutoMock
  • It should run against all the feature
  • It should have enough test to cover real scenarios (1000? 10000?) - I dont know
  • They should run every build

@Pmyl is aware from early investigation that tsAutoMock was adding few seconds to the test run.
We should create a real scenario and confirm this number, then we can decide how much delay is permitted from this library.

Implementing VariableDeclaration

related to #83 - when I setup the following test

import { createMock } from 'ts-auto-mock';
import { Connection, Model, Document} from 'mongoose';

describe('for mongoose', () => {
    describe('connection', () => {
        interface Thing extends Document{
          name: string
        }
        interface Interface {
          thing: Model<Thing>
        }

        fit('should set an empty string', () => {
            const mock: Interface = createMock<Interface>();
            console.log(mock.thing);
        });
    });
});

It gives the following error

Child process failed to process the request: TypeError: Cannot read property '0' of undefined
    at /ts-auto-mock/dist/transformer/index.js:1:6932

running it with jest-ts-auto-mock also helpfully reveals
NOT IMPLEMENTED VariableDeclaration

I'm happy to have a crack at implementing VariableDeclaration if that would be useful.

Support for type of

typeof is not currently supported and it would be nice to implement the correct value.

Example

var obj = {
   a: ''
}
interface Interface {
    typeOf: typeof obj;
 }

The result of typeOf should be the var obj with default values.
A solution would be to generate the literal type on the fly and keep in the correct scope
I am not sure yet about all the implementations and how to solve it because there are scenario that a bit more complex. For example typeof of an enum type.

This issue needs to be investigated.

An in-range update of webpack is breaking the build 🚨

The devDependency webpack was updated from 4.35.3 to 4.36.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

webpack is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ci/circleci: build: Your tests failed on CircleCI (Details).

Release Notes for v4.36.0

Features

  • SourceMapDevToolPlugin append option now supports the default placeholders in addition to [url]
  • Arrays in resolve and parser options (Rule and Loader API) support backreferences with "..." when overriding options.
Commits

The new version differs by 42 commits.

  • 95d21bb 4.36.0
  • aa1216c Merge pull request #9422 from webpack/feature/dot-dot-dot-merge
  • b3ec775 improve merging of resolve and parsing options
  • 53a5ae2 Merge pull request #9419 from vankop/remove-valid-jsdoc-rule
  • ab75240 Merge pull request #9413 from webpack/dependabot/npm_and_yarn/ajv-6.10.2
  • 0bdabf4 Merge pull request #9418 from webpack/dependabot/npm_and_yarn/eslint-plugin-jsdoc-15.5.2
  • f207cdc remove valid jsdoc rule in favour of eslint-plugin-jsdoc
  • 31333a6 chore(deps-dev): bump eslint-plugin-jsdoc from 15.3.9 to 15.5.2
  • 036adf0 Merge pull request #9417 from webpack/dependabot/npm_and_yarn/eslint-plugin-jest-22.8.0
  • 37d4480 Merge pull request #9411 from webpack/dependabot/npm_and_yarn/simple-git-1.121.0
  • ce2a183 chore(deps-dev): bump eslint-plugin-jest from 22.7.2 to 22.8.0
  • 0beeb7e Merge pull request #9391 from vankop/create-hash-typescript
  • bf1a24a #9391 resolve super call discussion
  • bd7d95b #9391 resolve discussions, AbstractMethodError
  • 4190638 chore(deps): bump ajv from 6.10.1 to 6.10.2

There are 42 commits in total.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

add ability to define custom mocks for same type (example, Promises)

With the current implementation of the library to mock a promise with your special promise you need to

const mockManuallyEdited = createMock<{ promise: Promise<string>; }>();
mockManuallyEdited.promise = new CustomFakePromise();
(mockManuallyEdited.promise as CustomFakePromise<string>).resolve('data');

It would be nice to have the ability to define a mock once and it will be used for that type all the time.

declare function alwaysUseCustomMock<T extends object, U extends T>(factory: () => U): <T2>(cb: (mock: T2) => T) => Extension<T2, U>;
// usage
alwaysUseCustomMock<Promise<any>, CustomFakePromise<any>>(() => new CustomFakePromise());

Improve definition for exported modules that are used by the transformed mock

There are few modules that are exported because the code transformed need them at runtime.

We have right now:
in ts-auto-mock/extension:

  1. Marker

in ts-auto-mock/repository:

  1. Repository

Instead of exporting the class or the method directly we should exporting as ɵ{NameOfTheClass} so it's more clear that it should be be used by the user

Example:

export { Marker as ɵMarker } from './marker/marker';

With this solution the user would be less temped to use them

This change would affect also the internal usage in the transformer module.

improve caching for generics

The current code base is not caching types that use generics. Ideally we would like to cache the types and use the generic value at runtime. Something like this.

repository.register('mockFactory-person', (function(generics1, generics2) {
    var name, id, legs;
    return {
      get name() { return name || (name = '') },
      set name(_name) { name = _name },
      get id() { return id || (id = repository.getGenericFactory(generics1.key)(generics1.childGenerics)) },
      set id(_id) { id = _id },
      get legs() { return legs || (legs = repository.getFactory('mockFactory-legs')(generics2)) },
      set legs(_legs) { legs = _legs }
    }
});

const personMock = createMock<Person<string, HumanLeg<number>>>();
//will be transformed into
const personMock = repository.getFactory('mockFactory-person')({ key: 'native.string' }, { key: 'mockFactory-human-leg', childGenerics: ['native.number'] })

Generic reused

Example

interface Interface<T> {
  generic: T;
}

const mock1 = createMock<Interface<string>>();
mock.generic // "" CORRECT
const mock2 = createMock<Interface<number>>();
mock2.generic // "" WRONG. IT should be 0

Prevent repetition of emitted code when mocking extended/implemented interfaces

As a user I want to be able to run my test suit with more performance as possible without code repetition emitted by the transformer.

Use case
Given the case where we have an interface and an implemented class:

interface IPerson {
  firstName: string;
  lastName: string;
}

class PersonImpl implements IPerson {
  public firstName: string;
  public lastName: string;
  public age: number;
}

if I mock Person in one spec and IPerson in another spec I ends up with this (more or less) emitted code:

// factory for IPerson mock
repository.register('mockFactory-i-person', (function(){
  var firstName, lastName;
  return {
    get firstName() { return firstName || (firstName = '') },
    set firstName(_firstName) { firstName = _firstName },
    get lastName() { return lastName || (lastName = '') },
    set lastName(_lastName) { lastName = _lastName }
  }
}))

// factory for PersonImpl mock
repository.register('mockFactory-person-impl', (function(){
  var firstName, lastName, age;
  return {
    get firstName() { return firstName || (firstName = '') },
    set firstName(_firstName) { firstName = _firstName },
    get lastName() { return lastName || (lastName = '') },
    set lastName(_lastName) { lastName = _lastName },
    get age() { return age || (age = '') },
    set age(_age) { age = _age }
  }
}))

The emitted code contains a repetition that could affect the performance in the long run.

Proposed solution
I don't have a complete solution but the idea is to treat extension (and intersection between objects) using some sort of Object.assign to reuse already existing factories.
The final emitted code would be on the line of:

// factory for IPerson mock
repository.register('mockFactory-i-person', (function(){
  var firstName, lastName;
  return {
    get firstName() { return firstName || (firstName = '') },
    set firstName(_firstName) { firstName = _firstName },
    get lastName() { return lastName || (lastName = '') },
    set lastName(_lastName) { lastName = _lastName }
  }
}))

// factory for PersonImpl mock
repository.register('mockFactory-person-impl', (function(){
  var age;
  return assignWorkingForGetSet({
      get age() { return age || (age = '') },
      set age(_age) { age = _age }
    },
    repository.get('mockFactory-i-person')
  );
}))

ts_auto_mock_1.createMock is not a function

This issue happened in windows environment using git bash. the transformer is not able to find the createMock function, so it will not convert the mock.

If you run npm run test:debug it will log the differences between the paths

The ideal solution is to make sure the path comparison is environment compatible, using path join in the transformer matcher

Question: Can we change the defaults?

Hello,

Awesome idea with this project!

I'm trying to implement this in one of my projects and it seems to work pretty well so far.

I've seen that the mocks generated have these defaults:
https://github.com/Typescript-TDD/ts-auto-mock/blob/master/docs/DETAILS.md

I'm curious if there is a way to change all the defaults since, for example, an empty string is acting strangely in React and I'd like to have all the strings mapped to something like Mocked string.

Thanks!

An in-range update of commitlint is breaking the build 🚨

There have been updates to the commitlint monorepo:

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

This monorepo update includes releases of one or more dependencies which all belong to the commitlint group definition.

commitlint is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ci/circleci: build: Your tests failed on CircleCI (Details).

Commits

The new version differs by 39 commits.

  • c17420d v8.1.0
  • ca19d70 chore: update dependency lodash to v4.17.14 (#724)
  • 5757ef2 build(deps): bump lodash.template from 4.4.0 to 4.5.0 (#721)
  • 5b5f855 build(deps): bump lodash.merge from 4.6.0 to 4.6.2 (#722)
  • 4cb979d build(deps): bump lodash from 4.17.11 to 4.17.13 (#723)
  • a89c1ba chore: add devcontainer setup
  • 9aa5709 chore: pin dependencies (#714)
  • c9ef5e2 chore: centralize typescript and jest setups (#710)
  • c9dcf1a chore: pin dependencies (#708)
  • 6a6a8b0 refactor: rewrite top level to typescript (#679)
  • 0fedbc0 chore: update dependency @types/jest to v24.0.15 (#694)
  • 0b9c7ed chore: update dependency typescript to v3.5.2 (#695)
  • 4efb34b chore: update dependency globby to v10 (#705)
  • 804af8b chore: update dependency lint-staged to v8.2.1 (#696)
  • 9075844 fix: add explicit dependency on chalk (#687)

There are 39 commits in total.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Override default values of mock

Sometimes we need a mock of a type but we need to specify some properties directly.

Right now to do it you have to create the mock and then ovveride the value manually

What if we could pass a value that has to be a partial of the type for the mock and it will ovveride the value?

interface Type { propertyA: number; propertyB: string; propertyC: boolean; } createMock<Type>({ propertyA: 5, propertyB: “my value”)

An in-range update of @typescript-eslint/eslint-plugin-tslint is breaking the build 🚨

The devDependency @typescript-eslint/eslint-plugin-tslint was updated from 2.19.0 to 2.19.1.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

@typescript-eslint/eslint-plugin-tslint is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • test (10.x): There are 1 failures, 0 warnings, and 0 notices.

Release Notes for v2.19.1

2.19.1 (2020-02-10)

Bug Fixes

  • eslint-plugin: [unbound-method] blacklist a few unbound natives (#1562) (4670aab)
  • typescript-estree: ts returning wrong file with project references (#1575) (4c12dac)
Commits

The new version differs by 5 commits.

  • 1c8f0df chore: publish v2.19.1
  • 4c12dac fix(typescript-estree): ts returning wrong file with project references (#1575)
  • e9cf734 docs(eslint-plugin): fix typo in readme
  • 10d86b1 docs(eslint-plugin): [no-dupe-class-members] fix typo (#1566)
  • 4670aab fix(eslint-plugin): [unbound-method] blacklist a few unbound natives (#1562)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Add tslint to project

Add tslint to project so the code will be consistent with different developers/machines

Union type string imported

If using a union type imported in an interface the transformers can't resolve it.

describe('union type string imported', () => {
  it('should assign the first value as if it would declared literal', () => {
    interface UnionContainer {
      union: TypeUnion;
    }

    const properties: Mock<UnionContainer> = createMock<UnionContainer>();
    expect(properties.union).toBe("1");
  });
});

The type TypeUnion is already in the codebase.

Mocks for Typescript Types

Oftentimes I run into issues writing unit tests for my code when it depends on types defined in a third party library. So far I haven't found any solution for this. Types are especially difficult to mock out.

I would love to be able to use this library to mock out TypeScript types. For example, a library has this type defined,

export type Producer = Sender & {
  connect(): Promise<void>
  disconnect(): Promise<void>
  ...
}

Is there any plans to support types? Thank you!

support interfaces with call signatures

Great library - I've been trying to extend it to support call signatures in an interface but am getting a little lost.

This is the code that I'd like to work

    interface InterfaceDefiningMethod {
        (): string;
    }

    interface Interface {
        a: InterfaceDefiningMethod;
    }

    it('should set the functions', () => {
        const properties: Interface = createMock<Interface>();
        expect(properties.a()).toBe('');
    });

I've played around with using typeChecker.getSignaturesOfType to get hold of the call signature but am struggling to find the right way to return a function.

joshuavial@21dbe1d has an example of what I've been trying - any tips on the best way to solve this?

Create mock of defined number of list

It would be nice to have a quick way to create mock for an array of types.. if I want to create a mock of an array of a particular type createMock will return an empty array.

The proposal is to create a createMockList function that need ls the generic type and in the argument receive the lengh of the array

createMockList(3)

Type Literal Reference with recursion

this should compile correctly.

interface A {
    a: this;

    b: {
        c: string;
    }
}

It gives an error on the compiler.

Reason:
The current descriptor for typeLiteral is acting as an InterfaceDeclaration.
Because of this it will replace the current this node causing any other this reference to fail.

Solution:
We should treat typesLiteral as a different descriptor that will not store the this value.

#83

Recursion in intersection

This Interface should be compiled correctly without giving errors

interface InterfaceWithIntersection {
    int: InterfaceWithIntersection & B;
 }

 createMock<InterfaceWithIntersection>

This interface is valid because an intersection (InterfaceWithIntersection & B) its just the combination of multiple types.
The current compiler is failing because is trying to resolve all the properties of an intersection type causing a maximum call stack error.

This is what is happening

  1. It will first resolve Interface
  2. it will find the property int
  3. it will detect that is an InterfaceWithIntersection
  4. it will resolve all the properties of InterfaceWithIntersection & B.

Because its resolving all the properties of InterfaceWithIntersection it will do keep resolving itself.

The proposed solution is to create a cache declaration for Intersection type, like we do for any other declarations.

The cache declaration will contains 2 declarations and every time the compiler will find an intersectionType it will check the cache first, so it will not resolve all the properties again

With this solution we have to be careful about

  • generics,
  • intersection between primitive types (string)
  • intersection with typescript libraries, like promises

We should create multiple tests for all the scenario above

Union type empty objects crash

// imported
export type Object = {} | {};
// finish import

describe('union type empty object imported', () => {
  it('should assign the first value as if it would declared literal', () => {
    interface UnionContainer {
      union: Object;
    }

    const properties: Mock<UnionContainer> = createMock<UnionContainer>();
    expect(properties.union).toEqual({});
  });
});

Cannot read property for 3rd party types

I am on a Google Apps Script project using typescript and use @types/google-apps-script for the types. I want to create a mock object to test an apps script object locally.

const mockSpreadsheet = createMock<GoogleAppsScript.Spreadsheet.Spreadsheet>();

but when running the test (with mocha) I got this error message:

> npx mocha -r ./tsnode.js **/*.spec.ts

Cannot read property 'kind' of undefined

Previously I tried to use an interface I created by myself at it worked. But when I am using interface from apps script (GoogleAppsScript.Spreadsheet.Spreadsheet) it returned an error. I am not sure this is the problem with ts-auto-mock or the 3rd party types

Improve mock registration cache

As a ts auto mock user I would like to create mocks only once if they are repeated in the code so it will be faster.

Everytime ts auto mock find a createMock it will create a mock of Interface in the current test

test1.test.ts
Pseudo code:

// test1.test.ts
import {repository} from 'ts-auto-mock/repository';

repository.instance.registerFactory("create__interface__mock_1", () => {
... // the mock
})

test2.test.ts
When another test will need to mock Interface instead of recreating it will import repository and use the mock

// test2.test.ts
import {repository} from 'ts-auto-mock/repository';
var mock = repository.instance.getFactory("create__interface__mock_1")();

Ts Auto Mock controls the compilation but not how test are run
This could be bring few issues:

  • if the tests are not run in the same context it will not find the mock
  • if the tests are run in parallel it will not find the mock

Possible solution:
There is a current workaround to this issue in the options (cacheBetweenTests) that disable the cache between files. However we could:

  • Register the mock in a generated file during compilation (create__interface__mock_1.ts)
  • Import the mock in the test that needs it
// test2.test.ts
import {create_interface_mock_1} from 'pathToTheMockGenerated';
var mock = create_interface_mock_1();

Please feel free to comment and add anything I've missed

Improve example documentation

One of the challenges to use ts-auto-mock is the installation.

We should provide better documentation case by case for each type of configuration

Few on top of my mind:

Jest
karma and webpack
angular-cli
webpack

and more

Feel free to comment on this issue for more potential configuration"

Improve typings for Mock

Currently the type of Mock that is returned by createMock is not working for all the scenario and you may need to cast it to his original type to make it work.

Example

interface Interface {
 a: string;
 method(): Promise<number>;
}
   
class Class {
 constructor(int: Interface) {}
}
   
const mock: Mock<Interface> = createMock<Interface>();
new Class(mock) // error
new Class(mock as unknown as Interface) // it works.. but is not a good casting

Return null

Hello,

I have the problem, that in one of my tests I need the return value "null".
My Interface looks like these:

interface IFooBar {
  readonly id: string;
}
interface IFoo {
  readonly bar: IFooBar;
}

When I create a new mock with

createMock<IFoo>({
  bar: null
});

The resulting object is always:

{
  bar: {
    id: ""
  }
}

Is it possible somehow to return null instead?

Intersection types its loosing generics

When mocking intersections generics are not correctly applied if the same interface is used more than once in the same intersection

Example

interface Test<T> { test: T; }

    interface Interface<T, T2> {
        a: Interface<T, T2> & Test<T> & Test<T2>;
    }

    interface TestA {
        b: string;
    }

    interface TestB {
        c: number;
    }

    const properties: Interface<TestA, TestB> = createMock<Interface<TestA, TestB>>();
    expect(properties.a.test.b).toBe('');
    expect(properties.a.test.c).toBe(0);

TestB is completely ignored for 2 reason:

  1. Deep merge doesnt work #94
  2. generics refer always to a single type based on the declaration.

For-of-loop in test

Unfortunately I found another bug.
As soon as I create a mock of an interface, I can't use For-of-loops in my tests.
I always get an exception: "TypeError: Cannot read property 'ɵRepository' of undefined"
If I comment out createMock, the for-of-loop works correctly.

Example:

import { createMock } from 'ts-auto-mock';

interface MyInterface {
    a: string;
}

describe('Foo', () => {
    test('some test', () => {
        const myInstance: MyInterface = createMock<MyInterface>();
        const a: string[] = ['hello', 'world'];
        for (const b of a) {
            console.log(b);
        }
    });
});

Intersection types are not merge correctly

In this scenario ts auto mock should be able to mix/merge all the properties for ABC

interface D { d: { d1: string }; }
interface E { d: { d2: number }; }
interface F { f: number; }
interface A { x: D; }
interface B { x: E; }
interface C { x: F; }

type ABC = A & B & C;
const abc: ABC = {
    x: {
        d: {
            d1: '',
            d2: 0,
        },
        f: 3,
    },
};

Right now instead it will not merge literal properties after the first level.
f and d2 will not be in the mock

Issue
Its failing because it resolving the properties of the initial intersections types that will not include the subtypes

Possible solution
Still to investigate

RangeError: Maximum call stack size exceeded

When extending an interface that has this in one of his type the compiler report:
RangeError: Maximum call stack size exceeded

interface TestB {
  property: this
}
interface Test extends TestB {}

after an investigation I've found out the the "this" reference refer to TestB instead of Test.
That is wrong because in javascript "this" should refer to Test when extending

Documentation on transformer descriptor

Right now is difficult to understand what happen for specific scenario like

() => void or interface {a: string, b: number }

Is not easy to follow the code to understand where it happen and what is what.

We need some kind of documentation to help maintain and debug the code

Issue with webpack live-reload

I did and run a simple example usage of this library. I faced with runtime issue after I re-save my code then I get an error:

TypeError: c_projects_test_src_index_ts_Repository.ɵRepository.instance.getFactory(...) is not a function

"RangeError: Maximum call stack size exceeded" when mocking a large library

joshuavial@1647fc0 has an example of ts-auto-mock failing to parse a fairly large definition file from mongoose (https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/mongoose/index.d.ts)

Child process failed to process the request: RangeError: Maximum call stack size exceeded
    at getTypeOfNode (/ts-auto-mock/node_modules/typescript/lib/typescript.js:60536:20)
    at Object.getTypeAtLocation (/ts-auto-mock/node_modules/typescript/lib/typescript.js:32265:31)
    at /ts-auto-mock/dist/transformer/index.js:1:6913

I'm wondering if it's a problem with the size of the definition causing the GetDeclaration recursion to overrun the stack size. Hopefully there is a simple work around which doesn't involve a lot of re-architecture, but happy to lend a hand if that's what it takes to parse the library.

intersection with typescript libs

I wrote some test scenario with jasmine to simplify the explanation

describe('intersection with typescript lib', () => {
	type TypeIntersection = {} & Promise<string>;
		
	interface Intersection {
		a: TypeIntersection;
	}

	it('should be undefined', () => {
		const properties: Mock<Intersection> = createMock<Intersection>();
		expect(properties.a.then).toBeUndefined(); // it fail
	});
});

Add changelog

It would be nice to automate the changes between one version to another with the list of bugs and feature done

Variable Declaration

In typescript you can define a Variable with the same name as an interface

var Test: Test;

interface Test {
   a: string;
}

createMock<Test>();

This should refere to Test interface and not variable.

Typescript should always use the interface and not the variable.

Issue
The compile fail because its trying to use variable declaration as type;
TsAutoMock doesn't distinguish about multiple declarations and will always use the first one.

Possible solution
A possible solution is to ignore any variable declaration from declarations list.

Add support for babel (Maybe)

When babel is used in combination with Typescript is not possible to use ts-auto-mock because the code is compiled by Babel.

This issue opened in typescirpt-is explain the scenario (https://github.com/woutervh-/typescript-is/issues/18)

A possible solution would be to write another plugin for babel

I've opened this issue as a placeholder, I'm not sure yet how much work is involved to achieve this.

Improve mock typings and front interface

export type Mock<T> = T & { ___thisIsAMockMarker: boolean };

This is horrible.

And it was my idea. Bad Giulio.

I have an alternative for this. During On.Mock(myMock) instead of giving an error at development time I would give an error at runtime.

Let's remove the type Mock<T> and just return T from createMock(). During On.Mock(myMock) we just check if ___thisIsAMockMarker is defined (we don't care about the value) and if it doesn't we throw an Error that says that the provided mock is not recognized as a mock object.

If we then want to remove ___thisIsAMockMarker we can use other techniques (e.g. all the mocks objects are created from a class and we test it with instanceof) but at that point we will still keep the same interface and everything will be retrocompatible.

Map not supported

Hello,

I found another problem with the Map-Class.
If I write the following code:

interface Foo {
    c: Map<string, string>;
}
const foo: Foo = createMock<Foo>();

The resulting object doesn't have the key "c":

import * as ɵRepository from "ts-auto-mock/repository";
import * as ɵExtension from "ts-auto-mock/extension";
import * as ɵMerge from "ts-auto-mock/merge";
ɵRepository.ɵRepository.instance.registerFactory("@Foo_1", function(t) {
    return (function() {
        var d = {},
            m = {};
        Object.defineProperty(m, ɵExtension.ɵMarker.instance.get(), {
            value: !0
        });
        return m;
    })();
});
import {
    createMock
} from 'ts-auto-mock';
const foo = ɵRepository.ɵRepository.instance.getFactory("@Foo_1")([]);

Is this issue known?
My environment:

  • ts-auto-mock: 1.5.2
  • ttypescript: 1.5.10
  • typescript: 3.7.5

tsconfig.json

{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "declaration": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "noImplicitAny": false,
    "noImplicitThis": true,
    "skipLibCheck": true,
    "lib": [
      "dom",
      "ES6"
    ],
    "module": "ES6",
    "moduleResolution": "node",
    "sourceMap": true,
    "target": "ES6",
    "plugins": [
      { "transform": "ts-auto-mock/transformer" }
    ]
  },
  "include": [
    "src/**/*.ts",
    "typings/index"
  ],
  "exclude": [
    "node_modules"
  ],
  "compileOnSave": false
}

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.