@@ -24,6 +24,17 @@ fn node_assert_eq() -> node::Expr {
2424 node:: expr ( "(begin (assert! (equal? $l $r)))" ) . unwrap ( )
2525}
2626
27+ fn node_number ( ) -> node:: Expr {
28+ node:: expr (
29+ "
30+ (let ((x $x))
31+ (set! state (if (number? x) x state))
32+ state)
33+ " ,
34+ )
35+ . unwrap ( )
36+ }
37+
2738// Helper trait for debugging the graph.
2839trait DebugNode : Debug + Node { }
2940impl < T > DebugNode for T where T : Debug + Node { }
@@ -169,16 +180,6 @@ fn test_graph_nested_counter() {
169180 )
170181 . unwrap ( ) ;
171182
172- // The number node for receiving the result.
173- let number = node:: expr (
174- "
175- (let ((x $x))
176- (set! state (if (number? x) x state))
177- state)
178- " ,
179- )
180- . unwrap ( ) ;
181-
182183 // Graph A.
183184 let mut ga = GraphNode :: default ( ) ;
184185 let inlet = ga. add_node ( Box :: new ( node:: graph:: Inlet ) as Box < dyn DebugNode > ) ;
@@ -191,11 +192,11 @@ fn test_graph_nested_counter() {
191192 let mut gb = petgraph:: graph:: DiGraph :: new ( ) ;
192193 let push = gb. add_node ( Box :: new ( node_push ( ) ) as Box < dyn DebugNode > ) ;
193194 let graph_a = gb. add_node ( Box :: new ( ga) as Box < _ > ) ;
194- let number = gb. add_node ( Box :: new ( number ) as Box < _ > ) ;
195+ let number = gb. add_node ( Box :: new ( node_number ( ) ) as Box < _ > ) ;
195196 gb. add_edge ( push, graph_a, Edge :: from ( ( 0 , 0 ) ) ) ;
196197 gb. add_edge ( graph_a, number, Edge :: from ( ( 0 , 0 ) ) ) ;
197198
198- // Generate the module, which should have just one top-level expr for `push` .
199+ // Generate the module.
199200 let module = gantz_core:: codegen:: module ( & gb) ;
200201
201202 // Create the VM.
@@ -211,8 +212,8 @@ fn test_graph_nested_counter() {
211212 vm. run ( f. to_pretty ( 100 ) ) . unwrap ( ) ;
212213 }
213214
214- // Increment the nested counter by pushing evaluation. The first is `0`, the
215- // second is `1`.
215+ // Increment the nested counter by pushing evaluation.
216+ // The first is `0`, the second is `1`.
216217 vm. call_function_by_name_with_args ( & push_eval_fn_name ( & [ push. index ( ) ] ) , vec ! [ ] )
217218 . unwrap ( ) ;
218219 vm. call_function_by_name_with_args ( & push_eval_fn_name ( & [ push. index ( ) ] ) , vec ! [ ] )
@@ -236,3 +237,82 @@ fn test_graph_nested_counter() {
236237 . expect ( "number state was `None`" ) ;
237238 assert_eq ! ( number_state, 1 ) ;
238239}
240+
241+ // A simple test for pushing evaluation from a node within a nested graph.
242+ //
243+ // GRAPH A
244+ //
245+ // --------
246+ // | Push |
247+ // -+------
248+ // |
249+ // -+----
250+ // | 42 |
251+ // -+----
252+ // |
253+ // -+--------
254+ // | Outlet |
255+ // ----------
256+ //
257+ // GRAPH B
258+ //
259+ // -+---------
260+ // | GRAPH A |
261+ // -+---------
262+ // |
263+ // -+--------
264+ // | number |
265+ // ----------
266+ //
267+ // A simple-as-possible demonstration of pushing evaluation from within a nested
268+ // node, and propagating that evaluation through the outlets of the graph node.
269+ #[ test]
270+ #[ ignore = "requires #78, #77" ]
271+ fn test_graph_nested_push_eval ( ) {
272+ // GRAPH A
273+ let mut ga = GraphNode :: default ( ) ;
274+ let push = ga. add_node ( Box :: new ( node_push ( ) ) as Box < dyn DebugNode > ) ;
275+ let int = ga. add_node ( Box :: new ( node_int ( 42 ) ) as Box < _ > ) ;
276+ let outlet = ga. add_node ( Box :: new ( node:: graph:: Outlet ) as Box < _ > ) ;
277+ ga. add_edge ( push, int, Edge :: from ( ( 0 , 0 ) ) ) ;
278+ ga. add_edge ( int, outlet, Edge :: from ( ( 0 , 0 ) ) ) ;
279+
280+ // Graph B.
281+ let mut gb = petgraph:: graph:: DiGraph :: new ( ) ;
282+ let graph_a = gb. add_node ( Box :: new ( ga) as Box < dyn DebugNode > ) ;
283+ let number = gb. add_node ( Box :: new ( node_number ( ) ) as Box < _ > ) ;
284+ gb. add_edge ( graph_a, number, Edge :: from ( ( 0 , 0 ) ) ) ;
285+
286+ // Generate the module.
287+ let module = gantz_core:: codegen:: module ( & gb) ;
288+
289+ // Create the VM.
290+ let mut vm = Engine :: new_base ( ) ;
291+
292+ // Initialise the node state vars.
293+ vm. register_value ( ROOT_STATE , SteelVal :: empty_hashmap ( ) ) ;
294+ gantz_core:: graph:: register ( & gb, & [ ] , & mut vm) ;
295+
296+ // Register the fns.
297+ for f in module {
298+ println ! ( "{}\n " , f. to_pretty( 100 ) ) ;
299+ vm. run ( f. to_pretty ( 100 ) ) . unwrap ( ) ;
300+ }
301+
302+ // Call the nested push node's eval fn.
303+ let push_path = [ graph_a. index ( ) , push. index ( ) ] ;
304+ vm. call_function_by_name_with_args ( & push_eval_fn_name ( & push_path) , vec ! [ ] )
305+ . unwrap ( ) ;
306+
307+ // Now check that the outlet's state is `42`.
308+ let outlet_state = node:: state:: extract :: < u32 > ( & vm, & [ graph_a. index ( ) , outlet. index ( ) ] )
309+ . expect ( "failed to extract outlet state" )
310+ . expect ( "outlet state was `None`" ) ;
311+ assert_eq ! ( outlet_state, 42 ) ;
312+
313+ // Check that the number in the root graph was updated from the outlet.
314+ let number_state = node:: state:: extract :: < u32 > ( & vm, & [ number. index ( ) ] )
315+ . expect ( "failed to extract number state" )
316+ . expect ( "number state was `None`" ) ;
317+ assert_eq ! ( number_state, 42 ) ;
318+ }
0 commit comments