Skip to content

Send setup actions even when no setup for position tracking #298

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 1 commit into from
Apr 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/actions/setupActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ interface SetupActions {
}

export const setupActions = async ({ actions, send, path }: SetupActions): Promise<void> => {
if (!actions) {
return
}
const { commands, commits, files, watchers } = actions

// validate commit is new
Expand Down
8 changes: 5 additions & 3 deletions src/actions/utils/loadWatchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ const loadWatchers = (watchers: string[]) => {
fsWatcher.on('change', (path, event) => {
const now = +new Date()
if (!lastFire || lastFire - now > 1000) {
vscode.commands.executeCommand(COMMANDS.RUN_TEST, null, () => {
// cleanup watcher on success
disposeWatcher(watcher)
vscode.commands.executeCommand(COMMANDS.RUN_TEST, {
onSuccess: () => {
// cleanup watcher on success
disposeWatcher(watcher)
},
})
}
})
Expand Down
14 changes: 8 additions & 6 deletions src/channel/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ class Channel implements Channel {
alreadyConfigured: true,
})
// update the current stepId on startup
vscode.commands.executeCommand(COMMANDS.SET_CURRENT_STEP, action.payload)
vscode.commands.executeCommand(COMMANDS.SET_CURRENT_POSITION, action.payload.position)
} catch (e) {
const error = {
type: 'UnknownError',
Expand Down Expand Up @@ -286,14 +286,15 @@ class Channel implements Channel {
return
// load step actions (git commits, commands, open files)
case 'SETUP_ACTIONS':
await vscode.commands.executeCommand(COMMANDS.SET_CURRENT_STEP, action.payload)
setupActions({ actions: action.payload, send: this.send })
await vscode.commands.executeCommand(COMMANDS.SET_CURRENT_POSITION, action.payload.position)
setupActions({ actions: action.payload.actions, send: this.send })
return
// load solution step actions (git commits, commands, open files)
case 'SOLUTION_ACTIONS':
await solutionActions({ actions: action.payload, send: this.send })
await vscode.commands.executeCommand(COMMANDS.SET_CURRENT_POSITION, action.payload.position)
await solutionActions({ actions: action.payload.actions, send: this.send })
// run test following solution to update position
vscode.commands.executeCommand(COMMANDS.RUN_TEST, action.payload)
vscode.commands.executeCommand(COMMANDS.RUN_TEST)
return

default:
Expand Down Expand Up @@ -328,12 +329,13 @@ class Channel implements Channel {

switch (actionType) {
case 'TEST_PASS':
console.log('TEST_PASS', action)
const tutorial = this.context.tutorial.get()
if (!tutorial) {
throw new Error('Error with current tutorial. Tutorial may be missing an id.')
}
// update local storage stepProgress
const progress = this.context.progress.setStepComplete(tutorial, action.payload.stepId)
const progress = this.context.progress.setStepComplete(tutorial, action.payload.position.stepId)
this.context.position.setPositionFromProgress(tutorial, progress)
saveCommit()
}
Expand Down
42 changes: 25 additions & 17 deletions src/editor/commands.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import * as T from 'typings'
import * as TT from 'typings/tutorial'
import * as vscode from 'vscode'
import createTestRunner, { Payload } from '../services/testRunner'
import createTestRunner from '../services/testRunner'
import { setupActions } from '../actions/setupActions'
import createWebView from '../webview'
import logger from '../services/logger'

export const COMMANDS = {
START: 'coderoad.start',
OPEN_WEBVIEW: 'coderoad.open_webview',
CONFIG_TEST_RUNNER: 'coderoad.config_test_runner',
RUN_TEST: 'coderoad.run_test',
SET_CURRENT_STEP: 'coderoad.set_current_step',
SET_CURRENT_POSITION: 'coderoad.set_current_position',
}

interface CreateCommandProps {
Expand All @@ -20,7 +22,7 @@ interface CreateCommandProps {
export const createCommands = ({ extensionPath, workspaceState }: CreateCommandProps) => {
// React panel webview
let webview: any
let currentStepId: string | null = ''
let currentPosition: T.Position
let testRunner: any

return {
Expand Down Expand Up @@ -55,32 +57,38 @@ export const createCommands = ({ extensionPath, workspaceState }: CreateCommandP
await setupActions({ actions: config.actions, send: webview.send, path: config.path })
}
testRunner = createTestRunner(config, {
onSuccess: (payload: Payload) => {
onSuccess: (position: T.Position) => {
logger('test pass position', position)
// send test pass message back to client
webview.send({ type: 'TEST_PASS', payload })
webview.send({ type: 'TEST_PASS', payload: { position } })
},
onFail: (payload: Payload, message: string) => {
onFail: (position: T.Position, message: string) => {
// send test fail message back to client with failure message
webview.send({ type: 'TEST_FAIL', payload: { ...payload, message } })
webview.send({ type: 'TEST_FAIL', payload: { position, message } })
},
onError: (payload: Payload) => {
// send test error message back to client
webview.send({ type: 'TEST_ERROR', payload })
onError: (position: T.Position) => {
// TODO: send test error message back to client
const message = 'Error with test runner'
webview.send({ type: 'TEST_ERROR', payload: { position, message } })
},
onRun: (payload: Payload) => {
onRun: (position: T.Position) => {
// send test run message back to client
webview.send({ type: 'TEST_RUNNING', payload })
webview.send({ type: 'TEST_RUNNING', payload: { position } })
},
})
},
[COMMANDS.SET_CURRENT_STEP]: ({ stepId }: Payload) => {
[COMMANDS.SET_CURRENT_POSITION]: (position: T.Position) => {
// set from last setup stepAction
currentStepId = stepId
currentPosition = position
},
[COMMANDS.RUN_TEST]: (current: Payload | undefined, onSuccess: () => void) => {
[COMMANDS.RUN_TEST]: (callback?: { onSuccess: () => void }) => {
logger('run test current', currentPosition)
// use stepId from client, or last set stepId
const payload: Payload = { stepId: current && current.stepId?.length ? current.stepId : currentStepId }
testRunner(payload, onSuccess)
// const position: T.Position = {
// ...current,
// stepId: current && current.position.stepId?.length ? current.position.stepId : currentPosition.stepId,
// }
testRunner(currentPosition, callback?.onSuccess)
},
}
}
2 changes: 1 addition & 1 deletion src/services/logger/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LOG } from '../../environment'

export type Log = string | object | null
export type Log = string | object | null | undefined

const logger = (...messages: Log[]): void => {
if (!LOG) {
Expand Down
32 changes: 15 additions & 17 deletions src/services/testRunner/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { TutorialTestRunnerConfig } from 'typings/tutorial'
import * as T from 'typings'
import * as TT from 'typings/tutorial'
import { exec } from '../node'
import logger from '../logger'
import parser from './parser'
Expand All @@ -7,22 +8,19 @@ import onError from '../sentry/onError'
import { clearOutput, displayOutput } from './output'
import { formatFailOutput } from './formatOutput'

export interface Payload {
stepId: string | null
}

interface Callbacks {
onSuccess(payload: Payload): void
onFail(payload: Payload, message: string): void
onRun(payload: Payload): void
onError(payload: Payload): void
onSuccess(position: T.Position): void
onFail(position: T.Position, message: string): void
onRun(position: T.Position): void
onError(position: T.Position): void
}

const failChannelName = 'CodeRoad (Tests)'
const logChannelName = 'CodeRoad (Logs)'

const createTestRunner = (config: TutorialTestRunnerConfig, callbacks: Callbacks) => {
return async (payload: Payload, onSuccess?: () => void): Promise<void> => {
const createTestRunner = (config: TT.TutorialTestRunnerConfig, callbacks: Callbacks) => {
return async (position: T.Position, onSuccess?: () => void): Promise<void> => {
logger('createTestRunner', position)
const startTime = throttle()
// throttle time early
if (!startTime) {
Expand All @@ -32,7 +30,7 @@ const createTestRunner = (config: TutorialTestRunnerConfig, callbacks: Callbacks
logger('------------------- RUN TEST -------------------')

// flag as running
callbacks.onRun(payload)
callbacks.onRun(position)

let result: { stdout: string | undefined; stderr: string | undefined }
try {
Expand All @@ -59,12 +57,12 @@ const createTestRunner = (config: TutorialTestRunnerConfig, callbacks: Callbacks
// FAIL also trigger stderr
if (stdout && stdout.length && !tap.ok) {
const firstFailMessage = tap.failed[0].message
callbacks.onFail(payload, firstFailMessage)
callbacks.onFail(position, firstFailMessage)
const output = formatFailOutput(tap)
displayOutput({ channel: failChannelName, text: output, show: true })
return
} else {
callbacks.onError(payload)
callbacks.onError(position)
// open terminal with error string
displayOutput({ channel: failChannelName, text: stderr, show: true })
return
Expand All @@ -74,14 +72,14 @@ const createTestRunner = (config: TutorialTestRunnerConfig, callbacks: Callbacks
// PASS
if (tap.ok) {
clearOutput(failChannelName)
callbacks.onSuccess(payload)
callbacks.onSuccess(position)
if (onSuccess) {
onSuccess()
}
} else {
// should never get here
onError(new Error(`Error with running test ${JSON.stringify(payload)}`))
callbacks.onError(payload)
onError(new Error(`Error with running test ${JSON.stringify(position)}`))
callbacks.onError(position)
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/webview/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ async function render(panel: vscode.WebviewPanel, rootPath: string) {
const createUri = (_filePath: string): any => {
const filePath = (_filePath.startsWith('vscode') ? _filePath.substr(16) : _filePath).replace('///', '\\')

// @ts-ignore
return panel.webview.asWebviewUri(vscode.Uri.file(path.join(rootPath, filePath)))
}

Expand Down
2 changes: 1 addition & 1 deletion web-app/src/services/state/actions/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ const contextActions: ActionFunctionMap<T.MachineContext, T.MachineEvent> = {
// update progress by tracking completed
const currentProgress: T.Progress = context.progress

const { stepId } = event.payload
const { stepId } = event.payload.position

currentProgress.steps[stepId] = true

Expand Down
36 changes: 24 additions & 12 deletions web-app/src/services/state/actions/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,24 @@ export default (editorSend: any) => ({
type: 'EDITOR_TUTORIAL_CONTINUE_CONFIG',
payload: {
// pass position because current stepId or first stepId will be empty
stepId: context.position.stepId,
position: context.position,
},
})
},
loadLevel(context: CR.MachineContext): void {
const level: TT.Level = selectors.currentLevel(context)
if (level.setup) {
// load step actions
editorSend({
type: 'SETUP_ACTIONS',
payload: level.setup,
})
}
const step: TT.Step | null = selectors.currentStep(context)
// load step actions
editorSend({
type: 'SETUP_ACTIONS',
payload: {
position: {
stepId: step?.id || null,
levelId: level.id,
},
actions: level.setup,
},
})
},
loadStep(context: CR.MachineContext): void {
const step: TT.Step | null = selectors.currentStep(context)
Expand All @@ -43,8 +48,12 @@ export default (editorSend: any) => ({
editorSend({
type: 'SETUP_ACTIONS',
payload: {
stepId: step.id,
...step.setup,
// set position here
position: {
stepId: step.id,
levelId: context.position.levelId,
},
actions: step.setup,
},
})
}
Expand All @@ -56,8 +65,11 @@ export default (editorSend: any) => ({
editorSend({
type: 'SOLUTION_ACTIONS',
payload: {
stepId: step.id,
...step.solution,
position: {
stepId: step.id,
levelId: context.position.levelId,
},
actions: step.solution,
},
})
}
Expand Down