@@ -42,3 +42,127 @@ tape("variable.import(name, module) can import a variable that depends on a muta
4242 const baz = main . variable ( true ) . define ( "baz" , [ "bar" ] , bar => `baz-${ bar } ` ) ;
4343 test . deepEqual ( await valueof ( baz ) , { value : "baz-13" } ) ;
4444} ) ;
45+
46+ tape ( "variable.import() allows non-circular imported values from circular imports" , async test => {
47+ const runtime = new Runtime ( ) ;
48+ const a = runtime . module ( ) ;
49+ const b = runtime . module ( ) ;
50+ a . define ( "foo" , [ ] , ( ) => "foo" ) ;
51+ b . define ( "bar" , [ ] , ( ) => "bar" ) ;
52+ a . import ( "bar" , b ) ;
53+ b . import ( "foo" , a ) ;
54+ const afoobar = a . variable ( true ) . define ( "foobar" , [ "foo" , "bar" ] , ( foo , bar ) => 'a' + foo + bar ) ;
55+ const bfoobar = b . variable ( true ) . define ( "foobar" , [ "foo" , "bar" ] , ( foo , bar ) => 'b' + foo + bar ) ;
56+ test . deepEqual ( await valueof ( afoobar ) , { value : "afoobar" } ) ;
57+ test . deepEqual ( await valueof ( bfoobar ) , { value : "bfoobar" } ) ;
58+ } ) ;
59+
60+ tape ( "variable.import() fails when importing creates a circular reference" , async test => {
61+ const runtime = new Runtime ( ) ;
62+ const a = runtime . module ( ) ;
63+ const b = runtime . module ( ) ;
64+ a . import ( "bar" , b ) ;
65+ a . define ( "foo" , [ "bar" ] , ( bar ) => `foo${ bar } ` ) ;
66+ b . import ( "foo" , a ) ;
67+ b . define ( "bar" , [ "foo" ] , ( foo ) => `${ foo } bar` ) ;
68+ const afoobar = a . variable ( true ) . define ( "foobar" , [ "foo" , "bar" ] , ( foo , bar ) => 'a' + foo + bar ) ;
69+ const bbarfoo = b . variable ( true ) . define ( "barfoo" , [ "bar" , "foo" ] , ( bar , foo ) => 'b' + bar + foo ) ;
70+ test . deepEqual ( await valueof ( afoobar ) , { error : "RuntimeError: foo could not be resolved" } ) ;
71+ test . deepEqual ( await valueof ( bbarfoo ) , { error : "RuntimeError: bar could not be resolved" } ) ;
72+ } ) ;
73+
74+ tape (
75+ "variable.import() fails to resolve variables derived from a direct circular import with" ,
76+ async test => {
77+ const runtime = new Runtime ( ) ;
78+ let a1 , b1 , a2 , b2 ;
79+
80+ function define1 ( ) {
81+ const main = runtime . module ( ) ;
82+ a1 = main . variable ( true ) . define ( "a" , function ( ) {
83+ return 1 ;
84+ } ) ;
85+ b1 = main . variable ( true ) . define ( [ "b" ] , function ( b ) {
86+ return b ;
87+ } ) ;
88+ const child1 = runtime . module ( define2 ) . derive ( [ "a" ] , main ) ;
89+ main . import ( "b" , child1 ) ;
90+ return main ;
91+ }
92+
93+ function define2 ( ) {
94+ const main = runtime . module ( ) ;
95+ b2 = main . variable ( true ) . define ( "b" , function ( ) {
96+ return 2 ;
97+ } ) ;
98+ a2 = main . variable ( true ) . define ( [ "a" ] , function ( a ) {
99+ return a ;
100+ } ) ;
101+ const child1 = runtime . module ( define1 ) . derive ( [ "b" ] , main ) ;
102+ main . import ( "a" , child1 ) ;
103+ return main ;
104+ }
105+ define1 ( ) ;
106+
107+ test . deepEqual ( await valueof ( a1 ) , { value : 1 } ) ;
108+ test . deepEqual ( await valueof ( b1 ) , { error : 'RuntimeError: b could not be resolved' } ) ;
109+ test . deepEqual ( await valueof ( a2 ) , { error : 'RuntimeError: a could not be resolved' } ) ;
110+ test . deepEqual ( await valueof ( b2 ) , { value : 2 } ) ;
111+ }
112+ ) ;
113+
114+ tape (
115+ "variable.import() also fails to resolve variables derived from an indirectly circular import with" ,
116+ async test => {
117+ const runtime = new Runtime ( ) ;
118+ let a , b , c , importA , importB , importC ;
119+
120+ function define1 ( ) {
121+ const main = runtime . module ( ) ;
122+ a = main . variable ( true ) . define ( "a" , function ( ) {
123+ return 1 ;
124+ } ) ;
125+ importC = main . variable ( true ) . define ( [ "c" ] , function ( c ) {
126+ return c ;
127+ } ) ;
128+ const child3 = runtime . module ( define3 ) . derive ( [ "a" ] , main ) ;
129+ main . import ( "c" , child3 ) ;
130+ return main ;
131+ }
132+
133+ function define2 ( ) {
134+ const main = runtime . module ( ) ;
135+ b = main . variable ( true ) . define ( "b" , function ( ) {
136+ return 2 ;
137+ } ) ;
138+ importA = main . variable ( true ) . define ( [ "a" ] , function ( a ) {
139+ return a ;
140+ } ) ;
141+ const child1 = runtime . module ( define1 ) . derive ( [ "b" ] , main ) ;
142+ main . import ( "a" , child1 ) ;
143+ return main ;
144+ }
145+
146+ function define3 ( ) {
147+ const main = runtime . module ( ) ;
148+ c = main . variable ( true ) . define ( "c" , function ( ) {
149+ return 3 ;
150+ } ) ;
151+ importB = main . variable ( true ) . define ( [ "b" ] , function ( b ) {
152+ return b ;
153+ } ) ;
154+ const child2 = runtime . module ( define2 ) . derive ( [ "c" ] , main ) ;
155+ main . import ( "b" , child2 ) ;
156+ return main ;
157+ }
158+
159+ define1 ( ) ;
160+
161+ test . deepEqual ( await valueof ( a ) , { value : 1 } ) ;
162+ test . deepEqual ( await valueof ( b ) , { value : 2 } ) ;
163+ test . deepEqual ( await valueof ( c ) , { value : 3 } ) ;
164+ test . deepEqual ( await valueof ( importA ) , { error : 'RuntimeError: a could not be resolved' } ) ;
165+ test . deepEqual ( await valueof ( importB ) , { error : 'RuntimeError: b could not be resolved' } ) ;
166+ test . deepEqual ( await valueof ( importC ) , { error : 'RuntimeError: c could not be resolved' } ) ;
167+ }
168+ ) ;
0 commit comments