@@ -165,6 +165,48 @@ end`)
165165 }
166166}
167167
168+ func TestDBCapabilityEachLoopControlCannotCrossCallbackBoundary (t * testing.T ) {
169+ stub := & dbCapabilityStub {
170+ eachRows : []Value {
171+ NewHash (map [string ]Value {"id" : NewString ("p-1" )}),
172+ NewHash (map [string ]Value {"id" : NewString ("p-2" )}),
173+ },
174+ }
175+ engine := MustNewEngine (Config {})
176+ script , err := engine .Compile (`def break_from_callback()
177+ db.each("Player") do |row|
178+ if row[:id] == "p-2"
179+ break
180+ end
181+ end
182+ end
183+
184+ def next_from_callback()
185+ db.each("Player") do |row|
186+ if row[:id] == "p-2"
187+ next
188+ end
189+ end
190+ end` )
191+ if err != nil {
192+ t .Fatalf ("compile failed: %v" , err )
193+ }
194+
195+ _ , err = script .Call (context .Background (), "break_from_callback" , nil , CallOptions {
196+ Capabilities : []CapabilityAdapter {MustNewDBCapability ("db" , stub )},
197+ })
198+ if err == nil || ! strings .Contains (err .Error (), "break used outside of loop" ) {
199+ t .Fatalf ("expected callback break outside-loop error, got %v" , err )
200+ }
201+
202+ _ , err = script .Call (context .Background (), "next_from_callback" , nil , CallOptions {
203+ Capabilities : []CapabilityAdapter {MustNewDBCapability ("db" , stub )},
204+ })
205+ if err == nil || ! strings .Contains (err .Error (), "next used outside of loop" ) {
206+ t .Fatalf ("expected callback next outside-loop error, got %v" , err )
207+ }
208+ }
209+
168210func TestDBCapabilityRejectsCallableUpdateAttributes (t * testing.T ) {
169211 stub := & dbCapabilityStub {}
170212 engine := MustNewEngine (Config {})
0 commit comments