Skip to content

Commit

Permalink
pick up jest 23.3 and enhance error reporting, troubleshooting etc
Browse files Browse the repository at this point in the history
  • Loading branch information
connectdotz committed Jul 5, 2018
1 parent 9479c69 commit 475b901
Show file tree
Hide file tree
Showing 11 changed files with 374 additions and 164 deletions.
21 changes: 17 additions & 4 deletions .github/ISSUE_TEMPLATE.md
@@ -1,18 +1,31 @@

### Environment

1. `node -v`: [fill]
2. `npm -v`: [fill]
3. `npm ls react-scripts` (if you haven’t ejected): [fill]
1. `npm -v`: [fill]
1. `npm ls jest` or `npm ls react-scripts` (if you haven’t ejected): [fill]
1. you vscode-jest settings if customized:
- jest.pathToJest? [fill]
- jest.pathToConfig? [fill]
- anything else that you think might be relevant? [fill]

4. Operating system: [fill]
1. Operating system: [fill]

### Prerequisite
- are you able to run jest test from command line? [fill]
- how do yo run your tests from command line? (for example: `npm run test` or `node_modules/.bin/jest`) [fill]

### Steps to Reproduce

<!-- Please create a repository that reproduces the issue with the minimal amount of code possible. -->

[fill]

### Relevant Debug Info

<!-- If applicable, following self-diagnosis in https://github.com/jest-community/vscode-jest/blob/master/README.md#troubleshooting, and include the relevant debug info here to speed up the issue resolution -->

[fill]

### Expected Behavior

Expand All @@ -26,4 +39,4 @@

---

