Giter Club home page Giter Club logo

pact-gen-ts's People

Contributors

crpc avatar fiszcz avatar lukaszfiszer avatar pawfa avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Forkers

fiszcz pawfa

pact-gen-ts's Issues

Generation fails when API function is defined as arrow function expression

When API function is defined as arrow function expression:

/**
 * @pact
 * @pact-method GET
 * @pact-path /example
 */
const getExample = () => axios.get('/example')

pact-gen-ts fails with following error:

> pact-gen-ts

InvalidOperationError: A child of the kind Block was expected.
    at Object.throwIfNullOrUndefined (C:\Users\hlukafis\projects\payments-in-ui\node_modules\@ts-morph\common\dist\ts-morph-common.js:471:19)
    at ArrowFunction.getFirstChildByKindOrThrow (C:\Users\hlukafis\projects\payments-in-ui\node_modules\ts-morph\dist\ts-morph.js:3734:30)
    at InteractionCreator.getResponseBodyForApiFunction (C:\Users\hlukafis\projects\payments-in-ui\node_modules\pact-gen-ts\lib\core\interaction-creator.js:73:50)
    at InteractionCreator.getInteractionForPactJsDoc (C:\Users\hlukafis\projects\payments-in-ui\node_modules\pact-gen-ts\lib\core\interaction-creator.js:57:43)
    at Array.map (<anonymous>)
    at InteractionCreator.findAllInteractions (C:\Users\hlukafis\projects\payments-in-ui\node_modules\pact-gen-ts\lib\core\interaction-creator.js:113:31)
    at Function.getAllInteractionsInFile (C:\Users\hlukafis\projects\payments-in-ui\node_modules\pact-gen-ts\lib\core\interaction-creator.js:109:61)
    at readInteractionsFromFiles (C:\Users\hlukafis\projects\payments-in-ui\node_modules\pact-gen-ts\lib\core\create-pacts.js:51:71)
    at createPactForProvider (C:\Users\hlukafis\projects\payments-in-ui\node_modules\pact-gen-ts\lib\core\create-pacts.js:38:35)
    at C:\Users\hlukafis\projects\payments-in-ui\node_modules\pact-gen-ts\lib\core\create-pacts.js:28:61

Test pact-gen-ts using multiple TypeScript versions

TypeScript compiler changes have a huge impact on pact-gen-ts functionality. Due to TS not following semantic versioning it is hard to predict when it might cause issues with pact-gen-ts library.

My suggestion is to test library with different versions of TypeScript - including @next. Example implementation provided here: react-redux gh action with different TS versions.

It could give us quick feedback whether the API changed in upcomfing TypeScript version

Handle .tsx files

Our tool cannot analyze .tsx files with JSX syntax.
And throw error with any type when we for example export type from .tsx files.

Rename @pact-body to @pact-request-body

Since we already have @pact-response-body and @pact-response-header annotation, the body of the request should be annotated with @pact-request-body for consistency and to avoid confusion

Nested objects in interfaces/types are overwritten by last @pact-matcher used

When api function return type/interface contains nested object which itself contains one of the @pact-matcher - whole nested object in body in generated pact is replaced with the last pact-matcher defined. Example definitions and output:

export interface PactMatchersNestedType {
    nestedObject: {
        /** @pact-matcher hex */
        matcher?: string;
    }
}

/**
 * @pact
 * @pact-method GET
 * @pact-path /api
 */
export function apiNestedFunction(): PactMatchersNestedType {
    return {
        nestedObject: {}
    };
}

generated interaction looks like this:

      "description": "apiNestedFunction",
      "request": Object {
        "headers": Object {},
        "method": "GET",
        "path": "/api",
      },
      "response": Object {
        "body": Object {
          "nestedObject": "3F",
        },
        "headers": Object {},
        "matchingRules": Object {
          "$.body": Object {
            "match": "type",
          },
          "$.body.nestedObject": Object {
            "match": "regex",
            "regex": "^[0-9a-fA-F]+$",
          },
        },
        "status": 200,
      },

where as you can see nestedObject property inside body is replaced with hex from defined pact-matcher.

I've tested a few pact-matchers and this issue happens every time. If more than one pact-matcher is defined then the last one is used.
Marked property can be optional or required, nested object can contain additional optional or required properties not marked with any matcher - with all this cases same issue occurs.

Same issue happens for interface and TS type definition.

Duplicated machingRules

