packages feed

zeolite-lang-0.24.1.0: tests/delegation.0rt

/* -----------------------------------------------------------------------------
Copyright 2023 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 "delegate to functions" {
  success
}

unittest fromCategory {
  \ Testing.checkEquals(Value:call1(13, "message"), 123-13+7)
}

unittest fromType {
  \ Testing.checkEquals(Value.call2(13, "message"), 456-13+7)
}

unittest fromValue {
  \ Testing.checkEquals(Value.new().call3(13, "message"), 789-13+7)
}

concrete Value {
  @type new () -> (#self)
  @category call1 (Int, String) -> (Int)
  @type call2 (Int, String) -> (Int)
  @value call3 (Int, String) -> (Int)
}

define Value {
  new () { return #self{ } }

  call1 (number1, message1) {
    return delegate -> `delegatedTo1`
  }

  call2 (number2, message2) {
    \ delegate -> `delegatedTo1`
    return delegate -> `delegatedTo2`
  }

  call3 (number3, message3) {
    \ delegate -> `delegatedTo1`
    \ delegate -> `delegatedTo2`
    return delegate -> `delegatedTo3`
  }

  @category delegatedTo1 (Int, String) -> (Int)
  delegatedTo1 (number, message) {
    return 123-number+message.size()
  }

  @type delegatedTo2 (Int, String) -> (Int)
  delegatedTo2 (number, message) {
    return 456-number+message.size()
  }

  @value delegatedTo3 (Int, String) -> (Int)
  delegatedTo3 (number, message) {
    return 789-number+message.size()
  }
}


testcase "delegate to correct initializer" {
  success
}

unittest fromCategory {
  Value value <- Value:new1(13, "message")
  \ Testing.checkEquals(value.getInt(), 13)
  \ Testing.checkEquals(value.getString(), "message")
}

unittest fromType {
  Value value <- Value.new2(13, "message")
  \ Testing.checkEquals(value.getInt(), 13)
  \ Testing.checkEquals(value.getString(), "message")
}

unittest fromValue {
  Value value <- Value.new2(9, "error")
  value <- value.new3(13, "message")
  \ Testing.checkEquals(value.getInt(), 13)
  \ Testing.checkEquals(value.getString(), "message")
}

concrete Value {
  @category new1 (Int, String) -> (Value)
  @type new2 (Int, String) -> (Value)
  @value new3 (Int, String) -> (Value)
  @value getInt () -> (Int)
  @value getString () -> (String)
}

define Value {
  @value Int number
  @value String message

  new1 (number1, message1) {
    return delegate -> Value
  }

  new2 (number2, message2) {
    return delegate -> Value
  }

  new3 (number3, message3) {
    return delegate -> Value
  }

  getInt () { return number }
  getString () { return message }
}


testcase "delegate to #self" {
  success
}

unittest fromType {
  Value value <- Value.new1(13, "message")
  \ Testing.checkEquals(value.getInt(), 13)
  \ Testing.checkEquals(value.getString(), "message")
}

unittest fromValue {
  Value value <- Value.new1(9, "error")
  value <- value.new2(13, "message")
  \ Testing.checkEquals(value.getInt(), 13)
  \ Testing.checkEquals(value.getString(), "message")
}

concrete Value {
  @type new1 (Int, String) -> (Value)
  @value new2 (Int, String) -> (Value)
  @value getInt () -> (Int)
  @value getString () -> (String)
}

define Value {
  @value Int number
  @value String message

  new1 (number1, message1) {
    return delegate -> #self
  }

  new2 (number2, message2) {
    return delegate -> #self
  }

  getInt () { return number }
  getString () { return message }
}


testcase "delegate fails from unittest" {
  error
  require compiler "delegation"
}

unittest test {
  \ delegate -> `Value:new`
}

concrete Value {
  @category new () -> (Value)
}

define Value {
  new () {
    return Value{ }
  }
}


testcase "delegate fails from @category variable initializer" {
  error
  require compiler "delegation"
}

concrete Value { }

define Value {
  @category Value value <- delegate -> Value
}


testcase "delegate fails with ignored args" {
  error
  require compiler "ignore"
}

concrete Value {
  @category new (Int, String) -> (Value)
}

define Value {
  new (value, _) {
    return delegate -> `delegatedTo`
  }

  @category delegatedTo (Int, String) -> (Value)
  delegatedTo (number, message) {
    return Value{ }
  }
}


testcase "delegate fails with hidden args" {
  error
  require compiler "message"
  require compiler "hidden"
}

concrete Value {
  @category new (Int, String) -> (Value)
}

define Value {
  new (value, message) {
    $Hidden[message]$
    return delegate -> `delegatedTo`
  }

  @category delegatedTo (Int, String) -> (Value)
  delegatedTo (number, message) {
    return Value{ }
  }
}


testcase "delegate fails with missing label" {
  error
  require compiler "message:"
}

concrete Value {
  @category new (Int, String) -> (Value)
}

define Value {
  new (number, message) {
    return delegate -> `delegatedTo`
  }

  @category delegatedTo (Int, String message:) -> (Value)
  delegatedTo (number, message) {
    return Value{ }
  }
}


testcase "delegate passes along labels" {
  success
}

unittest test {
  \ Testing.checkEquals(Value:new(13, message: "message").getString(), "message")
}

concrete Value {
  @category new (Int, String message:) -> (Value)
  @value getString () -> (String)
}

define Value {
  @value Int number
  @value String message

  new (number, message) {
    return delegate -> `delegatedTo`
  }

  getString () { return message }

  @category delegatedTo (Int, String message:) -> (Value)
  delegatedTo (number, message) {
    return delegate -> Value
  }
}


testcase "delegate handles optional with &." {
  success
}

concrete Helper {
  @type testEmpty (Int) -> ()
  @type testNonEmpty (Int) -> ()
  @type call (Bool fake:) -> (optional String)
}

define Helper {
  testEmpty (position) {
    \ Testing.checkEquals(delegate -> `Helper.call(fake: true)&.readAt`, empty)
  }

  testNonEmpty (position) {
    \ Testing.checkEquals(delegate -> `Helper.call(fake: false)&.readAt`, "123".readAt(position))
  }

  call (fake) {
    if (fake) {
      return empty
    } else {
      return "123"
    }
  }
}

unittest testEmpty {
  \ Helper.testEmpty(1)
}

unittest testNonEmpty {
  \ Helper.testNonEmpty(1)
}


testcase "delegate applies optional with &." {
  error
  require compiler "value"
  require compiler "modifier"
}

concrete Helper {
  @type test (Int) -> ()
  @type call () -> (optional String)
}

define Helper {
  test (position) {
    Char value <- delegate -> `Helper.call()&.readAt`
  }

  call () {
    return empty
  }
}