/* ----------------------------------------------------------------------------- Copyright 2020 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 "internal param not visible from @type" { error require "#x" } concrete Value {} define Value { types<#x> {} @type something () -> () something () { optional #x val <- empty } } testcase "internal filter not applied in @type" { compiles } unittest test { \ Value.something() } concrete Value { @type something<#x> () -> () } define Value { types<#x> { #x defines LessThan<#x> } something () {} } testcase "internal filter not applied in @category" { compiles } unittest test { \ Value:something() } concrete Value { @category something<#x> () -> () } define Value { types<#x> { #x defines LessThan<#x> } something () {} } testcase "internal params" { success } unittest test { \ Value.create() } concrete Value { @type create<#x,#y> () -> (Value) } define Value { types<#x,#y> {} create () { return Value{ types<#x,#y> } } } @value interface Type1 {} @value interface Type2 {} testcase "internal params with filters" { compiles } @value interface Get<|#x> { get () -> (#x) } @value interface Set<#x|> { set (#x) -> () } concrete Value { @type create<#x,#y> #x requires Get<#x> #y allows Set<#y> () -> (Value) } define Value { types<#x,#y> { #x requires Get<#x> #y allows Set<#y> } create () { return Value{ types<#x,#y> } } } testcase "internal params missing filters" { error require "Get|Set" } @value interface Get<|#x> { get () -> (#x) } @value interface Set<#x|> { set (#x) -> () } concrete Value { @category create<#x,#y> () -> (Value) } define Value { types<#x,#y> { #x requires Get<#x> #y allows Set<#y> } create () { return Value{ types<#x,#y> } } } testcase "internal params with values" { compiles } concrete Value { @category create<#x,#y> () -> (Value) } define Value { types<#x,#y> {} @value Bool value create () { return Value{ types<#x,#y>, false } } } testcase "value depends on internal param" { success } unittest test { \ Value.create(Type.create()) } concrete Type<#y> { @type create () -> (Type<#y>) } define Type { create () { return Type<#y>{ } } } concrete Value { @type create<#x> (Type<#x>) -> (Value) } define Value { types<#z> {} @value Type<#z> value create (value) { return Value{ types<#x>, value } } } testcase "value mismatch with internal param" { error require "create" require "Bool" require "String" } unittest test { \ Value.create(Type.create()) } concrete Type<#y> { @type create () -> (Type<#y>) } define Type { create () { return Type<#y>{ } } } concrete Value { @type create<#x> (Type<#x>) -> (Value) } define Value { types<#z> {} @value Type<#z> value create (value) { return Value{ types<#x>, value } } } testcase "internal param clash with external" { error require "#x" } concrete Value<#x> {} define Value { types<#x> {} } testcase "internal param clash with function" { error require "#x" } concrete Value { @value check<#x> () -> () } define Value { types<#x> {} } testcase "internal param clash with internal function" { error require "#x" } concrete Value {} define Value { types<#x> {} @value check<#x> () -> () check () {} } testcase "internal param no clash with category" { compiles } concrete Value { @category create<#x> () -> (Value) } define Value { types<#x> {} create () { return Value { types<#x> } } } testcase "reduce internal param success" { success } unittest test { Value value <- Value.create() if (!value.check("")) { fail("Failed") } } concrete Value { @type create<#x> () -> (Value) @value check<#y> (#y) -> (Bool) } define Value { types<#x> {} create () { return Value { types<#x> } } check (y) { return present(reduce<#y,#x>(y)) } } testcase "reduce internal param fail" { success } unittest test { Value value <- Value.create() if (value.check(value)) { fail("Failed") } } concrete Value { @type create<#x> () -> (Value) @value check<#y> (#y) -> (Bool) } define Value { types<#x> {} create () { return Value { types<#x> } } check (y) { return present(reduce<#y,#x>(y)) } }