@@ -2,7 +2,7 @@ import { loggerMock } from '@sim/testing'
22import { describe , expect , it , vi } from 'vitest'
33import { ExecutionState } from '@/executor/execution/state'
44import { BlockResolver } from './block'
5- import type { ResolutionContext } from './reference'
5+ import { RESOLVED_EMPTY , type ResolutionContext } from './reference'
66
77vi . mock ( '@sim/logger' , ( ) => loggerMock )
88vi . mock ( '@/blocks/registry' , async ( ) => {
@@ -134,15 +134,18 @@ describe('BlockResolver', () => {
134134 expect ( resolver . resolve ( '<source.items.1.id>' , ctx ) ) . toBe ( 2 )
135135 } )
136136
137- it . concurrent ( 'should return undefined for non-existent path when no schema defined' , ( ) => {
138- const workflow = createTestWorkflow ( [ { id : 'source' , type : 'unknown_block_type' } ] )
139- const resolver = new BlockResolver ( workflow )
140- const ctx = createTestContext ( 'current' , {
141- source : { existing : 'value' } ,
142- } )
137+ it . concurrent (
138+ 'should return RESOLVED_EMPTY for non-existent path when no schema defined' ,
139+ ( ) => {
140+ const workflow = createTestWorkflow ( [ { id : 'source' , type : 'unknown_block_type' } ] )
141+ const resolver = new BlockResolver ( workflow )
142+ const ctx = createTestContext ( 'current' , {
143+ source : { existing : 'value' } ,
144+ } )
143145
144- expect ( resolver . resolve ( '<source.nonexistent>' , ctx ) ) . toBeUndefined ( )
145- } )
146+ expect ( resolver . resolve ( '<source.nonexistent>' , ctx ) ) . toBe ( RESOLVED_EMPTY )
147+ }
148+ )
146149
147150 it . concurrent ( 'should throw error for path not in output schema' , ( ) => {
148151 const workflow = createTestWorkflow ( [
@@ -162,7 +165,7 @@ describe('BlockResolver', () => {
162165 expect ( ( ) => resolver . resolve ( '<source.invalidField>' , ctx ) ) . toThrow ( / A v a i l a b l e f i e l d s : / )
163166 } )
164167
165- it . concurrent ( 'should return undefined for path in schema but missing in data' , ( ) => {
168+ it . concurrent ( 'should return RESOLVED_EMPTY for path in schema but missing in data' , ( ) => {
166169 const workflow = createTestWorkflow ( [
167170 {
168171 id : 'source' ,
@@ -175,7 +178,7 @@ describe('BlockResolver', () => {
175178 } )
176179
177180 expect ( resolver . resolve ( '<source.stdout>' , ctx ) ) . toBe ( 'log output' )
178- expect ( resolver . resolve ( '<source.result>' , ctx ) ) . toBeUndefined ( )
181+ expect ( resolver . resolve ( '<source.result>' , ctx ) ) . toBe ( RESOLVED_EMPTY )
179182 } )
180183
181184 it . concurrent (
@@ -191,7 +194,7 @@ describe('BlockResolver', () => {
191194 const resolver = new BlockResolver ( workflow )
192195 const ctx = createTestContext ( 'current' , { } )
193196
194- expect ( resolver . resolve ( '<workflow.childTraceSpans>' , ctx ) ) . toBeUndefined ( )
197+ expect ( resolver . resolve ( '<workflow.childTraceSpans>' , ctx ) ) . toBe ( RESOLVED_EMPTY )
195198 }
196199 )
197200
@@ -208,7 +211,7 @@ describe('BlockResolver', () => {
208211 const resolver = new BlockResolver ( workflow )
209212 const ctx = createTestContext ( 'current' , { } )
210213
211- expect ( resolver . resolve ( '<workflowinput.childTraceSpans>' , ctx ) ) . toBeUndefined ( )
214+ expect ( resolver . resolve ( '<workflowinput.childTraceSpans>' , ctx ) ) . toBe ( RESOLVED_EMPTY )
212215 }
213216 )
214217
@@ -225,20 +228,35 @@ describe('BlockResolver', () => {
225228 const resolver = new BlockResolver ( workflow )
226229 const ctx = createTestContext ( 'current' , { } )
227230
228- expect ( resolver . resolve ( '<hitl.response>' , ctx ) ) . toBeUndefined ( )
229- expect ( resolver . resolve ( '<hitl.submission>' , ctx ) ) . toBeUndefined ( )
230- expect ( resolver . resolve ( '<hitl.resumeInput>' , ctx ) ) . toBeUndefined ( )
231+ expect ( resolver . resolve ( '<hitl.response>' , ctx ) ) . toBe ( RESOLVED_EMPTY )
232+ expect ( resolver . resolve ( '<hitl.submission>' , ctx ) ) . toBe ( RESOLVED_EMPTY )
233+ expect ( resolver . resolve ( '<hitl.resumeInput>' , ctx ) ) . toBe ( RESOLVED_EMPTY )
231234 }
232235 )
233236
234- it . concurrent ( 'should return undefined for non-existent block' , ( ) => {
237+ it . concurrent ( 'should return undefined for block not in workflow ' , ( ) => {
235238 const workflow = createTestWorkflow ( [ { id : 'existing' } ] )
236239 const resolver = new BlockResolver ( workflow )
237240 const ctx = createTestContext ( 'current' , { } )
238241
239242 expect ( resolver . resolve ( '<nonexistent>' , ctx ) ) . toBeUndefined ( )
240243 } )
241244
245+ it . concurrent ( 'should return RESOLVED_EMPTY for block in workflow that did not execute' , ( ) => {
246+ const workflow = createTestWorkflow ( [
247+ { id : 'start-block' , name : 'Start' , type : 'start_trigger' } ,
248+ { id : 'slack-block' , name : 'Slack' , type : 'slack_trigger' } ,
249+ ] )
250+ const resolver = new BlockResolver ( workflow )
251+ const ctx = createTestContext ( 'current' , {
252+ 'slack-block' : { message : 'hello from slack' } ,
253+ } )
254+
255+ expect ( resolver . resolve ( '<slack.message>' , ctx ) ) . toBe ( 'hello from slack' )
256+ expect ( resolver . resolve ( '<start>' , ctx ) ) . toBe ( RESOLVED_EMPTY )
257+ expect ( resolver . resolve ( '<start.input>' , ctx ) ) . toBe ( RESOLVED_EMPTY )
258+ } )
259+
242260 it . concurrent ( 'should fall back to context blockStates' , ( ) => {
243261 const workflow = createTestWorkflow ( [ { id : 'source' } ] )
244262 const resolver = new BlockResolver ( workflow )
@@ -1012,24 +1030,24 @@ describe('BlockResolver', () => {
10121030 expect ( resolver . resolve ( '<source.other>' , ctx ) ) . toBe ( 'exists' )
10131031 } )
10141032
1015- it . concurrent ( 'should handle output with undefined values' , ( ) => {
1033+ it . concurrent ( 'should return RESOLVED_EMPTY for output with undefined values' , ( ) => {
10161034 const workflow = createTestWorkflow ( [ { id : 'source' , type : 'unknown_block_type' } ] )
10171035 const resolver = new BlockResolver ( workflow )
10181036 const ctx = createTestContext ( 'current' , {
10191037 source : { value : undefined , other : 'exists' } ,
10201038 } )
10211039
1022- expect ( resolver . resolve ( '<source.value>' , ctx ) ) . toBeUndefined ( )
1040+ expect ( resolver . resolve ( '<source.value>' , ctx ) ) . toBe ( RESOLVED_EMPTY )
10231041 } )
10241042
1025- it . concurrent ( 'should return undefined for deeply nested non-existent path' , ( ) => {
1043+ it . concurrent ( 'should return RESOLVED_EMPTY for deeply nested non-existent path' , ( ) => {
10261044 const workflow = createTestWorkflow ( [ { id : 'source' , type : 'unknown_block_type' } ] )
10271045 const resolver = new BlockResolver ( workflow )
10281046 const ctx = createTestContext ( 'current' , {
10291047 source : { level1 : { level2 : { } } } ,
10301048 } )
10311049
1032- expect ( resolver . resolve ( '<source.level1.level2.level3>' , ctx ) ) . toBeUndefined ( )
1050+ expect ( resolver . resolve ( '<source.level1.level2.level3>' , ctx ) ) . toBe ( RESOLVED_EMPTY )
10331051 } )
10341052 } )
10351053} )
0 commit comments