###############################################################################
#
# object.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 object-97.0.1 {honor NoDispose with -tostring} -body {
  set x [object invoke -tostring Interpreter.GetActive Host]
  object invoke -flags +NonPublic Interpreter.GetActive.Host disposed
} -cleanup {
  unset -nocomplain x
} -constraints {eagle} -isolationLevel Interpreter -result {False}}

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

runTest {test object-97.0.2 {honor NoDispose with -alias fail} -body {
  catch {object invoke -objectname host -alias Interpreter.GetActive Host} x
  list [object invoke -flags +NonPublic Interpreter.GetActive.Host disposed] $x
} -cleanup {
  unset -nocomplain x
} -constraints {eagle} -isolationLevel Interpreter -result \
{False {can't add "host": command already exists}}}

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

runTest {test object-97.1 {simple object usage} -body {
  list [set x [object create System.Object]] [object invoke $x ToString] \
      [object dispose $x] [unset x] [object invoke System.String Format \
      "this is a test... {0}" [expr {2 + 2}]]
} -cleanup {
  unset -nocomplain x
} -constraints {eagle} -match regexp -result {^System#Object#\d+ System\.Object\
removed \{\} \{this is a test\.\.\. 4\}$}}

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

runTest {test object-97.2 {-alias option overrides opaque handle reuse} -body {
  set x1 [object invoke -create Type GetType System.String]
  set x2 [object invoke -create -alias Type GetType System.String]
  set x3 [object invoke -create Type GetType System.String]
  set x4 [object invoke -create -alias Type GetType System.String]

  list [catch {$x1 ToString}] [$x2 ToString] [catch {$x3 ToString}] \
      [$x4 ToString] [expr {$x1 ne $x2}] [expr {$x1 eq $x3}] \
      [expr {$x2 eq $x4}]
} -cleanup {
  unset -nocomplain x1 x2 x3 x4; # dispose
} -constraints {eagle} -result {1 System.String 1 System.String True True True}}

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

runTest {test object-97.3.1 {assembly qualified member names} -body {
  set type System.String
  list [object members -pattern "* memberName Format" $type] \
      [object members -signatures -qualified -pattern "* memberName Format *" \
      $type]
} -cleanup {
  unset -nocomplain type
} -constraints {eagle dotNet20} -result \
{{{memberType Method memberName Format}} {{memberType Method memberName Format\
methodType Method methodName Format callingConvention Standard returnType\
{{System.String, mscorlib, Version=2.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089}} parameterTypes {{System.String, mscorlib,\
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}\
{System.Object, mscorlib, Version=2.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089}}} {memberType Method memberName Format\
methodType Method methodName Format callingConvention Standard returnType\
{{System.String, mscorlib, Version=2.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089}} parameterTypes {{System.String, mscorlib,\
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}\
{System.Object, mscorlib, Version=2.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089} {System.Object, mscorlib, Version=2.0.0.0,\
Culture=neutral, PublicKeyToken=b77a5c561934e089}}} {memberType Method\
memberName Format methodType Method methodName Format callingConvention\
Standard returnType {{System.String, mscorlib, Version=2.0.0.0,\
Culture=neutral, PublicKeyToken=b77a5c561934e089}} parameterTypes\
{{System.String, mscorlib, Version=2.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089} {System.Object, mscorlib, Version=2.0.0.0,\
Culture=neutral, PublicKeyToken=b77a5c561934e089} {System.Object, mscorlib,\
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}\
{System.Object, mscorlib, Version=2.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089}}} {memberType Method memberName Format\
methodType Method methodName Format callingConvention Standard returnType\
{{System.String, mscorlib, Version=2.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089}} parameterTypes {{System.String, mscorlib,\
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}\
{System.Object[], mscorlib, Version=2.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089}}} {memberType Method memberName Format\
methodType Method methodName Format callingConvention Standard returnType\
{{System.String, mscorlib, Version=2.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089}} parameterTypes {{System.IFormatProvider,\
mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}\
{System.String, mscorlib, Version=2.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089} {System.Object[], mscorlib, Version=2.0.0.0,\
Culture=neutral, PublicKeyToken=b77a5c561934e089}}}}}}

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

runTest {test object-97.3.2 {assembly qualified member names} -body {
  set type System.String
  list [object members -pattern "* memberName Format" $type] \
      [object members -signatures -qualified -pattern "* memberName Format *" \
      $type]
} -cleanup {
  unset -nocomplain type
} -constraints {eagle dotNet40} -result \
{{{memberType Method memberName Format}} {{memberType Method memberName Format\
methodType Method methodName Format callingConvention Standard returnType\
{{System.String, mscorlib, Version=4.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089}} parameterTypes {{System.String, mscorlib,\
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}\
{System.Object, mscorlib, Version=4.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089}}} {memberType Method memberName Format\
methodType Method methodName Format callingConvention Standard returnType\
{{System.String, mscorlib, Version=4.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089}} parameterTypes {{System.String, mscorlib,\
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}\
{System.Object, mscorlib, Version=4.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089} {System.Object, mscorlib, Version=4.0.0.0,\
Culture=neutral, PublicKeyToken=b77a5c561934e089}}} {memberType Method\
memberName Format methodType Method methodName Format callingConvention\
Standard returnType {{System.String, mscorlib, Version=4.0.0.0,\
Culture=neutral, PublicKeyToken=b77a5c561934e089}} parameterTypes\
{{System.String, mscorlib, Version=4.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089} {System.Object, mscorlib, Version=4.0.0.0,\
Culture=neutral, PublicKeyToken=b77a5c561934e089} {System.Object, mscorlib,\
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}\
{System.Object, mscorlib, Version=4.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089}}} {memberType Method memberName Format\
methodType Method methodName Format callingConvention Standard returnType\
{{System.String, mscorlib, Version=4.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089}} parameterTypes {{System.String, mscorlib,\
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}\
{System.Object[], mscorlib, Version=4.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089}}} {memberType Method memberName Format\
methodType Method methodName Format callingConvention Standard returnType\
{{System.String, mscorlib, Version=4.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089}} parameterTypes {{System.IFormatProvider,\
mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}\
{System.String, mscorlib, Version=4.0.0.0, Culture=neutral,\
PublicKeyToken=b77a5c561934e089} {System.Object[], mscorlib, Version=4.0.0.0,\
Culture=neutral, PublicKeyToken=b77a5c561934e089}}}}}}

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

runTest {test object-97.4 {ScriptEnumerator success} -setup {
  set type [object invoke -create -alias Type GetType [appendArgs \
      Eagle._Components.Private.ScriptEnumerator`1, " " [lindex \
      [info assembly] 0]]]

  set newType [$type -create MakeGenericType System.Int32]

  set script(moveNext) [object invoke Script Create {
    incr index; expr {$index >= 0 && $index < [llength $list]}
  }]

  set script(current) [object invoke Script Create {
    set obj($index) [object invoke -create Int32 Parse [lindex $list $index]]
    lappend objs $obj($index); return $obj($index)
  }]

  set script(reset) [object invoke Script Create {
    set index -1
  }]
} -body {
  set enumerator [object create -alias $newType "" \
      $script(moveNext) $script(current) $script(reset)]

  set objs [list]; set list [list 1 2 3 4]; set index -1; set result [list]

  while {[$enumerator MoveNext]} {
    lappend result [$enumerator Current]
  }

  $enumerator Reset

  set result
} -cleanup {
  unset -nocomplain result obj objs index list enumerator \
      script newType type
} -constraints {eagle} -result {1 2 3 4}}

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

runTest {test object-97.5 {ScriptEnumerator MoveNext failure} -setup {
  set type [object invoke -create -alias Type GetType [appendArgs \
      Eagle._Components.Private.ScriptEnumerator`1, " " [lindex \
      [info assembly] 0]]]

  set newType [$type -create MakeGenericType System.Int32]

  set script(moveNext) [object invoke Script Create {
    error "failed to move next"
  }]

  set script(current) [object invoke Script Create {
    set obj($index) [object invoke -create Int32 Parse [lindex $list $index]]
    lappend objs $obj($index); return $obj($index)
  }]

  set script(reset) [object invoke Script Create {
    set index -1
  }]
} -body {
  set enumerator [object create -alias $newType "" \
      $script(moveNext) $script(current) $script(reset)]

  set objs [list]; set list [list 1 2 3 4]; set index -1; set result [list]

  catch {
    while {[$enumerator MoveNext]} {
      lappend result [$enumerator Current]
    }

    $enumerator Reset
  } msg

  list $result $msg
} -cleanup {
  unset -nocomplain msg result obj objs index list enumerator \
      script newType type
} -constraints {eagle} -match regexp -result {^\{\} \{.* --->\
Eagle\._Components\.Public\.ScriptException: failed to move next.*\}$}}

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

runTest {test object-97.6 {ScriptEnumerator Current failure} -setup {
  set type [object invoke -create -alias Type GetType [appendArgs \
      Eagle._Components.Private.ScriptEnumerator`1, " " [lindex \
      [info assembly] 0]]]

  set newType [$type -create MakeGenericType System.Int32]

  set script(moveNext) [object invoke Script Create {
    incr index; expr {$index >= 0 && $index < [llength $list]}
  }]

  set script(current) [object invoke Script Create {
    error "failed to get current"
  }]

  set script(reset) [object invoke Script Create {
    set index -1
  }]
} -body {
  set enumerator [object create -alias $newType "" \
      $script(moveNext) $script(current) $script(reset)]

  set objs [list]; set list [list 1 2 3 4]; set index -1; set result [list]

  catch {
    while {[$enumerator MoveNext]} {
      lappend result [$enumerator Current]
    }

    $enumerator Reset
  } msg

  list $result $msg
} -cleanup {
  unset -nocomplain msg result obj objs index list enumerator \
      script newType type
} -constraints {eagle} -match regexp -result {^\{\} \{.* --->\
Eagle\._Components\.Public\.ScriptException: failed to get current.*\}$}}

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

runTest {test object-97.7 {ScriptEnumerator Reset failure} -setup {
  set type [object invoke -create -alias Type GetType [appendArgs \
      Eagle._Components.Private.ScriptEnumerator`1, " " [lindex \
      [info assembly] 0]]]

  set newType [$type -create MakeGenericType System.Int32]

  set script(moveNext) [object invoke Script Create {
    incr index; expr {$index >= 0 && $index < [llength $list]}
  }]

  set script(current) [object invoke Script Create {
    set obj($index) [object invoke -create Int32 Parse [lindex $list $index]]
    lappend objs $obj($index); return $obj($index)
  }]

  set script(reset) [object invoke Script Create {
    error "failed to reset"
  }]
} -body {
  set enumerator [object create -alias $newType "" \
      $script(moveNext) $script(current) $script(reset)]

  set objs [list]; set list [list 1 2 3 4]; set index -1; set result [list]

  catch {
    while {[$enumerator MoveNext]} {
      lappend result [$enumerator Current]
    }

    $enumerator Reset
  } msg

  list $result $msg
} -cleanup {
  unset -nocomplain msg result obj objs index list enumerator \
      script newType type
} -constraints {eagle} -match regexp -result {^\{1 2 3 4\} \{.* --->\
Eagle\._Components\.Public\.ScriptException: failed to reset.*\}$}}

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

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