/* ----------------------------------------------------------------------------- Copyright 2020-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 "converted call" { success } unittest test { Value value <- Value.create() \ value.Base.call() } @value interface Base { call () -> () } concrete Value { refines Base @type create () -> (Value) } define Value { call () {} create () { return Value{} } } testcase "converted call bad type" { error require "Base" } unittest test { Value value <- Value.create() \ value.Base.call() } @value interface Base { call () -> () } concrete Value { @value call () -> () @type create () -> (Value) } define Value { call () {} create () { return Value{} } } testcase "call from union" { error require "\[Base\|Value\]" } unittest test { [Base|Value] value <- Value.create() \ value.call() } @value interface Base { call () -> () } concrete Value { refines Base @type create () -> (Value) } define Value { call () {} create () { return Value{} } } testcase "call from union with conversion" { success } unittest test { [Base|Value] value <- Value.create() \ value.Base.call() } @value interface Base { call () -> () } concrete Value { refines Base @type create () -> (Value) } define Value { call () {} create () { return Value{} } } testcase "call from intersect" { success } unittest test { [Base1&Base2] value <- Value.create() \ value.call() } @value interface Base1 { call () -> () } @value interface Base2 {} concrete Value { refines Base1 refines Base2 @type create () -> (Value) } define Value { call () {} create () { return Value{} } } testcase "call from intersect with conversion" { success } unittest test { [Base1&Base2] value <- Value.create() \ value.Base1.call() } @value interface Base1 { call () -> () } @value interface Base2 {} concrete Value { refines Base1 refines Base2 @type create () -> (Value) } define Value { call () {} create () { return Value{} } } testcase "call from intersect with conversion" { success } unittest test { [Base1&Base2] value <- Value.create() \ value.Base1.call() } @value interface Base1 { call () -> () } @value interface Base2 {} concrete Value { refines Base1 refines Base2 @type create () -> (Value) } define Value { call () {} create () { return Value{} } } testcase "call from param type" { success } unittest test { \ Test.check() } @type interface Base { call () -> () } concrete Value { defines Base } define Value { call () {} } concrete Test { @type check<#x> #x defines Base () -> () } define Test { check () { \ #x.call() } } testcase "call from bad param type" { error require "call.+param #x" } @type interface Base { call () -> () } define Test { @type check<#x> () -> () check () { \ #x.call() } } concrete Test {} testcase "call from param value" { success } unittest test { Value value <- Value.create() \ Test.check(value) } @value interface Base { call () -> () } concrete Value { refines Base @type create () -> (Value) } define Value { call () {} create () { return Value{} } } concrete Test { @type check<#x> #x requires Base (#x) -> () } define Test { check (value) { \ value.call() } } testcase "call from bad param value" { error require "call.+param #x" } @value interface Base { call () -> () } define Test { @type check<#x> (#x) -> () check (value) { \ value.call() } } concrete Test {} testcase "convert arg" { success } unittest test { \ Test.convert(Value.create()).call() } @value interface Base { call () -> () } concrete Value { refines Base @type create () -> (Value) } define Value { call () {} create () { return Value{} } } concrete Test { @type convert (Value) -> (Base) } define Test { convert (value) { return value } } testcase "bad convert arg" { error require "does not refine Value" } @value interface Base {} concrete Value {} define Value {} define Test { @type convert (Base) -> (Value) convert (value) { return value } } concrete Test {} testcase "bad instance in param" { error require "Test" require "define" require "Equals" } unittest test { \ Call.call>() } concrete Value<#x> { #x defines Equals<#x> } define Value {} concrete Call { @type call<#x> () -> () } define Call { call () {} } testcase "overwrite arg" { error require "arg" } define Test { @type call (Int) -> () call (arg) { arg <- 2 } } concrete Test {} testcase "self in @category function" { error require "self" } define Test { @category call () -> () call () { Test value <- self } } concrete Test {} testcase "large dispatch tables" { success } unittest callDispatch { \ Testing.checkEquals(Type.new().get(),00) \ Testing.checkEquals(Type.new().get01(),01) \ Testing.checkEquals(Type.new().get02(),02) \ Testing.checkEquals(Type.new().get03(),03) \ Testing.checkEquals(Type.new().get04(),04) \ Testing.checkEquals(Type.new().get05(),05) \ Testing.checkEquals(Type.new().get06(),06) \ Testing.checkEquals(Type.new().get07(),07) \ Testing.checkEquals(Type.new().get08(),08) \ Testing.checkEquals(Type.new().get09(),09) \ Testing.checkEquals(Type.new().get10(),10) \ Testing.checkEquals(Type.new().get11(),11) \ Testing.checkEquals(Type.new().get12(),12) \ Testing.checkEquals(Type.new().get13(),13) \ Testing.checkEquals(Type.new().get14(),14) \ Testing.checkEquals(Type.new().get15(),15) \ Testing.checkEquals(Type.new().get16(),16) \ Testing.checkEquals(Type.new().get17(),17) \ Testing.checkEquals(Type.new().get18(),18) } unittest reduceBuiltin { \ Testing.checkPresent(reduce(Type.new())) \ Testing.checkPresent(reduce(Type.new())) \ Testing.checkPresent(reduce(Type.new())) \ Testing.checkPresent(reduce(Type.new())) \ Testing.checkPresent(reduce(Type.new())) \ Testing.checkPresent(reduce(Type.new())) \ Testing.checkPresent(reduce(Type.new())) \ Testing.checkPresent(reduce(Type.new())) \ Testing.checkPresent(reduce(Type.new())) \ Testing.checkPresent(reduce(Type.new())) \ Testing.checkPresent(reduce(Type.new())) \ Testing.checkPresent(reduce(Type.new())) \ Testing.checkPresent(reduce(Type.new())) \ Testing.checkPresent(reduce(Type.new())) \ Testing.checkPresent(reduce(Type.new())) \ Testing.checkPresent(reduce(Type.new())) \ Testing.checkPresent(reduce(Type.new())) \ Testing.checkPresent(reduce(Type.new())) \ Testing.checkPresent(reduce(Type.new())) } concrete Type { refines Base01 refines Base02 refines Base03 refines Base04 refines Base05 refines Base06 refines Base07 refines Base08 refines Base09 refines Base10 refines Base11 refines Base12 refines Base13 refines Base14 refines Base15 refines Base16 refines Base17 refines Base18 @type new () -> (Type) @value get () -> (Int) } define Type { new () { return Type{ } } get () { return 00 } get01 () { return 01 } get02 () { return 02 } get03 () { return 03 } get04 () { return 04 } get05 () { return 05 } get06 () { return 06 } get07 () { return 07 } get08 () { return 08 } get09 () { return 09 } get10 () { return 10 } get11 () { return 11 } get12 () { return 12 } get13 () { return 13 } get14 () { return 14 } get15 () { return 15 } get16 () { return 16 } get17 () { return 17 } get18 () { return 18 } } @value interface Base01 { get01 () -> (Int) } @value interface Base02 { get02 () -> (Int) } @value interface Base03 { get03 () -> (Int) } @value interface Base04 { get04 () -> (Int) } @value interface Base05 { get05 () -> (Int) } @value interface Base06 { get06 () -> (Int) } @value interface Base07 { get07 () -> (Int) } @value interface Base08 { get08 () -> (Int) } @value interface Base09 { get09 () -> (Int) } @value interface Base10 { get10 () -> (Int) } @value interface Base11 { get11 () -> (Int) } @value interface Base12 { get12 () -> (Int) } @value interface Base13 { get13 () -> (Int) } @value interface Base14 { get14 () -> (Int) } @value interface Base15 { get15 () -> (Int) } @value interface Base16 { get16 () -> (Int) } @value interface Base17 { get17 () -> (Int) } @value interface Base18 { get18 () -> (Int) }