-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
22 changed files
with
385 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import type { | ||
AggregatedResultMetadata, | ||
DescribeBlockMetadata, | ||
RunMetadata, | ||
TestEntryMetadata, | ||
TestFnInvocationMetadata, | ||
TestInvocationMetadata, | ||
} from 'jest-metadata'; | ||
|
||
import { PREFIX } from '../constants'; | ||
|
||
import { chain, extractCode, getStart, getStop } from './utils'; | ||
import type { AllureTestCaseMetadata } from './metadata'; | ||
|
||
export class MetadataSquasher { | ||
protected readonly testInvocationConfig: MetadataSquasherConfig<AllureTestCaseMetadata>; | ||
|
||
constructor(flat: boolean) { | ||
this.testInvocationConfig = flat | ||
? MetadataSquasher.flatConfig() | ||
: MetadataSquasher.deepConfig(); | ||
} | ||
|
||
testInvocation(metadata: TestInvocationMetadata): AllureTestCaseMetadata { | ||
const config = this.testInvocationConfig as any; | ||
const keys = Object.keys(config) as (keyof AllureTestCaseMetadata)[]; | ||
const result: Partial<AllureTestCaseMetadata> = {}; | ||
const context = { | ||
aggregatedResult: metadata.entry.describeBlock.run.aggregatedResult, | ||
run: metadata.entry.describeBlock.run, | ||
describeBlock: [...metadata.entry.ancestors()], | ||
testEntry: metadata.entry, | ||
testInvocation: metadata, | ||
testFnInvocation: metadata.fn, | ||
}; | ||
|
||
for (const key of keys) { | ||
result[key] = config[key](context, key); | ||
} | ||
|
||
return result as AllureTestCaseMetadata; | ||
} | ||
|
||
private static flatConfig(): MetadataSquasherConfig<AllureTestCaseMetadata> { | ||
return { | ||
code: extractCode, | ||
workerId: ({ run }) => run?.get([PREFIX, 'workerId']) as string, | ||
description: chain(['testEntry', 'testInvocation', 'testFnInvocation']), | ||
descriptionHtml: chain([ | ||
'testEntry', | ||
'testInvocation', | ||
'testFnInvocation', | ||
]), | ||
attachments: chain(['testEntry', 'testInvocation', 'testFnInvocation']), | ||
parameters: chain(['testEntry', 'testInvocation', 'testFnInvocation']), | ||
labels: chain([ | ||
'aggregatedResult', | ||
'run', | ||
'describeBlock', | ||
'testEntry', | ||
'testInvocation', | ||
'testFnInvocation', | ||
]), | ||
links: chain([ | ||
'aggregatedResult', | ||
'run', | ||
'describeBlock', | ||
'testEntry', | ||
'testInvocation', | ||
'testFnInvocation', | ||
]), | ||
start: getStart, | ||
stop: getStop, | ||
}; | ||
} | ||
|
||
private static deepConfig(): MetadataSquasherConfig<AllureTestCaseMetadata> { | ||
return { | ||
...this.flatConfig(), | ||
attachments: chain(['testEntry', 'testInvocation']), | ||
parameters: chain(['testEntry', 'testInvocation']), | ||
}; | ||
} | ||
} | ||
|
||
export type MetadataSquasherConfig<T extends object> = { | ||
[K in keyof T]: MetadataSquasherMapping<T, K>; | ||
}; | ||
|
||
export type MetadataSquasherMapping<T, K extends keyof T = keyof T> = ( | ||
context: MetadataSquasherContext, | ||
key: K, | ||
) => T[K]; | ||
|
||
export type MetadataSquasherContext = Partial<{ | ||
aggregatedResult: AggregatedResultMetadata; | ||
run: RunMetadata; | ||
describeBlock: DescribeBlockMetadata[]; | ||
testEntry: TestEntryMetadata; | ||
testInvocation: TestInvocationMetadata; | ||
testFnInvocation: TestFnInvocationMetadata; | ||
}>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import type { | ||
HookInvocationMetadata, | ||
TestFnInvocationMetadata, | ||
} from 'jest-metadata'; | ||
|
||
import { PREFIX } from '../constants'; | ||
|
||
import type { AllureTestStepMetadata } from './metadata'; | ||
|
||
export class StepExtractor { | ||
constructor(protected readonly flat: boolean) {} | ||
|
||
public extractFromHook( | ||
metadata: HookInvocationMetadata, | ||
): AllureTestStepMetadata { | ||
const data = { | ||
name: metadata.definition.hookType, | ||
...(metadata.get([PREFIX]) as AllureTestStepMetadata), | ||
}; | ||
|
||
if (this.flat) { | ||
delete data.attachments; | ||
delete data.parameters; | ||
} | ||
|
||
return data; | ||
} | ||
|
||
public extractFromTestFn( | ||
metadata: TestFnInvocationMetadata, | ||
): AllureTestStepMetadata { | ||
const data = { | ||
name: 'test', | ||
...(metadata.get([PREFIX]) as AllureTestStepMetadata), | ||
}; | ||
|
||
if (this.flat) { | ||
delete data.attachments; | ||
delete data.parameters; | ||
} | ||
|
||
return data; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from './metadata'; | ||
export * from './MetadataSquasher'; | ||
export * from './StepExtractor'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import type { Metadata } from 'jest-metadata'; | ||
|
||
import { PREFIX } from '../../constants'; | ||
import type { | ||
MetadataSquasherContext, | ||
MetadataSquasherMapping, | ||
} from '../MetadataSquasher'; | ||
|
||
export function chain<T extends object, K extends keyof T>( | ||
sources: (keyof MetadataSquasherContext)[], | ||
): MetadataSquasherMapping<T, K> { | ||
return (context: MetadataSquasherContext, key: K) => { | ||
const path = [PREFIX, key as string]; | ||
const metadatas: Metadata[] = sources.flatMap((sourceName) => { | ||
const value: Metadata | Metadata[] | undefined = context[sourceName]; | ||
if (!value) return []; | ||
return Array.isArray(value) ? value : [value]; | ||
}); | ||
|
||
return metadatas.flatMap((metadata) => metadata.get(path, [])) as T[K]; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import type { HookInvocationMetadata } from 'jest-metadata'; | ||
import type { Metadata } from 'jest-metadata'; | ||
|
||
import type { MetadataSquasherMapping } from '../MetadataSquasher'; | ||
import type { AllureTestCaseMetadata } from '../metadata'; | ||
|
||
export const extractCode: MetadataSquasherMapping< | ||
AllureTestCaseMetadata, | ||
'code' | ||
> = ({ testInvocation }) => { | ||
if (!testInvocation) return []; | ||
|
||
const getHookDefinition = (metadata: HookInvocationMetadata) => | ||
metadata.definition; | ||
const getCode = (functionName: string) => (metadata: Metadata) => { | ||
const code = metadata.get(['allure2', 'code']); | ||
return code ? `${functionName}(${code})` : ''; | ||
}; | ||
|
||
return [ | ||
...testInvocation.beforeAll | ||
.map(getHookDefinition) | ||
.map(getCode('beforeAll')), | ||
...testInvocation.before.map(getHookDefinition).map(getCode('beforeEach')), | ||
getCode('test')(testInvocation.entry), | ||
...testInvocation.after.map(getHookDefinition).map(getCode('afterEach')), | ||
...testInvocation.afterAll.map(getHookDefinition).map(getCode('afterAll')), | ||
].filter(Boolean); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import type { MetadataSquasherMapping } from '../MetadataSquasher'; | ||
import type { AllureTestCaseMetadata } from '../metadata'; | ||
|
||
export const getStart: MetadataSquasherMapping< | ||
AllureTestCaseMetadata, | ||
'start' | ||
> = ({ testEntry, testInvocation }) => { | ||
const first = | ||
(testInvocation && | ||
(testInvocation.beforeAll[0] ?? | ||
testInvocation.before[0] ?? | ||
testInvocation.fn)) ?? | ||
testEntry; | ||
|
||
return (first?.get(['allure2', 'start']) as number) ?? Number.NaN; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import type { MetadataSquasherMapping } from '../MetadataSquasher'; | ||
import type { AllureTestCaseMetadata } from '../metadata'; | ||
import { PREFIX } from '../../constants'; | ||
|
||
export const getStop: MetadataSquasherMapping< | ||
AllureTestCaseMetadata, | ||
'stop' | ||
> = ({ testEntry, testInvocation }) => { | ||
const last = | ||
(testInvocation && | ||
(testInvocation.afterAll.at(-1) ?? | ||
testInvocation.after.at(-1) ?? | ||
testInvocation.fn)) ?? | ||
testEntry; | ||
|
||
const stop: number = (last?.get([PREFIX, 'stop']) as number); | ||
return stop; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export * from './chain'; | ||
export * from './extractCode'; | ||
export * from './getStart'; | ||
export * from './getStop'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.