Skip to content

Commit d2f13f6

Browse files
authored
fix(msp): add files to results of discover and mutationTest (#7)
Add `files` to both `discover` and `mutationTest` results, inspired by the report-schema. I've also reworked the readme to be more consistent: - removed arbitrary `export` and `readonly` keywords - consistently use `type` instead of `interface`
1 parent 712997c commit d2f13f6

File tree

3 files changed

+129
-33
lines changed

3 files changed

+129
-33
lines changed

packages/mutation-server-protocol/README.md

+60-17
Original file line numberDiff line numberDiff line change
@@ -89,23 +89,42 @@ The `discover` method is used to discover mutants in the given file paths. The s
8989
The `DiscoveredMutant` type is a subset of the `MutantResult` type. The `MutantResult` is the type that can be found in the [mutation testing report schema](https://github.com/stryker-mutator/mutation-testing-elements/blob/2902d56301cfdaa8ad2be59f3bca07bdf96f89b4/packages/report-schema/src/mutation-testing-report-schema.json#L37).
9090

9191
```ts
92-
export interface DiscoverParams {
92+
type DiscoverParams = {
9393
/**
9494
* The files to run discovery on, or undefined to discover all files in the current project.
9595
* A file ending with a `/` indicates a directory. Each path can specify exactly which code blocks to mutate/discover using a mutation range.
9696
* This can be done by postfixing your file with `:startLine[:startColumn]-endLine[:endColumn]`.
9797
*/
9898
files?: string[];
99-
}
100-
101-
type DiscoveredMutant = Pick<
102-
schema.MutantResult,
103-
'id' | 'location' | 'description' | 'mutatorName' | 'replacement'
104-
>;
105-
106-
export interface DiscoverResult {
107-
mutants: readonly DiscoveredMutant[];
108-
}
99+
};
100+
101+
type DiscoverResult = {
102+
files: DiscoveredFiles;
103+
};
104+
105+
type DiscoveredFiles = Record<string, DiscoveredFile>;
106+
107+
type DiscoveredFile = {
108+
mutants: DiscoveredMutant[];
109+
};
110+
111+
type DiscoveredMutant = {
112+
id: string;
113+
location: Location;
114+
description?: string;
115+
mutatorName: string;
116+
replacement?: string;
117+
};
118+
119+
type Location = {
120+
start: Position;
121+
end: Position;
122+
};
123+
124+
type Position = {
125+
line: number;
126+
column: number;
127+
};
109128
```
110129

111130
#### MutationTest
@@ -118,18 +137,42 @@ Whenever a partial result is in, the server is expected to send a `reportMutatio
118137
> The MutantResult should adhere to the [mutation testing report schema](https://github.com/stryker-mutator/mutation-testing-elements/blob/2902d56301cfdaa8ad2be59f3bca07bdf96f89b4/packages/report-schema/src/mutation-testing-report-schema.json#L37)
119138
120139
```ts
121-
export interface MutationTestParams {
140+
type MutationTestParams = {
122141
/**
123142
* The files to run mutation testing on, or undefined to run mutation testing on all files in the current project.
124143
* A file ending with a `/` indicates a directory. Each path can specify exactly which code blocks to mutate/discover using a mutation range.
125144
* This can be done by postfixing your file with `:startLine[:startColumn]-endLine[:endColumn]`.
126145
*/
127146
files?: string[];
128-
}
129-
130-
export interface MutationTestResult {
131-
mutants: schema.MutantResult[];
132-
}
147+
};
148+
149+
type MutationTestResult = {
150+
files: MutantResultFiles;
151+
};
152+
153+
type MutantResultFiles = Record<string, MutantResultFile>;
154+
155+
type MutantResultFile = {
156+
mutants: MutantResult[];
157+
};
158+
159+
type MutantResult = DiscoveredMutant & {
160+
coveredBy?: string[];
161+
duration?: number;
162+
killedBy?: string[];
163+
static?: boolean;
164+
status: MutantStatus;
165+
statusReason?: string;
166+
testsCompleted?: number;
167+
};
168+
169+
type MutantStatus =
170+
| 'Killed'
171+
| 'Survived'
172+
| 'NoCoverage'
173+
| 'Timeout'
174+
| 'CompileError'
175+
| 'RuntimeError';
133176
```
134177

135178
### Error messages

packages/mutation-server-protocol/src/schema.spec.ts

+48-14
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,39 @@ describe('Schema', () => {
4040
}
4141

4242
describe('DiscoverResult', () => {
43-
it('should have a mutants field', () => {
44-
DiscoverResult.parse({ mutants: [] });
43+
it('should have a files field', () => {
44+
DiscoverResult.parse({ files: {} });
4545
});
46+
47+
it('should allow an arbitrary amount of files', () => {
48+
DiscoverResult.parse({
49+
files: {
50+
'src/index.ts': {
51+
mutants: [],
52+
},
53+
'src/foo.ts': {
54+
mutants: [],
55+
},
56+
},
57+
});
58+
});
59+
4660
it('should allow an array of DiscoveredMutants', () => {
4761
DiscoverResult.parse({
48-
mutants: [
49-
{
50-
id: '1',
51-
location: {
52-
start: { line: 1, column: 1 },
53-
end: { line: 1, column: 1 },
54-
},
55-
mutatorName: 'foo',
62+
files: {
63+
'src/index.ts': {
64+
mutants: [
65+
{
66+
id: '1',
67+
location: {
68+
start: { line: 1, column: 1 },
69+
end: { line: 1, column: 1 },
70+
},
71+
mutatorName: 'foo',
72+
},
73+
],
5674
},
57-
],
75+
},
5876
});
5977
});
6078
it('should throw if the mutants array is missing', () => {
@@ -204,12 +222,28 @@ describe('Schema', () => {
204222
});
205223
});
206224
describe('MutationTestResult', () => {
207-
it('should parse an empty array', () => {
208-
MutationTestResult.parse({ mutants: [] });
225+
it('should parse empty files', () => {
226+
MutationTestResult.parse({ files: {} });
227+
});
228+
it('should parse an arbitrary amount of files', () => {
229+
MutationTestResult.parse({
230+
files: {
231+
'src/foo.ts': {
232+
mutants: [],
233+
},
234+
'src/bar.ts': {
235+
mutants: [],
236+
},
237+
},
238+
});
209239
});
210240
it('should parse an array of MutantResults', () => {
211241
MutationTestResult.parse({
212-
mutants: [validMinimalMutantResult()],
242+
files: {
243+
'src/index.ts': {
244+
mutants: [validMinimalMutantResult()],
245+
},
246+
},
213247
});
214248
});
215249
it('should throw if mutants is missing', () => {

packages/mutation-server-protocol/src/schema.ts

+21-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
enum as enum_,
1010
type z,
1111
boolean,
12+
record,
1213
} from 'zod';
1314

1415
export const ConfigureParams = object({
@@ -60,8 +61,18 @@ export const DiscoveredMutant = object({
6061
replacement: string().optional(),
6162
});
6263

64+
export type DiscoveredMutant = z.infer<typeof DiscoveredMutant>;
65+
66+
export const DiscoveredFile = object({ mutants: array(DiscoveredMutant) });
67+
68+
export type DiscoveredFile = z.infer<typeof DiscoveredFile>;
69+
70+
export const DiscoveredFiles = record(string(), DiscoveredFile);
71+
72+
export type DiscoveredFiles = z.infer<typeof DiscoveredFiles>;
73+
6374
export const DiscoverResult = object({
64-
mutants: array(DiscoveredMutant),
75+
files: DiscoveredFiles,
6576
});
6677

6778
export type DiscoverResult = z.infer<typeof DiscoverResult>;
@@ -123,8 +134,16 @@ export const MutantResult = DiscoveredMutant.extend({
123134

124135
export type MutantResult = z.infer<typeof MutantResult>;
125136

137+
export const MutantResultFile = object({ mutants: array(MutantResult) });
138+
139+
export type MutantResultFile = z.infer<typeof MutantResultFile>;
140+
141+
export const MutationResultFiles = record(string(), MutantResultFile);
142+
143+
export type MutationResultFiles = z.infer<typeof MutationResultFiles>;
144+
126145
export const MutationTestResult = object({
127-
mutants: array(MutantResult),
146+
files: MutationResultFiles,
128147
});
129148

130149
export type MutationTestResult = z.infer<typeof MutationTestResult>;

0 commit comments

Comments
 (0)