zeolite-lang-0.22.0.0: tests/defer.0rt
/* -----------------------------------------------------------------------------
Copyright 2021 Kevin P. Barry
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
----------------------------------------------------------------------------- */
// Author: Kevin P. Barry [ta0kira@gmail.com]
testcase "unused deferred" {
compiles
}
unittest test {
Int value <- defer
}
testcase "assigned deferred" {
compiles
}
unittest test {
Int value <- defer
value <- 1
\ value
}
testcase "defer new" {
error
require "value"
require "initialized"
}
unittest test {
Int value <- defer
\ value
}
testcase "defer existing" {
error
require "value"
require "initialized"
}
unittest test {
Int value <- 1
value <- defer
\ value
}
testcase "multiple deferred" {
error
require "value1"
require "initialized"
exclude "value0"
}
unittest test {
Int value1 <- 1
Int value2, value1 <- defer
\ value1
}
testcase "cannot defer _" {
error
require "defer"
require "discard"
}
unittest test {
_ <- defer
}
testcase "can defer @value member" {
error
require "value"
require "initialized"
}
concrete Type {}
define Type {
@value Int value
@value call () -> ()
call () {
value <- defer
\ value
}
}
testcase "can defer @category member" {
error
require "value"
require "initialized"
}
concrete Type {}
define Type {
@category Int value <- 1
@value call () -> ()
call () {
value <- defer
\ value
}
}
testcase "cannot defer function argument" {
error
require "defer"
require "value"
require "read-only"
}
concrete Type {}
define Type {
@value call (Int) -> ()
call (value) {
value <- defer
}
}
testcase "cannot defer read-only value" {
error
require "defer"
require "value"
require "read-only"
}
unittest test {
Int value <- 1
$ReadOnly[value]$
value <- defer
}
testcase "cannot defer hidden value" {
error
require "defer"
require "value"
require "hidden"
}
unittest test {
Int value <- 1
$Hidden[value]$
value <- defer
}
testcase "deferred initialized in if/elif/else" {
success
}
unittest test {
Int value <- defer
if (1 == 2) {
value <- 1
} elif (1 == 3) {
value <- 2
} else {
value <- 3
}
\ value
}
testcase "deferred missed in if" {
error
require "value"
require "initialized"
}
unittest test {
Int value <- defer
if (1 == 2) {
} elif (1 == 3) {
value <- 2
} else {
value <- 3
}
\ value
}
testcase "deferred missed in elif" {
error
require "value"
require "initialized"
}
unittest test {
Int value <- defer
if (1 == 2) {
value <- 1
} elif (1 == 3) {
} else {
value <- 3
}
\ value
}
testcase "deferred missed in else" {
error
require "value"
require "initialized"
}
unittest test {
Int value <- defer
if (1 == 2) {
value <- 1
} elif (1 == 3) {
value <- 2
} else {
}
\ value
}
testcase "deferred initialized before cleanup" {
success
}
unittest test {
Int value <- defer
cleanup {
\ value
} in value <- 1
}
testcase "deferred initialized in cleanup" {
success
}
unittest test {
Int value <- defer
cleanup {
value <- 1
} in \ empty
\ value
}
testcase "deferred initialized in scoped" {
success
}
unittest test {
Int value <- defer
scoped {
value <- 1
} in \ value
}
testcase "deferred not allowed in top-level scoped" {
error
require "defer"
require "scoped"
}
unittest test {
scoped {
} in Int value <- defer
}
testcase "deferred propagated from scoped statement" {
compiles
}
unittest test {
Int value <- defer
scoped {
} in if (true) {
value <- 1
} else {
value <- 2
}
\ value
}
testcase "deferred missed before cleanup" {
error
require "cleanup"
require "value"
require "initialized"
}
unittest test {
Int value <- defer
cleanup {
\ value
} in {
if (true) {
return _
} else {
value <- 1
}
}
}
testcase "deferred not checked in condition that jumps" {
crash
require "success"
}
unittest test {
Int value <- defer
if (true) {
fail("success")
} else {
value <- 1
}
\ value
}
testcase "deferred in nested block does not propagate" {
success
}
unittest test {
Int value <- 1
if (true) {
value <- defer
} else {
value <- defer
}
\ value
}