-
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
30 changed files
with
1,121 additions
and
41 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,35 @@ | ||
import fs from 'node:fs/promises'; | ||
import path from 'node:path'; | ||
|
||
import type { KeyedHelperCustomizer } from 'jest-allure2-reporter'; | ||
|
||
import { FileNavigator } from '../../../utils'; | ||
|
||
class FileNavigatorCache { | ||
#cache = new Map<string, Promise<FileNavigator>>(); | ||
|
||
resolve(filePath: string): Promise<FileNavigator> { | ||
const absolutePath = path.resolve(filePath); | ||
if (!this.#cache.has(absolutePath)) { | ||
this.#cache.set(absolutePath, this.#createNavigator(absolutePath)); | ||
} | ||
|
||
return this.#cache.get(absolutePath)!; | ||
} | ||
|
||
#createNavigator = async (filePath: string) => { | ||
const sourceCode = await fs.readFile(filePath, 'utf8').catch(() => ''); | ||
return new FileNavigator(sourceCode); | ||
}; | ||
|
||
clear() { | ||
this.#cache.clear(); | ||
} | ||
|
||
static readonly instance = new FileNavigatorCache(); | ||
} | ||
|
||
export const getFileNavigator: KeyedHelperCustomizer<'getFileNavigator'> = () => { | ||
const cache = new FileNavigatorCache(); | ||
return (filePath) => cache.resolve(filePath); | ||
}; |
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 @@ | ||
export * from './getFileNavigator'; |
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 |
---|---|---|
@@ -1,14 +1,6 @@ | ||
import type { ExtractSourceCodeHelper } from 'jest-allure2-reporter'; | ||
|
||
export { getFileNavigator } from './file-navigator'; | ||
export { getExecutorInfo } from './executor'; | ||
export { manifest } from './manifest'; | ||
export { markdown2html } from './markdown'; | ||
export { extractSourceCode, source2markdown } from './source-code'; | ||
export { stripAnsi } from './strip-ansi'; | ||
|
||
export const extractSourceCode = | ||
(): ExtractSourceCodeHelper => | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
(_: unknown, recursive?: true): any => | ||
recursive ? [] : void 0; | ||
|
||
export const source2markdown = () => () => ''; |
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,65 @@ | ||
import type { | ||
AllureTestItemMetadata, | ||
AllureNestedTestStepMetadata, | ||
ExtractSourceCodeHelperResult, | ||
KeyedHelperCustomizer, | ||
} from 'jest-allure2-reporter'; | ||
|
||
import { log } from '../../../logger'; | ||
import { compactArray } from '../../../utils'; | ||
|
||
export const extractSourceCode: KeyedHelperCustomizer<'extractSourceCode'> = ({ config }): any => { | ||
async function extractRecursively( | ||
item: AllureTestItemMetadata, | ||
): Promise<ExtractSourceCodeHelperResult[]> { | ||
const steps = item.steps || []; | ||
const before = steps.filter(isBefore); | ||
const after = steps.filter(isAfter); | ||
const data = [...before, item, ...after]; | ||
const result = await Promise.all(data.map(extractSingle)); | ||
return compactArray(result); | ||
} | ||
|
||
async function extractSingle( | ||
item: AllureTestItemMetadata, | ||
): Promise<ExtractSourceCodeHelperResult | undefined> { | ||
let code: string | undefined; | ||
const sourceLocation = item.sourceLocation; | ||
if (config.sourceCode?.enabled && sourceLocation) { | ||
for (const p of config.sourceCode.plugins) { | ||
try { | ||
code = await p.extractSourceCode?.(sourceLocation); | ||
} catch (error: unknown) { | ||
log.warn( | ||
error, | ||
`Failed to extract source code for ${sourceLocation.fileName}:${sourceLocation.lineNumber}:${sourceLocation.columnNumber}`, | ||
); | ||
} | ||
if (code) { | ||
break; | ||
} | ||
} | ||
} | ||
|
||
return code && sourceLocation | ||
? { | ||
code, | ||
language: 'typescript', | ||
fileName: sourceLocation.fileName!, | ||
lineNumber: sourceLocation.lineNumber!, | ||
columnNumber: sourceLocation.columnNumber!, | ||
} | ||
: undefined; | ||
} | ||
|
||
return (item: AllureTestItemMetadata, recursive: boolean) => | ||
recursive ? extractRecursively(item) : extractSingle(item); | ||
}; | ||
|
||
function isBefore(step: AllureNestedTestStepMetadata): boolean { | ||
return step.hookType === 'beforeAll' || step.hookType === 'beforeEach'; | ||
} | ||
|
||
function isAfter(step: AllureNestedTestStepMetadata): boolean { | ||
return step.hookType === 'afterAll' || step.hookType === 'afterEach'; | ||
} |
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,2 @@ | ||
export { extractSourceCode } from './extractSourceCode'; | ||
export { source2markdown } from './source2markdown'; |
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,11 @@ | ||
import type { KeyedHelperCustomizer } from 'jest-allure2-reporter'; | ||
|
||
const FENCE = '```'; | ||
|
||
export const source2markdown: KeyedHelperCustomizer<'source2markdown'> = () => (item) => { | ||
if (!item || !item.code) return ''; | ||
const language = item.language || ''; | ||
const title = item.fileName ? ` title="${item.fileName}"` : ''; | ||
// this snippet also includes file name to work with Markdown plugin | ||
return `${FENCE}${language}${title}\n${item.code}\n${FENCE}`; | ||
}; |
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,48 @@ | ||
import type { FileNavigator } from 'jest-allure2-reporter'; | ||
|
||
export function extractCoffeeBlock( | ||
coffee: any, | ||
navigator: FileNavigator, | ||
testLineIndex: number, | ||
): string { | ||
if (testLineIndex > navigator.getLineCount()) return ''; | ||
|
||
let currentLineIndex = testLineIndex - 2; | ||
if (currentLineIndex < 0) return ''; | ||
|
||
if (!navigator.jump(currentLineIndex + 1)) return ''; | ||
let currentLine = navigator.readLine(); | ||
|
||
const docblockEndIndex = currentLine.indexOf('###'); | ||
if (docblockEndIndex === -1) return ''; | ||
|
||
const docblockSignature = currentLine.slice(0, docblockEndIndex + 1); | ||
if (docblockSignature.trimStart() !== '#') return ''; | ||
|
||
const commentBoundary = currentLine.slice(0, docblockEndIndex + 3); | ||
const docblockStart = commentBoundary + '*'; | ||
const buffer = []; | ||
|
||
buffer.unshift(commentBoundary.trimStart()); | ||
while (currentLineIndex >= 0) { | ||
if (!navigator.moveUp()) break; | ||
currentLineIndex--; | ||
currentLine = navigator.readLine(); | ||
|
||
if (!currentLine.startsWith(docblockSignature)) { | ||
break; | ||
} | ||
|
||
buffer.unshift(currentLine.trimStart()); | ||
|
||
if (currentLine.startsWith(docblockStart)) { | ||
return coffee.compile(buffer.join('\n'), { bare: true }); | ||
} | ||
|
||
if (currentLine.startsWith(commentBoundary)) { | ||
break; | ||
} | ||
} | ||
|
||
return ''; | ||
} |
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,24 @@ | ||
import type { SourceCodePluginCustomizer } from 'jest-allure2-reporter'; | ||
import { parseWithComments } from 'jest-docblock'; | ||
|
||
import { importDefault } from '../../utils'; | ||
|
||
import { extractCoffeeBlock } from './extractCoffeeBlock'; | ||
|
||
export const coffee: SourceCodePluginCustomizer = async ({ $ }) => { | ||
const coffee = await importDefault('coffeescript').catch(() => null); | ||
if (!coffee) return {}; | ||
|
||
return { | ||
extractDocblock({ fileName, lineNumber }) { | ||
if (fileName && lineNumber && fileName.endsWith('.coffee')) { | ||
return $.getFileNavigator(fileName).then((navigator) => { | ||
const docblock = extractCoffeeBlock(coffee, navigator, lineNumber); | ||
return docblock ? parseWithComments(docblock) : undefined; | ||
}); | ||
} | ||
|
||
return; | ||
}, | ||
}; | ||
}; |
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 './coffeescript'; | ||
export * from './javascript'; | ||
export * from './typescript'; |
23 changes: 23 additions & 0 deletions
23
src/source-code/javascript/__snapshots__/extractJsdocAbove.test.ts.snap
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,23 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`extractJsDoc should extract a broken docblock 1`] = ` | ||
"/** | ||
* This is a broken docblock | ||
* but it's still a docblock | ||
*/" | ||
`; | ||
|
||
exports[`extractJsDoc should extract a multiline docblock 1`] = ` | ||
"/** | ||
* This is a multiline docblock | ||
*/" | ||
`; | ||
|
||
exports[`extractJsDoc should extract a single line docblock 1`] = `" /** This is a single line docblock */"`; | ||
|
||
exports[`extractJsDoc should extract a weird two-line docblock 1`] = ` | ||
"/** | ||
* This is a weird two-line docblock */" | ||
`; | ||
|
||
exports[`extractJsDoc should not extract a non-docblock 1`] = `""`; |
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,41 @@ | ||
import { FileNavigator } from '../../utils'; | ||
|
||
import { extractDocblockAbove as extractJsDocument_ } from './extractDocblockAbove'; | ||
|
||
const FIXTURES = [ | ||
`\ | ||
/** | ||
* This is a multiline docblock | ||
*/`, | ||
' /** This is a single line docblock */', | ||
`/** | ||
* This is a broken docblock | ||
* but it's still a docblock | ||
*/`, | ||
`/** | ||
* This is a weird two-line docblock */`, | ||
`/* | ||
* This is not a docblock | ||
*/`, | ||
].map((sourceCode) => sourceCode + '\n' + 'function test() {}\n'); | ||
|
||
describe('extractJsDoc', () => { | ||
const extract = (index: number, line: number) => | ||
extractJsDocument_(new FileNavigator(FIXTURES[index]), line); | ||
|
||
it('should extract a multiline docblock', () => expect(extract(0, 4)).toMatchSnapshot()); | ||
|
||
it('should extract a single line docblock', () => expect(extract(1, 2)).toMatchSnapshot()); | ||
|
||
it('should extract a broken docblock', () => expect(extract(2, 5)).toMatchSnapshot()); | ||
|
||
it('should extract a weird two-line docblock', () => expect(extract(3, 3)).toMatchSnapshot()); | ||
|
||
it('should not extract a non-docblock', () => expect(extract(4, 4)).toMatchSnapshot()); | ||
|
||
it('should ignore out of range line index', () => expect(extract(0, 5)).toBe('')); | ||
|
||
it('should ignore zero line index', () => expect(extract(0, 0)).toBe('')); | ||
|
||
it('should ignore the middle of a docblock', () => expect(extract(0, 2)).toBe('')); | ||
}); |
Oops, something went wrong.