Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent Jest coverage between shards #7904

Closed
ghost opened this issue Aug 31, 2023 · 3 comments
Closed

Inconsistent Jest coverage between shards #7904

ghost opened this issue Aug 31, 2023 · 3 comments

Comments

@ghost
Copy link

ghost commented Aug 31, 2023

Describe the bug

This is slightly different than #3854

The issue I'm seeing is that when you run jest with coverage and sharding, ts-jest causes jest to output consistent coverage-final.json files while swc/jest causes it to output inconsistent coverage-final.json files.

swc/jest -> coverage-shard-1.json:

{
  "[REDACTED-PATH]\\index.ts": {
    "path": "[REDACTED-PATH]\\index.ts",
    "statementMap": {
      "0": { "start": { "line": 4, "column": 13 }, "end": { "line": 4, "column": 24 } },
      "1": { "start": { "line": 1, "column": 26 }, "end": { "line": 1, "column": null } },
      "2": { "start": { "line": 2, "column": 25 }, "end": { "line": 2, "column": null } },
      "3": { "start": { "line": 4, "column": 24 }, "end": { "line": 4, "column": null } }
    },
    "fnMap": {},
    "branchMap": {},
    "s": { "0": 2, "1": 2, "2": 2, "3": 2 },
    "f": {},
    "b": {}
  }
}

swc/jest -> coverage-shard-2.json:

{
  "[REDACTED-PATH]\\index.ts": {
    "path": "[REDACTED-PATH]\\index.ts",
    "statementMap": {
      "0": { "start": { "line": 4, "column": 24 }, "end": { "line": 4, "column": 52 } }
    },
    "fnMap": {},
    "branchMap": {},
    "s": { "0": 0 },
    "f": {},
    "b": {}
  }
}

swc/jest -> nyc merge -> coverage-final.json:

{
  "[REDACTED-PATH]\\index.ts": {
    "path": "[REDACTED-PATH]\\index.ts",
    "statementMap": {
      "0": { "start": { "line": 4, "column": 24 }, "end": { "line": 4, "column": 52 } },
      "1": { "start": { "line": 4, "column": 13 }, "end": { "line": 4, "column": 24 } },
      "2": { "start": { "line": 1, "column": 26 }, "end": { "line": 1, "column": null } },
      "3": { "start": { "line": 2, "column": 25 }, "end": { "line": 2, "column": null } },
      "4": { "start": { "line": 4, "column": 24 }, "end": { "line": 4, "column": null } }
    },
    "fnMap": {},
    "branchMap": {},
    "s": { "0": 0, "1": 2, "2": 2, "3": 2, "4": 2 },
    "f": {},
    "b": {}
  }
}

ts-jest -> coverage-shard-1.json:

{
  "[REDACTED-PATH]\\index.ts": {
    "path": "[REDACTED-PATH]\\index.ts",
    "statementMap": {
      "0": { "start": { "line": 1, "column": 0 }, "end": { "line": 1, "column": 48 } },
      "1": { "start": { "line": 2, "column": 0 }, "end": { "line": 2, "column": 46 } },
      "2": { "start": { "line": 4, "column": 13 }, "end": { "line": 4, "column": 52 } }
    },
    "fnMap": {},
    "branchMap": {},
    "s": { "0": 2, "1": 2, "2": 2 },
    "f": {},
    "b": {}
  }
}

ts-jest -> coverage-shard-2.json:

{
  "[REDACTED-PATH]\\index.ts": {
    "path": "[REDACTED-PATH]\\index.ts",
    "statementMap": {
      "0": { "start": { "line": 1, "column": 0 }, "end": { "line": 1, "column": 48 } },
      "1": { "start": { "line": 2, "column": 0 }, "end": { "line": 2, "column": 46 } },
      "2": { "start": { "line": 4, "column": 13 }, "end": { "line": 4, "column": 52 } }
    },
    "fnMap": {},
    "branchMap": {},
    "s": { "0": 0, "1": 0, "2": 0 },
    "f": {},
    "b": {}
  }
}

ts-jest -> nyc merge -> coverage-final.json:

{
  "[REDACTED-PATH]\\index.ts": {
    "path": "[REDACTED-PATH]\\index.ts",
    "statementMap": {
      "0": { "start": { "line": 1, "column": 0 }, "end": { "line": 1, "column": 48 } },
      "1": { "start": { "line": 2, "column": 0 }, "end": { "line": 2, "column": 46 } },
      "2": { "start": { "line": 4, "column": 13 }, "end": { "line": 4, "column": 52 } }
    },
    "fnMap": {},
    "branchMap": {},
    "s": { "0": 2, "1": 2, "2": 2 },
    "f": {},
    "b": {}
  }
}

