From 1cd4955aca2bc05da712585ca688b840890cf544 Mon Sep 17 00:00:00 2001 From: Kornel Dubieniecki Date: Wed, 25 Sep 2019 19:20:09 +0200 Subject: [PATCH 1/7] feat: transform file paths into hyperlinks --- packages/jest-reporters/package.json | 3 ++- packages/jest-reporters/src/get_result_header.ts | 14 ++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/jest-reporters/package.json b/packages/jest-reporters/package.json index 26e2478139ab..e01aa16e66f3 100644 --- a/packages/jest-reporters/package.json +++ b/packages/jest-reporters/package.json @@ -25,7 +25,8 @@ "jest-worker": "^24.6.0", "slash": "^3.0.0", "source-map": "^0.6.0", - "string-length": "^3.1.0" + "string-length": "^3.1.0", + "terminal-link": "^2.0.0" }, "devDependencies": { "@types/exit": "^0.1.30", diff --git a/packages/jest-reporters/src/get_result_header.ts b/packages/jest-reporters/src/get_result_header.ts index 4c80809cdce6..81292fa3e518 100644 --- a/packages/jest-reporters/src/get_result_header.ts +++ b/packages/jest-reporters/src/get_result_header.ts @@ -9,6 +9,7 @@ import {Config} from '@jest/types'; import {TestResult} from '@jest/test-result'; import chalk from 'chalk'; import {formatTestPath, printDisplayName} from './utils'; +import terminalLink = require('terminal-link'); const LONG_TEST_COLOR = chalk.reset.bold.bgRed; // Explicitly reset for these messages since they can get written out in the @@ -30,6 +31,13 @@ export default ( projectConfig?: Config.ProjectConfig, ) => { const testPath = result.testFilePath; + const formattedTestPath = formatTestPath( + projectConfig ? projectConfig : globalConfig, + testPath, + ); + const fileLink = terminalLink(formattedTestPath, `file://${testPath}`, { + fallback: () => formattedTestPath, + }); const status = result.numFailingTests > 0 || result.testExecError ? FAIL : PASS; @@ -53,9 +61,7 @@ export default ( : ''; return ( - `${status} ${projectDisplayName}${formatTestPath( - projectConfig ? projectConfig : globalConfig, - testPath, - )}` + (testDetail.length ? ` (${testDetail.join(', ')})` : '') + `${status} ${projectDisplayName}${fileLink}` + + (testDetail.length ? ` (${testDetail.join(', ')})` : '') ); }; From 243a6979f060b2028aa864b54b1dccfe0ead09ce Mon Sep 17 00:00:00 2001 From: Kornel Dubieniecki Date: Wed, 2 Oct 2019 11:54:31 +0200 Subject: [PATCH 2/7] chore: commit yarn.lock --- yarn.lock | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/yarn.lock b/yarn.lock index efb2690bd15d..68b836bb94f9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13130,6 +13130,14 @@ supports-color@^7.0.0: dependencies: has-flag "^4.0.0" +supports-hyperlinks@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.0.0.tgz#b1b94a159e9df00b0a554b2d5f0e0a89690334b0" + integrity sha512-bFhn0MQ8qefLyJ3K7PpHiPUTuTVPWw6RXfaMeV6xgJLXtBbszyboz1bvGTVv4R0YpQm2DqlXXn0fFHhxUHVE5w== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + svgo@^1.0.0, svgo@^1.0.5: version "1.3.0" resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.0.tgz#bae51ba95ded9a33a36b7c46ce9c359ae9154313" @@ -13245,6 +13253,14 @@ tempfile@^2.0.0: temp-dir "^1.0.0" uuid "^3.0.1" +terminal-link@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.0.0.tgz#daa5d9893d57d3a09f981e1a45be37daba3f0ce6" + integrity sha512-rdBAY35jUvVapqCuhehjenLbYY73cVgRQ6podD6u9EDBomBBHjCOtmq2InPgPpTysOIOsQ5PdBzwSC/sKjv6ew== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + terser-webpack-plugin@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz#61b18e40eaee5be97e771cdbb10ed1280888c2b4" From 00ac96c9295367e6f8841b09424ede33a21728f2 Mon Sep 17 00:00:00 2001 From: Kornel Dubieniecki Date: Wed, 2 Oct 2019 11:58:33 +0200 Subject: [PATCH 3/7] chore: update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1bf053cde4a..1c5de2de5c29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ - `[jest-runner]` Warn if a worker had to be force exited ([#8206](https://github.com/facebook/jest/pull/8206)) - `[@jest/test-result]` Create method to create empty `TestResult` ([#8867](https://github.com/facebook/jest/pull/8867)) - `[jest-worker]` [**BREAKING**] Return a promise from `end()`, resolving with the information whether workers exited gracefully ([#8206](https://github.com/facebook/jest/pull/8206)) +- `[jest-reporters]` Transform file paths into hyperlinks ([#8980](https://github.com/facebook/jest/pull/8980)) ### Fixes From da3d6a77258cfa0f74958e5aa5d4d9608d923971 Mon Sep 17 00:00:00 2001 From: Kornel Dubieniecki Date: Wed, 2 Oct 2019 13:19:02 +0200 Subject: [PATCH 4/7] chore: add test --- .../src/__tests__/get_result_header.test.js | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 packages/jest-reporters/src/__tests__/get_result_header.test.js diff --git a/packages/jest-reporters/src/__tests__/get_result_header.test.js b/packages/jest-reporters/src/__tests__/get_result_header.test.js new file mode 100644 index 000000000000..f80fb621c4d7 --- /dev/null +++ b/packages/jest-reporters/src/__tests__/get_result_header.test.js @@ -0,0 +1,30 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {makeGlobalConfig} from '../../../../TestUtils'; +import {formatTestPath} from '../utils'; +import getResultHeader from '../get_result_header'; +const terminalLink = require('terminal-link'); + +jest.mock('terminal-link', () => jest.fn()); + +const testResult = { + testFilePath: '/foo', +}; + +const globalConfig = makeGlobalConfig(); + +test('should call `terminal-link` correctly', () => { + terminalLink.mockClear(); + + getResultHeader(testResult, globalConfig); + const call = terminalLink.mock.calls[0]; + + expect(terminalLink).toHaveBeenCalled(); + expect(call[0]).toBe(formatTestPath(globalConfig, testResult.testFilePath)); + expect(call[1]).toBe(`file://${testResult.testFilePath}`); +}); From 8d638f0c2954846edf6126d114b39348a7e4b2d1 Mon Sep 17 00:00:00 2001 From: Kornel Dubieniecki Date: Thu, 3 Oct 2019 12:25:20 +0200 Subject: [PATCH 5/7] chore: add test for the returned value --- .../src/__tests__/get_result_header.test.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/jest-reporters/src/__tests__/get_result_header.test.js b/packages/jest-reporters/src/__tests__/get_result_header.test.js index f80fb621c4d7..c692525a3a87 100644 --- a/packages/jest-reporters/src/__tests__/get_result_header.test.js +++ b/packages/jest-reporters/src/__tests__/get_result_header.test.js @@ -10,7 +10,7 @@ import {formatTestPath} from '../utils'; import getResultHeader from '../get_result_header'; const terminalLink = require('terminal-link'); -jest.mock('terminal-link', () => jest.fn()); +jest.mock('terminal-link', () => jest.fn(() => 'wannabehyperlink')); const testResult = { testFilePath: '/foo', @@ -28,3 +28,9 @@ test('should call `terminal-link` correctly', () => { expect(call[0]).toBe(formatTestPath(globalConfig, testResult.testFilePath)); expect(call[1]).toBe(`file://${testResult.testFilePath}`); }); + +test('should render the output correctly', () => { + const result = getResultHeader(testResult, globalConfig); + + expect(result).toMatch(/wannabehyperlink/); +}); From 350e8eae3f0fc1fe936068a2b320e95ed8ad3862 Mon Sep 17 00:00:00 2001 From: Kornel Dubieniecki Date: Mon, 14 Oct 2019 00:22:14 +0200 Subject: [PATCH 6/7] Apply the review suggestions --- .../src/__tests__/get_result_header.test.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/jest-reporters/src/__tests__/get_result_header.test.js b/packages/jest-reporters/src/__tests__/get_result_header.test.js index c692525a3a87..a11c24945d1b 100644 --- a/packages/jest-reporters/src/__tests__/get_result_header.test.js +++ b/packages/jest-reporters/src/__tests__/get_result_header.test.js @@ -18,19 +18,22 @@ const testResult = { const globalConfig = makeGlobalConfig(); -test('should call `terminal-link` correctly', () => { +beforeEach(() => { terminalLink.mockClear(); +}); +test('should call `terminal-link` correctly', () => { getResultHeader(testResult, globalConfig); - const call = terminalLink.mock.calls[0]; - expect(terminalLink).toHaveBeenCalled(); - expect(call[0]).toBe(formatTestPath(globalConfig, testResult.testFilePath)); - expect(call[1]).toBe(`file://${testResult.testFilePath}`); + expect(terminalLink).toBeCalledWith( + formatTestPath(globalConfig, testResult.testFilePath), + `file://${testResult.testFilePath}`, + expect.objectContaining({fallback: expect.any(Function)}), + ); }); -test('should render the output correctly', () => { +test('should render the terminal link', () => { const result = getResultHeader(testResult, globalConfig); - expect(result).toMatch(/wannabehyperlink/); + expect(result).toContain('wannabehyperlink'); }); From bd0921375071ff96e26ab46a4438dfc08ed7f4ba Mon Sep 17 00:00:00 2001 From: Kornel Dubieniecki Date: Mon, 14 Oct 2019 18:47:56 +0200 Subject: [PATCH 7/7] Hardcode expected values --- .../jest-reporters/src/__tests__/get_result_header.test.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/jest-reporters/src/__tests__/get_result_header.test.js b/packages/jest-reporters/src/__tests__/get_result_header.test.js index a11c24945d1b..3c0c3351ae3e 100644 --- a/packages/jest-reporters/src/__tests__/get_result_header.test.js +++ b/packages/jest-reporters/src/__tests__/get_result_header.test.js @@ -6,7 +6,6 @@ */ import {makeGlobalConfig} from '../../../../TestUtils'; -import {formatTestPath} from '../utils'; import getResultHeader from '../get_result_header'; const terminalLink = require('terminal-link'); @@ -26,8 +25,8 @@ test('should call `terminal-link` correctly', () => { getResultHeader(testResult, globalConfig); expect(terminalLink).toBeCalledWith( - formatTestPath(globalConfig, testResult.testFilePath), - `file://${testResult.testFilePath}`, + expect.stringContaining('foo'), + 'file:///foo', expect.objectContaining({fallback: expect.any(Function)}), ); });