###############################################################################
#
# scope.eagle --
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
#
# Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################

source [file join [file normalize [file dirname [info script]]] prologue.eagle]

###############################################################################

runTest {test scope-6.1 {clone/upvar/incr inside proc} -setup {
  proc foo { name a } {
    set c 9
    scope create -open -clone -args $name
    if {![info exists b]} then {upvar 2 $a b}; # caller of proc foo
    incr b $c
    return [list [info level] [info level [info level]] $b]
    # scope close; # always implied
  }
} -body {
  set s foo
  if {![info exists i]} then {set i 0}
  list [foo $s i] [foo $s i] [foo $s i]
} -cleanup {
  catch {scope destroy $s}
  unset -nocomplain s i
  rename foo ""
} -constraints {eagle} -result {{2 {foo foo i} 9} {2 {foo foo i} 18}\
{2 {foo foo i} 27}}}

###############################################################################

runTest {test scope-6.2 {create -open -procedure} -setup {
  proc foo { varName } {
    set ::scope [scope create -open -procedure -args]
    upvar 0 $varName myVar
    if {[info exists myVar]} then {
      incr myVar
    } else {
      set myVar 0
    }
    return $myVar
    # scope close; # always implied
  }
} -body {
  list [foo x] [foo y(1)] [foo x] [foo y(1)]
} -cleanup {
  catch {scope destroy $::scope}
  unset -nocomplain ::scope
  rename foo ""
} -constraints {eagle} -result {0 0 1 1}}

###############################################################################

runTest {test scope-6.3 {create/open -procedure} -setup {
  proc foo { varName } {
    if {[info exists ::scope] && [scope exists $::scope]} then {
      scope open -procedure -args
      set type open
    } else {
      set ::scope [scope create -open -procedure -args]
      set type create
    }
    upvar 0 $varName myVar
    if {[info exists myVar]} then {
      incr myVar
    } else {
      set myVar 0
    }
    return [list $type $myVar]
    # scope close; # always implied
  }
} -body {
  list [foo x] [foo y(1)] [foo x] [foo y(1)]
} -cleanup {
  catch {scope destroy $::scope}
  unset -nocomplain ::scope
  rename foo ""
} -constraints {eagle} -result {{create 0} {open 0} {open 1} {open 1}}}

###############################################################################

runTest {test scope-6.4 {create -procedure error (no proc frame)} -body {
  scope create -open -procedure -args
} -constraints {eagle} -returnCodes 1 -result {no procedure frame available}}

###############################################################################

runTest {test scope-6.5 {open -procedure error (no procedure frame)} -body {
  scope open -procedure -args
} -constraints {eagle} -returnCodes 1 -result {no procedure frame available}}

###############################################################################

runTest {test scope-6.6 {create -procedure error (cannot use name)} -body {
  scope create -open -procedure -args foobar
} -constraints {eagle} -returnCodes 1 -result \
{cannot specify scope name with -procedure}}

###############################################################################

runTest {test scope-6.7 {open -procedure error (cannot use name)} -body {
  scope open -procedure -args foobar
} -constraints {eagle} -returnCodes 1 -result \
{cannot specify scope name with -procedure}}

###############################################################################

runTest {test scope-6.8 {create/destroy while open} -setup {
  proc foo {} {
    scope create -open foo; scope destroy foo
  }
} -body {
  foo
} -cleanup {
  catch {scope destroy foo}
  rename foo ""
} -constraints {eagle} -result {}}

###############################################################################

runTest {test scope-6.9 {nested create ok} -setup {
  proc foo {} {
    set ::scope [scope create -open -procedure]; scope create -open foo
  }
} -body {
  foo
} -cleanup {
  catch {scope destroy foo}
  catch {scope destroy $::scope}
  unset -nocomplain ::scope
  rename foo ""
} -constraints {eagle} -result {foo}}

###############################################################################

runTest {test scope-6.10 {nested create error (not procedure frame)} -setup {
  proc foo {} {
    scope create -open foo; set ::scope [scope create -open -procedure]
  }
} -body {
  foo
} -cleanup {
  catch {scope destroy foo}
  catch {scope destroy $::scope}
  unset -nocomplain ::scope
  rename foo ""
} -constraints {eagle} -returnCodes 1 -result {no procedure frame available}}

###############################################################################

source [file join [file normalize [file dirname [info script]]] epilogue.eagle]
