diff --git a/src/formatter/webpack-formatter.ts b/src/formatter/webpack-formatter.ts index 389c4bbb..7adacfe4 100644 --- a/src/formatter/webpack-formatter.ts +++ b/src/formatter/webpack-formatter.ts @@ -17,7 +17,7 @@ function createWebpackFormatter(formatter: Formatter): Formatter { if (issue.file) { let location = chalk.bold(relativeToContext(issue.file, process.cwd())); if (issue.location) { - location += ` ${chalk.green.bold(formatIssueLocation(issue.location))}`; + location += `:${chalk.green.bold(formatIssueLocation(issue.location))}`; } return [`${color(severity)} in ${location}`, formatter(issue), ''].join(os.EOL); diff --git a/src/issue/issue-location.ts b/src/issue/issue-location.ts index 1095eed5..096ff551 100644 --- a/src/issue/issue-location.ts +++ b/src/issue/issue-location.ts @@ -25,20 +25,8 @@ function compareIssueLocations(locationA?: IssueLocation, locationB?: IssueLocat ); } -function formatIssueLocation({ start, end }: IssueLocation) { - if (!end.line || start.line === end.line) { - // the same line - if (!end.column || start.column === end.column) { - // the same column - return `${start.line}:${start.column}`; - } else { - // different column - return `${start.line}:${start.column}-${end.column}`; - } - } else { - // different lines - return `${start.line}:${start.column}-${end.line}:${end.column}`; - } +function formatIssueLocation(location: IssueLocation) { + return `${location.start.line}:${location.start.column}`; } export { IssueLocation, compareIssueLocations, formatIssueLocation }; diff --git a/src/issue/issue-webpack-error.ts b/src/issue/issue-webpack-error.ts index a1f768dc..8d76c17c 100644 --- a/src/issue/issue-webpack-error.ts +++ b/src/issue/issue-webpack-error.ts @@ -19,7 +19,7 @@ class IssueWebpackError extends webpack.WebpackError { this.file = relativeToContext(issue.file, process.cwd()); if (issue.location) { - this.file += ` ${chalk.green.bold(formatIssueLocation(issue.location))}`; + this.file += `:${chalk.green.bold(formatIssueLocation(issue.location))}`; } } diff --git a/test/e2e/type-script-context-option.spec.ts b/test/e2e/type-script-context-option.spec.ts index 4bb0180d..bee72e1a 100644 --- a/test/e2e/type-script-context-option.spec.ts +++ b/test/e2e/type-script-context-option.spec.ts @@ -89,7 +89,7 @@ describe('TypeScript Context Option', () => { const errors = await driver.waitForErrors(); expect(errors).toEqual([ [ - 'ERROR in ../src/model/User.ts 11:16-25', + 'ERROR in ../src/model/User.ts:11:16', "TS2339: Property 'firstName' does not exist on type 'User'.", ' 9 |', ' 10 | function getUserName(user: User): string {', @@ -100,7 +100,7 @@ describe('TypeScript Context Option', () => { ' 14 | export { User, getUserName };', ].join('\n'), [ - 'ERROR in ../src/model/User.ts 11:32-40', + 'ERROR in ../src/model/User.ts:11:32', "TS2339: Property 'lastName' does not exist on type 'User'.", ' 9 |', ' 10 | function getUserName(user: User): string {', diff --git a/test/e2e/type-script-formatter-option.spec.ts b/test/e2e/type-script-formatter-option.spec.ts index aea8353c..6b0af759 100644 --- a/test/e2e/type-script-formatter-option.spec.ts +++ b/test/e2e/type-script-formatter-option.spec.ts @@ -41,11 +41,11 @@ describe('TypeScript Formatter Option', () => { const errors = await driver.waitForErrors(); expect(errors).toEqual([ [ - 'ERROR in ./src/model/User.ts 11:16-25', + 'ERROR in ./src/model/User.ts:11:16', "It is the custom issue statement - TS2339: Property 'firstName' does not exist on type 'User'.", ].join('\n'), [ - 'ERROR in ./src/model/User.ts 11:32-40', + 'ERROR in ./src/model/User.ts:11:32', "It is the custom issue statement - TS2339: Property 'lastName' does not exist on type 'User'.", ].join('\n'), ]); diff --git a/test/e2e/type-script-pnp-support.spec.ts b/test/e2e/type-script-pnp-support.spec.ts index 90a5e312..b9580732 100644 --- a/test/e2e/type-script-pnp-support.spec.ts +++ b/test/e2e/type-script-pnp-support.spec.ts @@ -34,7 +34,7 @@ describe('TypeScript PnP Support', () => { errors = await driver.waitForErrors(); expect(errors).toEqual([ [ - 'ERROR in ./src/model/User.ts 11:16-25', + 'ERROR in ./src/model/User.ts:11:16', "TS2339: Property 'firstName' does not exist on type 'User'.", ' 9 |', ' 10 | function getUserName(user: User): string {', @@ -45,7 +45,7 @@ describe('TypeScript PnP Support', () => { ' 14 | export { User, getUserName };', ].join('\n'), [ - 'ERROR in ./src/model/User.ts 11:32-40', + 'ERROR in ./src/model/User.ts:11:32', "TS2339: Property 'lastName' does not exist on type 'User'.", ' 9 |', ' 10 | function getUserName(user: User): string {', @@ -72,7 +72,7 @@ describe('TypeScript PnP Support', () => { errors = await driver.waitForErrors(); expect(errors).toContain( [ - 'ERROR in ./src/index.ts 1:23-39', + 'ERROR in ./src/index.ts:1:23', semver.satisfies(semver.minVersion(dependencies.typescript), '>=4.0.0') ? "TS2307: Cannot find module './authenticate' or its corresponding type declarations." : "TS2307: Cannot find module './authenticate'.", @@ -118,7 +118,7 @@ describe('TypeScript PnP Support', () => { errors = await driver.waitForErrors(); expect(errors).toEqual([ [ - 'ERROR in ./src/index.ts 34:12-16', + 'ERROR in ./src/index.ts:34:12', "TS2339: Property 'role' does not exist on type 'void'.", ' 32 | const user = await login(email, password);', ' 33 |', @@ -129,7 +129,7 @@ describe('TypeScript PnP Support', () => { ' 37 | console.log(`Logged in as ${getUserName(user)}`);', ].join('\n'), [ - 'ERROR in ./src/index.ts 35:45-49', + 'ERROR in ./src/index.ts:35:45', "TS2345: Argument of type 'void' is not assignable to parameter of type 'User'.", ' 33 |', " 34 | if (user.role === 'admin') {", @@ -140,7 +140,7 @@ describe('TypeScript PnP Support', () => { ' 38 | }', ].join('\n'), [ - 'ERROR in ./src/index.ts 37:45-49', + 'ERROR in ./src/index.ts:37:45', "TS2345: Argument of type 'void' is not assignable to parameter of type 'User'.", ' 35 | console.log(`Logged in as ${getUserName(user)} [admin].`);', ' 36 | } else {', diff --git a/test/e2e/type-script-solution-builder-api.spec.ts b/test/e2e/type-script-solution-builder-api.spec.ts index c8d7b608..4c9d59ff 100644 --- a/test/e2e/type-script-solution-builder-api.spec.ts +++ b/test/e2e/type-script-solution-builder-api.spec.ts @@ -33,7 +33,7 @@ describe('TypeScript SolutionBuilder API', () => { errors = await driver.waitForErrors(); expect(errors).toEqual([ [ - 'ERROR in ./packages/shared/src/intersect.ts 2:41-49', + 'ERROR in ./packages/shared/src/intersect.ts:2:41', "TS2339: Property 'includes' does not exist on type 'T'.", ' 1 | function intersect(arrayA: T[] = [], arrayB: T): T[] {', ' > 2 | return arrayA.filter((item) => arrayB.includes(item));', @@ -55,7 +55,7 @@ describe('TypeScript SolutionBuilder API', () => { errors = await driver.waitForErrors(); expect(errors).toEqual([ [ - 'ERROR in ./packages/client/src/index.ts 4:42-48', + 'ERROR in ./packages/client/src/index.ts:4:42', "TS2345: Argument of type 'T[]' is not assignable to parameter of type 'T'.", semver.satisfies(semver.minVersion(typescript), '>=4.0.0') ? " 'T' could be instantiated with an arbitrary type which could be unrelated to 'T[]'." diff --git a/test/e2e/type-script-vue-extension.spec.ts b/test/e2e/type-script-vue-extension.spec.ts index 1a9fecb9..c088ab2e 100644 --- a/test/e2e/type-script-vue-extension.spec.ts +++ b/test/e2e/type-script-vue-extension.spec.ts @@ -63,7 +63,7 @@ describe('TypeScript Vue Extension', () => { errors = await driver.waitForErrors(); expect(errors).toEqual([ [ - 'ERROR in ./src/component/LoggedIn.vue 27:23-34', + 'ERROR in ./src/component/LoggedIn.vue:27:23', "TS2304: Cannot find name 'getUserName'.", ' 25 | const user: User = this.user;', ' 26 |', @@ -91,7 +91,7 @@ describe('TypeScript Vue Extension', () => { errors = await driver.waitForErrors(); expect(errors).toEqual([ [ - 'ERROR in ./src/component/LoggedIn.vue 27:31-40', + 'ERROR in ./src/component/LoggedIn.vue:27:31', "TS2339: Property 'firstName' does not exist on type 'User'.", ' 25 | const user: User = this.user;', ' 26 |', @@ -102,7 +102,7 @@ describe('TypeScript Vue Extension', () => { ' 30 | async logout() {', ].join('\n'), [ - 'ERROR in ./src/model/User.ts 11:16-25', + 'ERROR in ./src/model/User.ts:11:16', "TS2339: Property 'firstName' does not exist on type 'User'.", ' 9 |', ' 10 | function getUserName(user: User): string {', diff --git a/test/e2e/type-script-watch-api.spec.ts b/test/e2e/type-script-watch-api.spec.ts index 5ce64aaa..158d194e 100644 --- a/test/e2e/type-script-watch-api.spec.ts +++ b/test/e2e/type-script-watch-api.spec.ts @@ -32,7 +32,7 @@ describe('TypeScript Watch API', () => { errors = await driver.waitForErrors(); expect(errors).toEqual([ [ - 'ERROR in ./src/index.ts 34:7-28', + 'ERROR in ./src/index.ts:34:7', `TS2367: This condition will always return 'false' since the types 'Role' and '"admin"' have no overlap.`, ' 32 | const user = await login(email, password);', ' 33 |', @@ -74,7 +74,7 @@ describe('TypeScript Watch API', () => { ); expect(errors).toEqual([ [ - 'ERROR in ./src/model/User.ts 1:22-30', + 'ERROR in ./src/model/User.ts:1:22', "TS2307: Cannot find module './Role' or its corresponding type declarations.", " > 1 | import { Role } from './Role';", ' | ^^^^^^^^', @@ -94,7 +94,7 @@ describe('TypeScript Watch API', () => { errors = await driver.waitForErrors(); expect(errors).toEqual([ [ - 'ERROR in ./src/index.ts 34:7-31', + 'ERROR in ./src/index.ts:34:7', "TS2367: This condition will always return 'false' since the types 'Role' and '\"provider\"' have no overlap.", ' 32 | const user = await login(email, password);', ' 33 |', @@ -135,7 +135,7 @@ describe('TypeScript Watch API', () => { errors = await driver.waitForErrors(); expect(errors).toEqual([ [ - 'ERROR in ./src/index.ts 34:7-28', + 'ERROR in ./src/index.ts:34:7', `TS2367: This condition will always return 'false' since the types 'Role' and '"admin"' have no overlap.`, ' 32 | const user = await login(email, password);', ' 33 |', @@ -177,7 +177,7 @@ describe('TypeScript Watch API', () => { ); expect(errors).toEqual([ [ - 'ERROR in ./src/model/User.ts 1:22-30', + 'ERROR in ./src/model/User.ts:1:22', "TS2307: Cannot find module './Role' or its corresponding type declarations.", " > 1 | import { Role } from './Role';", ' | ^^^^^^^^', @@ -197,7 +197,7 @@ describe('TypeScript Watch API', () => { errors = await driver.waitForErrors(); expect(errors).toEqual([ [ - 'ERROR in ./src/index.ts 34:7-31', + 'ERROR in ./src/index.ts:34:7', "TS2367: This condition will always return 'false' since the types 'Role' and '\"provider\"' have no overlap.", ' 32 | const user = await login(email, password);', ' 33 |', @@ -241,7 +241,7 @@ describe('TypeScript Watch API', () => { errors = await driver.waitForErrors(); expect(errors).toEqual([ [ - 'ERROR in ./src/model/User.ts 11:16-25', + 'ERROR in ./src/model/User.ts:11:16', "TS2339: Property 'firstName' does not exist on type 'User'.", ' 9 |', ' 10 | function getUserName(user: User): string {', @@ -252,7 +252,7 @@ describe('TypeScript Watch API', () => { ' 14 | export { User, getUserName };', ].join('\n'), [ - 'ERROR in ./src/model/User.ts 11:32-40', + 'ERROR in ./src/model/User.ts:11:32', "TS2339: Property 'lastName' does not exist on type 'User'.", ' 9 |', ' 10 | function getUserName(user: User): string {', @@ -279,7 +279,7 @@ describe('TypeScript Watch API', () => { errors = await driver.waitForErrors(); expect(errors).toContain( [ - 'ERROR in ./src/index.ts 1:23-39', + 'ERROR in ./src/index.ts:1:23', semver.satisfies(semver.minVersion(dependencies.typescript), '>=4.0.0') ? "TS2307: Cannot find module './authenticate' or its corresponding type declarations." : "TS2307: Cannot find module './authenticate'.", @@ -325,7 +325,7 @@ describe('TypeScript Watch API', () => { errors = await driver.waitForErrors(); expect(errors).toEqual([ [ - 'ERROR in ./src/index.ts 34:12-16', + 'ERROR in ./src/index.ts:34:12', "TS2339: Property 'role' does not exist on type 'void'.", ' 32 | const user = await login(email, password);', ' 33 |', @@ -336,7 +336,7 @@ describe('TypeScript Watch API', () => { ' 37 | console.log(`Logged in as ${getUserName(user)}`);', ].join('\n'), [ - 'ERROR in ./src/index.ts 35:45-49', + 'ERROR in ./src/index.ts:35:45', "TS2345: Argument of type 'void' is not assignable to parameter of type 'User'.", ' 33 |', " 34 | if (user.role === 'admin') {", @@ -347,7 +347,7 @@ describe('TypeScript Watch API', () => { ' 38 | }', ].join('\n'), [ - 'ERROR in ./src/index.ts 37:45-49', + 'ERROR in ./src/index.ts:37:45', "TS2345: Argument of type 'void' is not assignable to parameter of type 'User'.", ' 35 | console.log(`Logged in as ${getUserName(user)} [admin].`);', ' 36 | } else {', @@ -457,7 +457,7 @@ describe('TypeScript Watch API', () => { expect(await driver.waitForErrors()).toEqual([ [ - 'ERROR in ./src/model/User.ts 12:47-59', + 'ERROR in ./src/model/User.ts:12:47', "TS2339: Property 'organization' does not exist on type 'User'.", ' 10 |', ' 11 | function getUserName(user: User): string {', diff --git a/test/e2e/webpack-production-build.spec.ts b/test/e2e/webpack-production-build.spec.ts index 83803bb1..c7f221f7 100644 --- a/test/e2e/webpack-production-build.spec.ts +++ b/test/e2e/webpack-production-build.spec.ts @@ -87,7 +87,7 @@ describe('Webpack Production Build', () => { // first error is from the webpack module resolution expect.anything(), [ - 'ERROR in ./src/authenticate.ts 1:22-36', + 'ERROR in ./src/authenticate.ts:1:22', "TS2307: Cannot find module './model/User' or its corresponding type declarations.", " > 1 | import { User } from './model/User';", ' | ^^^^^^^^^^^^^^', @@ -96,7 +96,7 @@ describe('Webpack Production Build', () => { " 4 | const response = await fetch('/login', {", ].join('\n'), [ - 'ERROR in ./src/index.ts 2:29-43', + 'ERROR in ./src/index.ts:2:29', "TS2307: Cannot find module './model/User' or its corresponding type declarations.", " 1 | import { login } from './authenticate';", " > 2 | import { getUserName } from './model/User';", diff --git a/test/unit/formatter/webpack-formatter.spec.ts b/test/unit/formatter/webpack-formatter.spec.ts index 720bfafa..178ab151 100644 --- a/test/unit/formatter/webpack-formatter.spec.ts +++ b/test/unit/formatter/webpack-formatter.spec.ts @@ -43,18 +43,18 @@ describe('formatter/webpack-formatter', () => { }); it('formats location', () => { - expect(formatter(issue)).toContain(' 1:7-16'); + expect(formatter(issue)).toContain(':1:7'); expect( formatter({ ...issue, location: { start: { line: 1, column: 7 }, end: { line: 10, column: 16 } }, }) - ).toContain(' 1:7-10:16'); + ).toContain(':1:7'); }); it('formats issue header like webpack', () => { expect(formatter(issue)).toEqual( - [`ERROR in ./some/file.ts 1:7-16`, 'TS123: Some issue content', ''].join(os.EOL) + [`ERROR in ./some/file.ts:1:7`, 'TS123: Some issue content', ''].join(os.EOL) ); }); });