Skip to content

Feature/refactor test runner #53

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Nov 15, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
createTestRunner in progress
  • Loading branch information
ShMcK committed Nov 13, 2019
commit ab13f524e58d84e26e4416e7499a54a5823a6f68
113 changes: 64 additions & 49 deletions src/actions/runTest.ts → src/actions/runTest/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as vscode from 'vscode'
import node from '../services/node'
import node from '../../services/node'

// TODO: use tap parser to make it easier to support other test runners

Expand All @@ -21,31 +21,49 @@ const getOutputChannel = (name: string): vscode.OutputChannel => {
return channel
}

interface Props {
interface Callbacks {
onSuccess(): void
onFail(): void
onRun(): void
onError(): void
}

async function runTest({onSuccess, onFail, onRun, onError}: Props): Promise<void> {
console.log('------------------- run test ------------------')
// increment process id
const processId = ++currentId
interface TestRunnerConfig {
command: string
parser(output: string): boolean
}

export const createTestRunner = (config: TestRunnerConfig, callbacks: Callbacks) => {

const outputChannelName = 'TEST_OUTPUT'

return {
run() {
console.log('------------------- run test ------------------')
const processId = ++currentId
callbacks.onRun()

try {
const {stdout} = await node.exec(config.command)
}
}
}
}

async function runTest({onSuccess, onFail, onRun, onError}: Callbacks): Promise<void> {


onRun()

const outputChannelName = 'Test Output'

// TODO: verify test runner for args
// jest CLI docs https://jestjs.io/docs/en/cli
const testArgs = [
'--json',
'--onlyChanged',
'--env=node',
'--maxConcurrency=4',
'--maxWorkers=4'
]
// const testArgs = [
// '--json',
// '--onlyChanged',
// '--env=node',
// '--maxConcurrency=4',
// '--maxWorkers=4'
// ]

const commandLine = `npm test -- ${testArgs.join(' ')}`

Expand All @@ -61,23 +79,22 @@ async function runTest({onSuccess, onFail, onRun, onError}: Props): Promise<void
if (stdout) {
const lines = stdout.split(/\r{0,1}\n/)
for (const line of lines) {
if (line.length === 0) {
continue
}

const regExp = /^{\"numFailedTestSuites/
const matches = regExp.exec(line)
if (matches && matches.length) {
const result = JSON.parse(line)

if (result.success) {
if (shouldExitEarly(processId)) {
// exit early
return
if (line.length > 0) {
const regExp = /^{\"numFailedTestSuites/
const matches = regExp.exec(line)
if (matches && matches.length) {
const result = JSON.parse(line)

if (result.success) {
if (shouldExitEarly(processId)) {
// exit early
return
}
console.log('success!')
onSuccess()
} else {
console.log('NOT SUCCESS?')
}
onSuccess()
} else {
console.log('NOT SUCCESS?')
}
}
}
Expand All @@ -104,25 +121,23 @@ async function runTest({onSuccess, onFail, onRun, onError}: Props): Promise<void
const lines = stdout.split(/\r{0,1}\n/)

for (const line of lines) {
if (line.length === 0) {
continue
}

const dataRegExp = /^{\"numFailedTestSuites"/
const matches = dataRegExp.exec(line)

if (matches && matches.length) {
const result = JSON.parse(line)
const firstError = result.testResults.find((t: any) => t.status === 'failed')

if (firstError) {
if (shouldExitEarly(processId)) {
// exit early
return
if (line.length > 0) {
const dataRegExp = /^{\"numFailedTestSuites"/
const matches = dataRegExp.exec(line)

if (matches && matches.length) {
const result = JSON.parse(line)
const firstError = result.testResults.find((t: any) => t.status === 'failed')

if (firstError) {
if (shouldExitEarly(processId)) {
// exit early
return
}
onFail()
} else {
console.error('NOTE: PARSER DID NOT WORK FOR ', line)
}
onFail()
} else {
console.error('NOTE: PARSER DID NOT WORK FOR ', line)
}
}
}
Expand Down
89 changes: 45 additions & 44 deletions src/actions/setupActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,50 +55,51 @@ const setupActions = async (workspaceRoot: vscode.WorkspaceFolder, actions: G.St
}

// run file watchers (listeners)
// if (listeners) {
// console.log('listeners')
// for (const listener of listeners) {
// if (!watchers[listener]) {
// const pattern = new vscode.RelativePattern(
// vscode.workspace.getWorkspaceFolder(workspaceRoot.uri)!,
// listener
// )
// console.log(pattern)
// watchers[listener] = vscode.workspace.createFileSystemWatcher(
// pattern
// )
// watchers[listener].onDidChange(() => {
// console.log('onDidChange')
// // trigger save
// vscode.commands.executeCommand('coderoad.run_test', null, () => {
// // cleanup watcher on success
// disposeWatcher(listener)
// })
// })
// watchers[listener].onDidCreate(() => {
// console.log('onDidCreate')
// // trigger save
// vscode.commands.executeCommand('coderoad.run_test', null, () => {
// // cleanup watcher on success
// disposeWatcher(listener)
// })
// })
// watchers[listener].onDidDelete(() => {
// console.log('onDidDelete')
// // trigger save
// vscode.commands.executeCommand('coderoad.run_test', null, () => {
// // cleanup watcher on success
// disposeWatcher(listener)
// })
// })
// }
// }
// } else {
// // remove all watchers
// for (const listener of Object.keys(watchers)) {
// disposeWatcher(listener)
// }
// }
if (listeners) {
console.log('listeners')
for (const listener of listeners) {
if (!watchers[listener]) {
const pattern = new vscode.RelativePattern(
vscode.workspace.getWorkspaceFolder(workspaceRoot.uri)!,
listener
)
console.log(pattern)
const listen = vscode.workspace.createFileSystemWatcher(
pattern
)
watchers[listener] = listen
watchers[listener].onDidChange(() => {
console.log('onDidChange')
// trigger save
vscode.commands.executeCommand('coderoad.run_test', null, () => {
// cleanup watcher on success
disposeWatcher(listener)
})
})
watchers[listener].onDidCreate(() => {
console.log('onDidCreate')
// trigger save
vscode.commands.executeCommand('coderoad.run_test', null, () => {
// cleanup watcher on success
disposeWatcher(listener)
})
})
watchers[listener].onDidDelete(() => {
console.log('onDidDelete')
// trigger save
vscode.commands.executeCommand('coderoad.run_test', null, () => {
// cleanup watcher on success
disposeWatcher(listener)
})
})
}
}
} else {
// remove all watchers
for (const listener of Object.keys(watchers)) {
disposeWatcher(listener)
}
}

// run command
if (commands) {
Expand Down
1 change: 1 addition & 0 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export interface MachineStateSchema {
TestRunning: {}
TestPass: {}
TestFail: {}
TestError: {}
StepNext: {}
LevelComplete: {}
}
Expand Down
1 change: 1 addition & 0 deletions web-app/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
8 changes: 7 additions & 1 deletion web-app/src/services/state/machine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,15 @@ export const machine = Machine<CR.MachineContext, CR.MachineStateSchema, CR.Mach
actions: ['updateStepProgress']
},
TEST_FAIL: 'TestFail',
TEST_ERROR: 'Normal'
TEST_ERROR: 'TestError'
},
},
TestError: {
onEntry: ['testFail'],
after: {
0: 'Normal'
}
},
TestPass: {
onExit: ['updateStepPosition'],
after: {
Expand Down