#!/usr/bin/ruby

# Tests for the try/catch branches.

func catch_multi {
  try {
    var f = :try_branch
    f.abcdefg
    (true, :a, :b, f)
  } catch {
      |msg|
    (false, :a, :b, :catch_branch, msg)
  }
}

func try_multi {
  try {
    var f = :try_branch
    (true, :a, :b, f)
  } catch {
      |msg|
    (false, :a, :b, :catch_branch, msg)
  }
}

do {
    var *v = catch_multi()
    assert_eq(v.first(4), [false, "a", "b", "catch_branch"])
    assert(v[4] ~~ /abcdefg/)
}

do {
    var *v = try_multi()
    assert_eq(v, [true, "a", "b", "try_branch"])
}

const x = try {
    (0, 1, 2)
} catch {
    (3, 4, 5)
}

assert_eq(Sys.ref(x), 'Sidef::Types::Number::Number')
assert_eq(x, 0)

const y = try {
    die ()
    (0, 1, 2)
} catch {
    (3, 4, 5)
}

assert_eq(Sys.ref(y), 'Sidef::Types::Number::Number')
assert_eq(y, 3)

assert_eq(try { 42 }, 42)
assert_eq(try { die -1 }, nil)

[1,2,3].map {
    var n = _
    assert_eq(try { assert_eq(_, n); 42+_ }, 42+n)
    assert_eq(try { die 1 } catch { _+42 }, 42+n)
}

do {
    var x = 42
    try { x += 1 }
    if (false) {
        die 'error'
    }
    assert_eq(x, 43)
}

do {
    var x = 42
    try { x += 1 } catch { 'something' }
    if (false) {
        die 'error'
    }
    assert_eq(x, 43)
}

do {
    var x = 42
    try { x += 1 } if (false)
    { die 'error' }
    assert_eq(x, 42)
}

do {
    func foo(n) {
        try {
            return 42
        }
        catch {
            die 'catch'
        }
        return n
    }

    func bar(n) {
        try {
            die "error"
        }
        catch {
            return 97
        }
        return n
    }

    func f(n) {
        (n > 100) || die "error"
    }

    func baz(n) {
        try {
            return f(n)
        }
        catch {
            return 13
        }
        return n
    }

    assert_eq(foo(1), 42)
    assert_eq(bar(1), 97)
    assert_eq(baz(1), 13)
}

say "** Test passed!"