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

feat(schema): add Pending status to JSON schema #2425

Merged
merged 14 commits into from
Apr 14, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/elements/src/components/file/file.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ export class FileComponent extends LitElement {
MutantStatus.Timeout,
MutantStatus.CompileError,
MutantStatus.RuntimeError,
MutantStatus.Pending,
]
.filter((status) => this.model.mutants.some((mutant) => mutant.status === status))
.map((status) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ const COLUMNS: Column<Metrics>[] = [
{
key: 'totalMutants',
label: 'Total',
tooltip: 'All mutants (valid + invalid + ignored)',
tooltip: 'All mutants (valid + invalid + ignored + pending)',
rouke-broersma marked this conversation as resolved.
Show resolved Hide resolved
category: 'number',
width: 'large',
isBold: true,
Expand Down
3 changes: 3 additions & 0 deletions packages/elements/src/lib/html-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export function getContextClassForStatus(status: MutantStatus) {
return 'warning';
case MutantStatus.Ignored:
case MutantStatus.RuntimeError:
case MutantStatus.Pending: // For now
rouke-broersma marked this conversation as resolved.
Show resolved Hide resolved
case MutantStatus.CompileError:
return 'secondary';
}
Expand Down Expand Up @@ -81,6 +82,8 @@ export function getEmojiForStatus(status: MutantStatus) {
case MutantStatus.Survived:
return renderEmoji('👽', status);
case MutantStatus.Timeout:
return renderEmoji('⏰', status);
rouke-broersma marked this conversation as resolved.
Show resolved Hide resolved
case MutantStatus.Pending:
return renderEmoji('⌛', status);
case MutantStatus.RuntimeError:
case MutantStatus.CompileError:
Expand Down
1 change: 1 addition & 0 deletions packages/elements/test/helpers/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export function createTestMetrics(overrides?: TestMetrics): TestMetrics {

export function createMetrics(overrides?: Metrics): Metrics {
const defaults: Metrics = {
pending: 0,
killed: 0,
survived: 0,
timeout: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ describe(MutationTestReportMutantViewComponent.name, () => {
{
key: 'totalMutants',
label: 'Total',
tooltip: 'All mutants (valid + invalid + ignored)',
tooltip: 'All mutants (valid + invalid + ignored + pending)',
category: 'number',
width: 'large',
isBold: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe(FileStateFilterComponent.name, () => {
'👽 Survived (1)',
'🙈 NoCoverage (1)',
'🤥 Ignored (1)',
' Timeout (1)',
' Timeout (1)',
'💥 CompileError (1)',
'💥 RuntimeError (1)',
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ object circe {
case MutantStatus.CompileError => "CompileError"
case MutantStatus.RuntimeError => "RuntimeError"
case MutantStatus.Ignored => "Ignored"
case MutantStatus.Pending => "Pending"
})

implicit lazy val testDefinitionCodec: Codec[TestDefinition] =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package mutationtesting

sealed trait MetricsResult {
/** The total number of mutants that are pending, meaning that they have been generated but not yet run.
*/
def pending: Int

/** At least one test failed while this mutant was active. The mutant is killed. This is what you want, good job!
*/
Expand Down Expand Up @@ -59,7 +62,7 @@ sealed trait MetricsResult {

/** All mutants.
*/
lazy val totalMutants: Int = totalValid + totalInvalid + ignored
lazy val totalMutants: Int = totalValid + totalInvalid + ignored + pending
rouke-broersma marked this conversation as resolved.
Show resolved Hide resolved

/** The total percentage of mutants that were killed. Or a {{Double.NaN}} if there are no mutants.
*/
Expand All @@ -75,6 +78,7 @@ sealed trait MetricsResult {
sealed trait DirOps extends MetricsResult {
val files: Iterable[MetricsResult]

override lazy val pending: Int = sumOfChildrenWith(_.pending)
override lazy val killed: Int = sumOfChildrenWith(_.killed)
override lazy val timeout: Int = sumOfChildrenWith(_.timeout)
override lazy val survived: Int = sumOfChildrenWith(_.survived)
Expand All @@ -91,6 +95,7 @@ sealed trait DirOps extends MetricsResult {
sealed trait FileOps extends MetricsResult {
val mutants: Iterable[MetricMutant]

override lazy val pending: Int = countWhere(MutantStatus.Pending)
override lazy val killed: Int = countWhere(MutantStatus.Killed)
override lazy val timeout: Int = countWhere(MutantStatus.Timeout)
override lazy val survived: Int = countWhere(MutantStatus.Survived)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ object MutantStatus {
case object CompileError extends MutantStatus
case object RuntimeError extends MutantStatus
case object Ignored extends MutantStatus
case object Pending extends MutantStatus

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ class MetricsResultTest extends munit.FunSuite {
test("all should be 0 on empty root") {
val sut = MetricsResultRoot(Nil)

assertEquals(sut.pending, 0)
assertEquals(sut.killed, 0)
assertEquals(sut.survived, 0)
assertEquals(sut.timeout, 0)
Expand Down Expand Up @@ -31,6 +32,7 @@ class MetricsResultTest extends munit.FunSuite {
}

private lazy val expectedSet: List[(String, MetricsResult => Number, Number)] = List(
("pending", _.pending, 1),
("killed", _.killed, 2),
("survived", _.survived, 2),
("timeout", _.timeout, 2),
Expand All @@ -43,7 +45,7 @@ class MetricsResultTest extends munit.FunSuite {
("totalCovered", _.totalCovered, 6),
("totalValid", _.totalValid, 9),
("totalInvalid", _.totalInvalid, 2),
("totalMutants", _.totalMutants, 12),
("totalMutants", _.totalMutants, 13),
("mutationScore", _.mutationScore, (4d / 9d) * 100),
(
"mutationScoreBasedOnCoveredCode",
Expand All @@ -60,6 +62,7 @@ class MetricsResultTest extends munit.FunSuite {
MetricsFile(
"bar.scala",
List(
MetricMutant(MutantStatus.Pending),
MetricMutant(MutantStatus.Killed),
MetricMutant(MutantStatus.Killed),
MetricMutant(MutantStatus.Survived),
Expand Down
4 changes: 3 additions & 1 deletion packages/metrics/src/calculateMetrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ function countTestFileMetrics(testFile: TestFileModel[]): TestMetrics {
function countFileMetrics(fileResult: FileUnderTestModel[]): Metrics {
const mutants = fileResult.flatMap((_) => _.mutants);
const count = (status: MutantStatus) => mutants.filter((_) => _.status === status).length;
const pending = count(MutantStatus.Pending);
const killed = count(MutantStatus.Killed);
const timeout = count(MutantStatus.Timeout);
const survived = count(MutantStatus.Survived);
Expand All @@ -155,6 +156,7 @@ function countFileMetrics(fileResult: FileUnderTestModel[]): Metrics {
const totalValid = totalUndetected + totalDetected;
const totalInvalid = runtimeErrors + compileErrors;
return {
pending,
killed,
timeout,
survived,
Expand All @@ -168,7 +170,7 @@ function countFileMetrics(fileResult: FileUnderTestModel[]): Metrics {
totalValid,
totalInvalid,
mutationScore: totalValid > 0 ? (totalDetected / totalValid) * 100 : DEFAULT_SCORE,
totalMutants: totalValid + totalInvalid + ignored,
totalMutants: totalValid + totalInvalid + ignored + pending,
rouke-broersma marked this conversation as resolved.
Show resolved Hide resolved
mutationScoreBasedOnCoveredCode: totalValid > 0 ? (totalDetected / totalCovered) * 100 || 0 : DEFAULT_SCORE,
};
}
4 changes: 4 additions & 0 deletions packages/metrics/src/model/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
* Container for the metrics of mutation testing
*/
export interface Metrics {
/**
* The total number of mutants that are pending, meaning that they have been generated but not yet run
*/
pending: number;
/**
* The total number of mutants that were killed
*/
Expand Down
4 changes: 3 additions & 1 deletion packages/metrics/test/unit/calculateMetrics.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ describe(calculateMetrics.name, () => {
const input: FileResultDictionary = {
'foo.js': createFileResult({
mutants: [
createMutantResult({ status: MutantStatus.Pending }),
createMutantResult({ status: MutantStatus.RuntimeError }),
createMutantResult({ status: MutantStatus.Killed }),
createMutantResult({ status: MutantStatus.CompileError }),
Expand All @@ -144,6 +145,7 @@ describe(calculateMetrics.name, () => {
const actual = calculateMetrics(input);

// Assert
expect(actual.metrics.pending, 'pending').to.eq(1);
expect(actual.metrics.killed, 'killed').to.eq(2);
expect(actual.metrics.compileErrors, 'compileErrors').eq(1);
expect(actual.metrics.runtimeErrors, 'runtimeErrors').eq(1);
Expand All @@ -153,7 +155,7 @@ describe(calculateMetrics.name, () => {
expect(actual.metrics.noCoverage, 'ignored').to.eq(1);
expect(actual.metrics.totalCovered, 'totalCovered').to.eq(4);
expect(actual.metrics.totalDetected, 'detected').to.eq(3);
expect(actual.metrics.totalMutants, 'mutants').to.eq(8);
expect(actual.metrics.totalMutants, 'mutants').to.eq(9);
expect(actual.metrics.totalValid, 'mutants').to.eq(5);
expect(actual.metrics.totalInvalid, 'mutants').to.eq(2);
expect(actual.metrics.totalUndetected, 'undetected').to.eq(2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
"type": "string",
"title": "MutantStatus",
"description": "Result of the mutation.",
"enum": ["Killed", "Survived", "NoCoverage", "CompileError", "RuntimeError", "Timeout", "Ignored"]
"enum": ["Killed", "Survived", "NoCoverage", "CompileError", "RuntimeError", "Timeout", "Ignored", "Pending"]
},
"statusReason": {
"type": "string",
Expand Down