When both /** @pact-request-body */ and /** @pact-response-body */ are used in one API function matchingRules are duplicated. Example:
this API function:

    async putApiCall() {
        /** @pact-request-body */
        const sendData= {prop: 1}
        const response = await this.axios.put<{ id: number, name: "John" | 'Emily' }[]>(
            `/example`,sendData
        );
        /** @pact-response-body */
        const data = response.data;
        return data
    }

will create this interaction:

{
      "request": {
        "method": "GET",
        "path": "/example",
        "headers": {
          "X-Client-Number": "12345"
        },
        "body": {
          "prop": 10
        },
        "matchingRules": {
          "$.body.name": {
            "match": "regex",
            "regex": "John|Emily"
          },
          "$.body": {
            "match": "type"
          }
        }
      },
      "response": {
        "headers": {
          "Content-Type": "application/json"
        },
        "body": [
          {
            "id": 10,
            "name": "John"
          }
        ],
        "matchingRules": {
          "$.body.name": {
            "match": "regex",
            "regex": "John|Emily"
          },
          "$.body": {
            "match": "type"
          }
        },
        "status": 200
      },
      "description": "putApiCall"
    }

where matchingRules for response and request are the same.

Add @pact-axios annotation

  • - add @pact-axios annotation which will generate pact from axios usage
  • - get response body from axios usage
  • - get request body from axios usage
  • - get query params from axios usage
  • - get HTTP method from axios usage
  • - get URL path from axios usage

Handle non-default stringifying of arrays in query

Code responsible for stringifying query params does not give an option to use other arrayFormat than default. This sometimes leads to being unable to generate pacts that reflect the way application calls an endpoint.

I think current API for defining query could be enhanced to something of following format:

/** 
* @pact-query 
* @query-array-format: comma // optional param, default is unchanged
*/`
const query = {
  ...
}

What do you guys think about it?

Empty response body

Currently when API function with pact-gen-ts docs does not implicitly return, what makes its type Promise, in generated interaction response body is defined as an empty object, e.g.:
API function:

    async putApiCall() {
        await this.axios.put( `/example`,{id: 1});
    }

and generated response in interaction:

      "response": {
        "status": 204,
        "headers": {
          "Content-Type": "application/json"
        },
        "body": {}
      },

to be consistent with existing pact specification body property should not be defined in generated pact in this scenario.

TS 4.4 compatibility broken

Pact-gen-ts does not generate any pacts for TS 4.4 - probably an issue is within ts-morph and analyzing files content. Need further investigation here.

Resolve path from axios request

It is a follow up of a review and implementation of #48 issue.

It is possible to resolve path from axios function call.
const {data} = await axios.get<string>('/api');

Url is always the first argument of axios call. It might take different forms which need to be handled, for example it could be simple string, template string, concatenated string, variable from other module, etc.

The final result of the type sent to function is always string.

Add "debug" flag to config

  • - add "debug" flag, enabling printing more information about the analysis of code and types.
  • - will print which file is currently analyzing
  • - will print which function is currently analyzing
  • - will print which type is currently analyzing

Typescript 4.7 support

After typescript upgrade to v4.7 pact-gen-ts doesn't generate json report.
Error: Pact interactions for provider: ... are empty.

Should exit with error on empty interactions array

Sometimes pact-gen-ts exits with error code 0 while not generating any interactions (for example when using with TypeScript 4.4 - issue tracked here).

I think this should always be treated as an error state with proper message.

If having no interactions with given provider is intentional, we should suggest removing config for this provider entirely.

Response body is silently not generated when type is "any"

When generating pacts from example/ the following pact is generated for getPosts interaction:

    {
      "request": {
        "path": "/api/clients/10/posts",
        "method": "GET",
        "headers": {},
        "query": "booleanField=true&fromDate=2013-02-01",
        "matchingRules": {
          "$.query.fromDate": {
            "match": "regex",
            "regex": "^([\\+-]?\\d{4}(?!\\d{2}\\b))((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))?)$"
          }
        }
      },
      "response": {
        "headers": {
          "Content-Type": "application/json"
        },
        "body": {},
        "status": 200
      },
      "description": "getPosts"
    },

The response.body is empty, even though /** @pact-response-body */ annotation is used in the getPosts function.

The same issue is present in pact for addNewPost

Type matchers JSDoc API

Instead of multiple annotations @pact-datetime, @pact-date, I suggest that we should have a single annotation @pact-type (the exact name is up to discussion) with different values.

interface User {
    /** @pact-type uuid */
    id: string;
    /** @pact-type email */
    email: string;
}

Some of the values should be renamed to be more precise:

  • date -> isoDate
  • dateTime -> isoDateTime

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.