Note we are looking for someone to take responsibility around keeping create-react-app up to date and working, could this be you?
The fastest (and the most fun) way to resolve the issue is to submit a pull-request yourself. If you are interested, feel free to check out the [contribution guide](https://github.com/jest-community/vscode-jest/CONTRIBUTING.md), we look forward to seeing your PR...
42 changes: 40 additions & 2 deletions README.md
@@ -1,5 +1,28 @@
# vscode-jest [![Build Status](https://travis-ci.org/jest-community/vscode-jest.svg?branch=master)](https://travis-ci.org/jest-community/vscode-jest)

---


Content
* [The Aim](#the-aim)
* [Maintainers](#maintainers)
* [Features](#features)
* [How to get it?](#how-to-get-it)
* [How to get it set up?](#how-to-get-it-set-up)
* [How to start the Jest?](#how-to-start-the-jest)
* [How do I debug tests?](#how-do-i-debug-tests)
* [Notes for troubleshooting](#notes-for-troubleshooting)
* [How do I show code coverage?](#how-do-i-show-code-coverage)
* [Inspiration](#inspiration)
* [Wanted](#wanted)
* [Troubleshooting](#troubleshooting)
* [start jest from non-root folder](#start-jest-from-non-root-folder)
* [non-standard environments](#non-standard-environments)
* [plugin not running as expect? try self-diagnosis](#plugin-not-running-as-expect-try-self-diagnosis)
* [Want to Contribute?](#want-to-contribute)

---

## The Aim

A comprehensive experience when using [Facebook's Jest](https://github.com/facebook/jest) within a project.
Expand Down Expand Up @@ -36,7 +59,7 @@ If have a more complex setup, it can probably be supported, check out the settin
Also, you should use Jest 17+, however 16 works - it will just offer a warning. We're aiming to try and do current Jest version - 1, but won't specifically drop support for older versions unless we're forced into it.


## How to start the Jest?
## How do we start the Jest?

The extension will start Jest for you when:

Expand Down Expand Up @@ -100,6 +123,7 @@ Someone to take responsibility for ensuring that the default setup for create-re

## Troubleshooting

### start jest from non-root folder
If you don't use the root of your project for your JS with Jest tests, do not worry, you can still use this project. You will need to use the "Start Jest Runner" command, and maybe have to configure your own `jest.pathToJest` setting inside the `.vscode/settings.json` to whatever you would use.

These are the [activation events](https://code.visualstudio.com/docs/extensionAPI/activation-events) which trigger the runner to start:
Expand All @@ -113,8 +137,22 @@ These are the [activation events](https://code.visualstudio.com/docs/extensionAP
],
```

These are the things that will trigger the extension loading. If one of these applies, and you're not seeing the "Jest" in the bottom bar, run the command `Open Developer Tools` and see if something has crashed, we'd love to know what that is, and ideally a project we can run against.
These are the things that will trigger the extension loading. If one of these applies, and you're not seeing the "Jest" in the bottom bar, reference the self-diagnosis below

### non-standard environments
vscode-jest supports common jest configuration, such as when jest is in `root/node_modules/.bin/jest`, or for react-native `root/node_modules/react-native-scripts`.

However, if your repo doesn't fall into these patterns or you want to pass extra parameters, you can easily use the `jest.pathToJest` or `jest.pathToConfig` settings to instruct the plugin on how to start jest. You can even use the scripts from package.json, such as `npm run test --` or `yarn test`. Feel free to experiment and search the issues for many examples.

### plugin not running as expect? try self-diagnosis
If your can execute jest tests on command line but vscode-jest was not running as expected, here is what you can do to find out what it is actually doing:
1. click on `Jest:stopped` on status bar to show Jest Output window:
<img src="images/output-channel.png" alt="Screenshot of the tool" width="100%">
1. turn on the debug mode: set `"jest.debugMode": true` in `.vscode/settings.json`
1. restart vscode-jest or reload the window (via `Reload Window` command)
1. open the developer tool (via `Help > Toggle Developer Tools` menu), you should see more information including how we extract jest config and spawn jest processes.

Hopefully most issues would be pretty obvious after seeing these extra output, and you can probably fix most yourself by customizing the `jest.pathToJest` and other settings.

## Want to Contribute?

Expand Down
10 changes: 9 additions & 1 deletion __mocks__/vscode.ts
Expand Up @@ -22,7 +22,10 @@ const OverviewRulerLane = {
Left: null,
}

const Uri = { file: f => f }
const Uri = {
file: f => f,
parse: jest.fn(),
}
const Range = jest.fn()
const Diagnostic = jest.fn()
const DiagnosticSeverity = { Error: 0, Warning: 1, Information: 2, Hint: 3 }
Expand All @@ -32,6 +35,10 @@ const debug = {
startDebugging: jest.fn(),
}

const commands = {
executeCommand: jest.fn(),
}

export {
languages,
StatusBarAlignment,
Expand All @@ -43,4 +50,5 @@ export {
Diagnostic,
DiagnosticSeverity,
debug,
commands,
}
Binary file added images/output-channel.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions package.json
Expand Up @@ -224,7 +224,7 @@
"danger": "^2",
"glob": "^7.1.1",
"husky": "^0.14.3",
"jest": "^23.2.0",
"jest": "^23.3.0",
"lint-staged": "^4.2.3",
"prettier": "1.7.3",
"rimraf": "^2.6.2",
Expand All @@ -237,9 +237,9 @@
"elegant-spinner": "^1.0.1",
"istanbul-lib-coverage": "^1.1.1",
"istanbul-lib-source-maps": "^1.1.0",
"jest-editor-support": "23.2.0",
"jest-editor-support": "23.3.0",
"jest-snapshot": "^23.0.1",
"jest-test-typescript-parser": "^23.2.0",
"jest-test-typescript-parser": "^23.3.0",
"micromatch": "^2.3.11"
}
}
117 changes: 60 additions & 57 deletions src/JestExt.ts
Expand Up @@ -22,6 +22,7 @@ import { hasDocument, isOpenInMultipleEditors } from './editor'
import { CoverageOverlay } from './Coverage/CoverageOverlay'
import { JestProcess, JestProcessManager } from './JestProcessManagement'
import { isWatchNotSupported, WatchMode } from './Jest'
import * as messaging from './messaging'

export class JestExt {
private workspace: ProjectWorkspace
Expand Down Expand Up @@ -147,12 +148,15 @@ export class JestExt {
.onJestEditorSupportEvent('executableStdErr', (error: Buffer) => this.handleStdErr(error))
.onJestEditorSupportEvent('nonTerminalError', (error: string) => {
this.channel.appendLine(`Received an error from Jest Runner: ${error.toString()}`)
this.channel.show(true)
})
.onJestEditorSupportEvent('exception', result => {
this.channel.appendLine(`\nException raised: [${result.type}]: ${result.message}\n`)
this.channel.show(true)
})
.onJestEditorSupportEvent('terminalError', (error: string) => {
this.channel.appendLine('\nException raised: ' + error)
this.channel.show(true)
})
}

Expand All @@ -179,9 +183,10 @@ export class JestExt {
} else {
status.stopped()
if (!jestProcess.stopRequested) {
this.channel.appendLine(
'Starting Jest in Watch mode failed too many times and has been stopped. Please check your system configuration.'
)
const msg = `Starting Jest in Watch mode failed too many times and has been stopped.`
this.channel.appendLine(`${msg}\n see troubleshooting: ${messaging.TroubleShootingURL}`)
this.channel.show(true)
messaging.systemErrorMessage(msg, messaging.showTroubleshootingAction)
}
}
},
Expand All @@ -196,66 +201,65 @@ export class JestExt {
status.stopped()
}

private getSettings() {
const validateJestSettings = (): boolean => {
// check if jest is too old
if (this.jestSettings.jestVersionMajor < 20) {
// version is just a hint, we don't really use this specifically.
// the main settings we care is the testMatch or testRegex, which is used to
// detect if a given file is a jest test suite.
vscode.window.showWarningMessage(
`Found jest version '${this.jestSettings
.jestVersionMajor}'. This extension relies on Jest 20+ features, some features may not work correctly.`
)
}

// check if we can detect jest test patterns
if (
!this.jestSettings.settings ||
((!this.jestSettings.settings.testMatch || !this.jestSettings.settings.testMatch.length) &&
!this.jestSettings.settings.testRegex)
) {
console.error(`invalid settings: ${JSON.stringify(this.jestSettings.settings)}`)

vscode.window.showErrorMessage(
'Invalid jest config, the plugin might not be able to function properly. Please check your settings, such as jest.pathToJest'
)
return false
}

return true
}

const onError = err => {
console.error('failed to get get jest config from jest cli... will fallback to default setting. error:', err)

// if the default settings appear to be valid, show a warning anyway,
// to help user self diagnose problem later, if any
if (validateJestSettings()) {
vscode.window.showWarningMessage('Failed to retrieve jest config, will fallback to the default setting')
showSettings()
}
}

const showSettings = (prefix: string = 'jest settings:') => {
if (this.workspace.debug) {
console.log(`${prefix}
jestVersionMajor=${this.jestSettings.jestVersionMajor}
testMatch=${this.jestSettings.settings.testMatch}
testRegex=${this.jestSettings.settings.testRegex}
`)
}
}
private validateJestSettings(showSettingPrefix?: string): boolean {
let isValid = true

// check if setting is a default: jestVersionMajor == null
if (!this.jestSettings.jestVersionMajor) {
messaging.systemWarningMessage(
'Failed to retrieve jest config, will fallback to default config that might not be compatible with your env.',
messaging.showTroubleshootingAction
)
isValid = false
} else if (this.jestSettings.jestVersionMajor < 20) {
// version is just a hint, we don't really use this specifically.
// the main settings we care is the testMatch or testRegex, which is used to
// detect if a given file is a jest test suite.
messaging.systemWarningMessage(
`Found jest version '${this.jestSettings
.jestVersionMajor}'. This extension relies on Jest 20+ features, some features may not work correctly.`
)
}

// check if we can detect jest test patterns
if (
!this.jestSettings.settings ||
((!this.jestSettings.settings.testMatch || !this.jestSettings.settings.testMatch.length) &&
!this.jestSettings.settings.testRegex)
) {
isValid = false
console.error(`invalid settings: ${JSON.stringify(this.jestSettings.settings)}`)

messaging.systemErrorMessage(
'Invalid jest config, the plugin might not be able to function properly.',
messaging.showTroubleshootingAction
)
}

// display settings in debug mode
if (this.workspace.debug && showSettingPrefix) {
console.log(`${showSettingPrefix}:
jestVersionMajor=${this.jestSettings.jestVersionMajor}
testMatch=${this.jestSettings.settings.testMatch}
testRegex=${this.jestSettings.settings.testRegex}
`)
}

return isValid
}

private getSettings() {
try {
this.jestSettings.getConfig(() => {
if (validateJestSettings()) {
if (this.validateJestSettings('Jest Config Retrieved')) {
this.workspace.localJestMajorVersion = this.jestSettings.jestVersionMajor
showSettings('Jest Settings Updated')
}
})
} catch (error) {
onError(error)
console.error('jestSettings.getConfig() failed:', error)
// most likely validating the default setting, which will trigger a warning
// that should be fine as this is an error condition that could impact the plugin functionality
this.validateJestSettings('Jest Config Retrieval Failed')
}
}

Expand Down Expand Up @@ -474,7 +478,6 @@ export class JestExt {
return {
range: new vscode.Range(it.start.line, it.start.column, it.start.line, it.start.column + 1),
hoverMessage: nameForState[state],

/* ERROR: this needs to include all ancestor describe block names as well!
in code bellow it block has identifier = 'aaa bbb ccc': but name is only 'ccc'
Expand Down
54 changes: 54 additions & 0 deletions src/messaging.ts
@@ -0,0 +1,54 @@
/**
* collection of functions to show messages with actions in a consistent manner
*/

import * as vscode from 'vscode'

export interface MessageAction {
title: string
action: () => void
}

export function systemErrorMessage(message: string, ...actions: Array<MessageAction>) {
const msg = vscode.window.showErrorMessage(message, ...extractActionTitles(actions))
if (msg) {
msg.then(handleMessageActions(actions))
}
}

export function systemWarningMessage(message: string, ...actions: Array<MessageAction>) {
const msg = vscode.window.showWarningMessage(message, ...extractActionTitles(actions))
if (msg) {
msg.then(handleMessageActions(actions))
}
}

// common actions
export const showTroubleshootingAction: MessageAction = {
title: 'help',
action: () => vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(TroubleShootingURL)),
}

export const TroubleShootingURL = 'https://github.com/jest-community/vscode-jest/blob/master/README.md#troubleshooting'
//
// internal methods
//
function extractActionTitles(actions?: Array<MessageAction>): string[] {
if (!actions || actions.length === 0) {
return []
}
return actions.map(a => a.title)
}
function handleMessageActions(actions?: Array<MessageAction>): (action?: string) => void {
return (action?: string) => {
if (!action) {
return
}
const found = actions.filter(a => a.title === action)
if (found.length === 1) {
found[0].action()
} else {
vscode.window.showWarningMessage(`unrecognized action ${action}`)
}
}
}

0 comments on commit 475b901

Please sign in to comment.