11import chalk from 'chalk' ;
22import type { APIClient } from './APIClient' ;
33import type { EventManager } from './EventManager' ;
4- import type { ExpectEngine } from './ExpectEngine' ;
5- import { parseTime } from './utils/parseTime' ;
64
7- const validStepKeys = [ 'name' ] ;
8-
9- export interface ISetControlParams {
10- 'part-id' : string ;
11- control : string ;
12- value : number ;
5+ export interface IScenarioCommand {
6+ validate ?( params : any ) : boolean ;
7+ run ( scenario : TestScenario , client : APIClient , params : any ) : Promise < void > ;
138}
149
10+ const validStepKeys = [ 'name' ] ;
11+
1512export interface IStepDefinition {
1613 name ?: string ;
17- 'wait-serial' : string ;
18- delay : string ;
19- 'set-control' : ISetControlParams ;
14+ [ key : string ] : any ;
2015}
2116
2217export interface IScenarioDefinition {
@@ -31,11 +26,13 @@ export class TestScenario {
3126 private stepIndex = 0 ;
3227 private client ?: APIClient ;
3328
34- constructor (
35- readonly scenario : IScenarioDefinition ,
36- readonly eventManager : EventManager ,
37- readonly expectEngine : ExpectEngine
38- ) { }
29+ readonly handlers : Record < string , IScenarioCommand > = { } ;
30+
31+ constructor ( readonly scenario : IScenarioDefinition , readonly eventManager : EventManager ) { }
32+
33+ registerCommands ( commands : Record < string , IScenarioCommand > ) {
34+ Object . assign ( this . handlers , commands ) ;
35+ }
3936
4037 validate ( ) {
4138 const { scenario } = this ;
@@ -71,26 +68,24 @@ export class TestScenario {
7168 async start ( client : APIClient ) {
7269 this . stepIndex = 0 ;
7370 this . client = client ;
74- await this . nextStep ( ) ;
75- }
76-
77- async nextStep ( ) {
78- if ( this . client ?. running ) {
79- void this . client . simPause ( ) ;
71+ for ( const step of this . scenario . steps ) {
72+ if ( client . running ) {
73+ void client . simPause ( ) ;
74+ }
75+ if ( step . name ) {
76+ this . log ( chalk `{gray Executing step:} {yellow ${ step . name } ` ) ;
77+ }
78+ await this . executeStep ( client , step ) ;
8079 }
80+ this . log ( chalk `{green Scenario completed successfully}` ) ;
81+ process . exit ( 0 ) ;
82+ }
8183
82- const step = this . scenario . steps [ this . stepIndex ] ;
83- if ( step == null ) {
84- this . log ( chalk `{green Scenario completed successfully}` ) ;
85- process . exit ( 0 ) ;
86- }
87- if ( step . name ) {
88- this . log ( chalk `{gray Executing step:} {yellow ${ step . name } ` ) ;
89- }
90- for ( const key of Object . keys ( this . handlers ) as Array < keyof typeof this . handlers > ) {
84+ async executeStep ( client : APIClient , step : IStepDefinition ) {
85+ for ( const key of Object . keys ( this . handlers ) ) {
9186 if ( key in step ) {
9287 const value = step [ key ] ;
93- void this . handlers [ key ] ( value as any , step ) ;
88+ await this . handlers [ key ] . run ( this , client , value ) ;
9489 this . stepIndex ++ ;
9590 return ;
9691 }
@@ -103,37 +98,13 @@ export class TestScenario {
10398 console . log ( chalk `{cyan [${ this . scenario . name } ]}` , message ) ;
10499 }
105100
101+ fail ( message : string ) {
102+ throw new Error ( `[${ this . client ?. lastNanos } ns] ${ message } ` ) ;
103+ }
104+
106105 async resume ( ) {
107106 await this . client ?. simResume (
108107 this . eventManager . timeToNextEvent >= 0 ? this . eventManager . timeToNextEvent : undefined
109108 ) ;
110109 }
111-
112- handlers = {
113- 'wait-serial' : async ( text : string ) => {
114- this . expectEngine . expectTexts . push ( text ) ;
115- this . expectEngine . once ( 'match' , ( ) => {
116- this . log ( chalk `Expected text matched: {green "${ text } "}` ) ;
117- const textIndex = this . expectEngine . expectTexts . indexOf ( text ) ;
118- if ( textIndex >= 0 ) {
119- this . expectEngine . expectTexts . splice ( textIndex , 1 ) ;
120- }
121- void this . nextStep ( ) ;
122- } ) ;
123- await this . resume ( ) ;
124- } ,
125- delay : async ( value : string , step : IStepDefinition ) => {
126- const nanos = parseTime ( value ) ;
127- const targetNanos = ( this . client ?. lastNanos ?? 0 ) + nanos ;
128- this . log ( chalk `delay {yellow ${ value } }` ) ;
129- this . eventManager . at ( targetNanos , ( ) => {
130- void this . nextStep ( ) ;
131- } ) ;
132- await this . resume ( ) ;
133- } ,
134- 'set-control' : async ( params : ISetControlParams ) => {
135- await this . client ?. controlSet ( params [ 'part-id' ] , params . control , params . value ) ;
136- await this . nextStep ( ) ;
137- } ,
138- } ;
139110}
0 commit comments