Open Xerillio opened 1 year ago
@Xerillio could you please provide a reproduction for this issue.
@bcoe You got it 😉
/package.json
:
{
"scripts": {
"test": "mocha -r ts-node/register './tests/**/*.test.ts'",
"coverage": "c8 npm test"
},
"devDependencies": {
"@types/chai": "^4.3.9",
"@types/mocha": "^10.0.3",
"c8": "^8.0.1",
"chai": "^4.3.10",
"mocha": "^10.2.0",
"ts-node": "^10.9.1",
"typescript": "^5.2.2"
}
}
/tsconfig.json
:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"esModuleInterop": true,
"strict": true
}
}
/.c8rc.json
:
{
"all": true,
"src": ["./src"],
"extension": [".ts"],
"report-dir": "./coverage"
}
/src/power.ts
:
import type { IPower } from "./ipower";
export class Power implements IPower {
calculate(base: number, exponent: number): number {
if (!Number.isInteger(exponent)) throw new Error("The exponent must be an integer");
let result = 1;
for (let i = 0; i < exponent; i++) {
result *= base;
}
return result;
}
}
/src/ipower.ts
:
export interface IPower {
calculate(base: number, exponent: number): number
}
/tests/power.test.ts
:
import { Power } from "../src/power";
import { expect } from "chai";
describe("Power", () => {
describe("#calculate", () => {
it("should return 1 when the exponent is 0", () => {
const sut = new Power();
const result = sut.calculate(9.876, 0);
expect(result).to.equal(1);
});
it("should throw when the exponent is not an integer", () => {
const sut = new Power();
expect(() => sut.calculate(9.876, 1.1)).to.throw(
Error,
"The exponent must be an integer");
});
});
});
Running coverage
then produces this result (0% for ipower.ts
):
$ npm run coverage
...
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-------------------
All files | 70.58 | 60 | 50 | 70.58 |
ipower.ts | 0 | 0 | 0 | 0 | 1-3
power.ts | 85.71 | 75 | 100 | 85.71 | 9-10
-----------|---------|----------|---------|---------|-------------------
Funny thing I noticed now because I didn't add tests for 100% coverage... if you move the contents of ipower.ts
into power.ts
the coverage of power.ts
is strangely enough higher than before:
$ npm run coverage
...
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 87.5 | 75 | 100 | 87.5 |
power.ts | 87.5 | 75 | 100 | 87.5 | 7-8
----------|---------|----------|---------|---------|-------------------
Is there news about this issue?
I encounter this too on a regular basis.
My go-to solution for now is to put my interfaces in one directory and then exclude that whole directory:
- src/
- interfaces/
- widget.ts
- classes/
- WidgetFactory.ts
- test/
- WidgetFactory.suite.ts
- .c8rc.yaml
{
"all": true,
"src": "./src",
"exclude": [
"interfaces/"
]
}
Or, if you prefer to co-locate your tests and interfaces, you could use file extensions:
- src/
- widgets/
- widget.interface.ts
- WidgetFactory.spec.ts
- WidgetFactory.ts
- .c8rc.yaml
{
"all": true,
"src": "./src",
"exclude": [
"**/*.interface.ts",
"**/*.spec.ts"
]
}
However, both of these share the problem that it's possible to end up with uncovered code if someone accidentally (or intentionally) puts something other than an interface in that directory/file. So, I'd love to see a solution that could somehow recognize and ignore these files automatically.
@jftanner could please give One Double Zero a try?
https://www.npmjs.com/package/one-double-zero?activeTab=readme
@jftanner could please give One Double Zero a try?
No offense, but I'm not interested in switching to such a new tool. A large part of security in open source comes from having many eyes looking at it. At 11 downloads per week, your tool isn't there yet.
That makes no sense right? How can a tool get downloads if you don't download it because it doesn't have downloads.
It solves your issue. It is fully tested. It is open source. What you want more?
I'm running
c8
usingmocha
withts-node/register
and I'm wondering if that might cause the issue. Essentially, I have a filetask-result.ts
that only contains aITaskResult
interface. This is used fromtask-runner.ts
(import { ITaskResult } from "./task-result"
). I have tests with 100% coverage fortask-runner.ts
, but using the--all
flag,c8
reports 0% coverage fortask-result.ts
.If I move the interface into
task-runner.ts
instead,task-runner.ts
still reports 100% coverage as expected.Is this an artefact from TS interfaces not being transpiled to JS and/or related to the same underlying issue in #182? Or is there a way to solve it while keeping the interface in its own file (I'd prefer not having to exclude individual files like this)?
If necessary, I can create a small example to reproduce it.