Input code

jest --silent --coverage --shard=1/2
mv ./coverage/coverage-final.json ./coverage/coverage-shard-1.json

jest --silent --coverage --shard=1/2
mv ./coverage/coverage-final.json ./coverage/coverage-shard-2.json

nyc merge ./coverage/ ./.nyc_output/coverage-final.json

Config

{
  "$schema": "https://json.schemastore.org/swcrc",
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "jsx": false,
      "dynamicImport": false,
      "privateMethod": false,
      "functionBind": false,
      "exportDefaultFrom": false,
      "exportNamespaceFrom": false,
      "decorators": true,
      "decoratorsBeforeExport": true,
      "topLevelAwait": false,
      "importMeta": false
    },
    "transform": null,
    "target": "es5",
    "loose": false,
    "externalHelpers": false,
    // Requires v1.2.50 or upper and requires target to be es2016 or upper.
    "keepClassNames": false
  },
  "minify": false
}

Playground link

No response

SWC Info output

Operating System:
    Platform: win32
    Arch: x64
    Machine Type: x86_64
    Version: Windows 10 Enterprise
    CPU: (12 cores)
        Models: 12th Gen Intel(R) Core(TM) i7-1265U

Binaries:
    Node: 18.16.1
    npm: N/A
    Yarn: N/A
    pnpm: N/A

Relevant Packages:
    @swc/core: 1.3.78
    @swc/helpers: N/A
    @swc/types: N/A
    typescript: 5.1.6

SWC Config:
    output: N/A
    .swcrc path: N/A

Next.js info:
    output: N/A

Expected behavior

Jest when used with swc/jest should output the same data in the "statementMap" in the coverage-final.json file that's outputted for each shard so that nyc can merge the resulting coverage files.

Actual behavior

Notice how "statementMap" is different depending on the shard that produced the output. In shard 1 (the shard that actually got some coverage on the file in question), there are 4 lines of data in "statementMap"

    "statementMap": {
      "0": { "start": { "line": 4, "column": 13 }, "end": { "line": 4, "column": 24 } },
      "1": { "start": { "line": 1, "column": 26 }, "end": { "line": 1, "column": null } },
      "2": { "start": { "line": 2, "column": 25 }, "end": { "line": 2, "column": null } },
      "3": { "start": { "line": 4, "column": 24 }, "end": { "line": 4, "column": null } }
    },

In shard 2, which produced zero coverage for the file in question, there is only 1 line of data in "statementMap"

    "statementMap": {
      "0": { "start": { "line": 4, "column": 24 }, "end": { "line": 4, "column": 52 } }
    },

nyc does not know how to merge these:

    "statementMap": {
      "0": { "start": { "line": 4, "column": 24 }, "end": { "line": 4, "column": 52 } },
      "1": { "start": { "line": 4, "column": 13 }, "end": { "line": 4, "column": 24 } },
      "2": { "start": { "line": 1, "column": 26 }, "end": { "line": 1, "column": null } },
      "3": { "start": { "line": 2, "column": 25 }, "end": { "line": 2, "column": null } },
      "4": { "start": { "line": 4, "column": 24 }, "end": { "line": 4, "column": null } }
    },

instead of merging, we have two data items that refer to the same statement: "0" and "4"

Version

1.3.78

Additional context

I'm not sure if the column: null matters since ts-jest produces that in several other places in my complete coverage-final.json file, and coverage seems fine with it. The issue seems to arise when one shard produces a number for the column and the other shard produces a null.

@ghost ghost added the C-bug label Aug 31, 2023
@kwonoj
Copy link
Member

kwonoj commented Aug 31, 2023

This is really not possible to debug, first there's no minimal repro at all, and secondly it involves so many toolchains at once - jest, babel (for jest coverage), sharding, nyc to merge and lastly swc per claims.

If you think swc is a culprit to play here it's likely coming from incorrect coverage mapping which should be provided as a minimal repro doesn't involve other tools.

@kwonoj
Copy link
Member

kwonoj commented Sep 7, 2023

Closing as lacks of information.

@kwonoj kwonoj closed this as completed Sep 7, 2023
@swc-bot
Copy link
Collaborator

swc-bot commented Oct 8, 2023

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@swc-project swc-project locked as resolved and limited conversation to collaborators Oct 8, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

No branches or pull requests

3 participants