##########################################################################
# TEPAM - Tcl's Enhanced Procedure and Argument Manager
##########################################################################
#
# proc_call_arg_valid.test 
# This file is part of the enhanced procedure and argument manager's regression
# test. It validates the declaration and call of the procedure sub commands.
#
# Copyright (C) 2009, 2010 Andreas Drollinger
# 
# Id: proc_call_arg_valid.test
##########################################################################
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
##########################################################################

source [file join \
   [file dirname [file dirname [file join [pwd] [info script]]]] \
   devtools testutilities.tcl]

testsNeedTcl     8.3
testsNeedTcltest 1.0

catch {namespace delete ::tepam}
testing {
   useLocal tepam.tcl tepam
}

# Tests is an extension of the test command. It adds the option -variations that allows \
# specifying a list values. For each of these values the test command is executed, replacing all '%1' 
# of the original test command string by the altered value.
proc tests {name description args} {
   set VariationList(0) {""}; # Default variation list 0, in case no variations are required
   for {set NbrVariationLists 0} {1} {incr NbrVariationLists} {
      set VariationListPos [lsearch -exact $args -variations]
      if {$VariationListPos<0} break
      set VariationList($NbrVariationLists) [lindex $args [expr $VariationListPos+1]]
      set args [lreplace $args $VariationListPos [expr $VariationListPos+1]]
   }
   for {set TestNbr 0} {$TestNbr<[llength $VariationList(0)]} {incr TestNbr} {
      set TestExec "test \"$name\.$TestNbr\" \"$description.$TestNbr\""
      foreach Arg $args {
         set NewArg $Arg
         for {set vl 0} {$vl<$NbrVariationLists} {incr vl} {
            regsub -all "%[expr $vl+1]" $NewArg [lindex $VariationList($vl) $TestNbr] NewArg
         }
         append TestExec " \{$NewArg\}"
      }
      uplevel 1 $TestExec
   }
}

######## Validation through choice lists ########

   tepam::procedure Value_Is_Pair {
      -args {
         {-int -type integer -optional -choices {2 4 6 8 10}}
         {-double -type double -optional -choices {2.0 4.0 6.0 8.0 10.0}}
         {-m_int -type integer -optional -multiple -choices {2 4 6 8 10}}
         {-m_double -type double -optional -multiple -choices {2.0 4.0 6.0 8.0 10.0}}
      }
   } {
   }

   # Choice list based argument check

      # Simple parameters
      tests tepam-argval.choic1.int1 "tepam, Choice list based argument check - simple parameters" \
               -variations {2 4 8 10} \
               -body {Value_Is_Pair -int %1} \
               -result "" -output ""

      tests tepam-argval.choic1.int2 "tepam, Choice list based argument check - simple parameters" \
               -variations {0 1 3 9 11} \
               -body {Value_Is_Pair -int %1} \
               -returnCodes error -result "*Argument 'int' has to be one of the following elements:*" -output "" -match glob

      tests tepam-argval.choic1.double1 "tepam, Choice list based argument check - simple parameters" \
               -variations {2.0 4.0 8.0 10.0} \
               -body {Value_Is_Pair -double %1} \
               -result "" -output ""

      tests tepam-argval.choic1.double2 "tepam, Choice list based argument check - simple parameters" \
               -variations {0 0.5 1 3 9 9.5 11} \
               -body {Value_Is_Pair -double %1} \
               -returnCodes error -result "*Argument 'double' has to be one of the following elements:*" -output "" -match glob

      # Multiple parameters
      tests tepam-argval.choic2.int1 "tepam, Choice list based argument check - multiple parameters" \
               -variations {2 4 8 10} \
               -body {Value_Is_Pair -m_int %1 -m_int %1} \
               -result "" -output ""

      tests tepam-argval.choic2.int2 "tepam, Choice list based argument check - multiple parameters" \
               -variations {0 1 3 9 11} \
               -body {Value_Is_Pair -m_int %1 -m_int %1} \
               -returnCodes error -result "*Argument 'm_int' has to be one of the following elements:*" -output "" -match glob

      tests tepam-argval.choic2.double1 "tepam, Choice list based argument check - multiple parameters" \
               -variations {2.0 4.0 8.0 10.0} \
               -body {Value_Is_Pair -m_double %1 -m_double %1} \
               -result "" -output ""

      tests tepam-argval.choic2.double2 "tepam, Choice list based argument check - multiple parameters" \
               -variations {0 0.5 1 3 9 9.5 11} \
               -body {Value_Is_Pair -m_double %1 -m_double %1} \
               -returnCodes error -result "*Argument 'm_double' has to be one of the following elements:*" -output "" -match glob

######## Validation through ranges ########

   tepam::procedure Value_Is_Medium {
      -args {
         {-int -type integer -optional -range {4 6}}
         {-double -type double -optional -range {4 6}}
         {-m_int -type integer -optional -multiple -range {4 6}}
         {-m_double -type double -optional -multiple -range {4 6}}
      }
   } {
   }

   # Range based argument check

      # Simple parameters
      tests tepam-argval.range1.int1 "tepam, Range based argument check - simple parameters" \
               -variations {4 5 6} \
               -body {Value_Is_Medium -int %1} \
               -result "" -output ""

      tests tepam-argval.range1.int2 "tepam, Range based argument check - simple parameters" \
               -variations {1 0 7 8} \
               -body {Value_Is_Medium -int %1} \
               -returnCodes error -result "*Argument 'int' has to be between*" -output "" -match glob

      tests tepam-argval.range1.double1 "tepam, Range based argument check - simple parameters" \
               -variations {4 5 6} \
               -body {Value_Is_Medium -double %1} \
               -result "" -output ""

      tests tepam-argval.range1.double2 "tepam, Range based argument check - simple parameters" \
               -variations {1 1.9 6.1 7 8} \
               -body {Value_Is_Medium -double %1} \
               -returnCodes error -result "*Argument 'double' has to be between*" -output "" -match glob

      # Multiple parameters
      tests tepam-argval.range2.int1 "tepam, Range based argument check - multiple parameters" \
               -variations {4 5 6} \
               -body {Value_Is_Medium -m_int %1 -m_int %1} \
               -result "" -output ""

      tests tepam-argval.range2.int2 "tepam, Range based argument check - multiple parameters" \
               -variations {1 0 7 8} \
               -body {Value_Is_Medium -m_int %1 -m_int %1} \
               -returnCodes error -result "*Argument 'm_int' has to be between*" -output "" -match glob

      tests tepam-argval.range2.double1 "tepam, Range based argument check - multiple parameters" \
               -variations {4 5 6} \
               -body {Value_Is_Medium -m_double %1 -m_double %1} \
               -result "" -output ""

      tests tepam-argval.range2.double2 "tepam, Range based argument check - multiple parameters" \
               -variations {1 1.9 6.1 7 8} \
               -body {Value_Is_Medium -m_double %1 -m_double %1} \
               -returnCodes error -result "*Argument 'm_double' has to be between*" -output "" -match glob

######## User specified argument validation, validation command ########

   proc StringLength_Is_3 {Value} {
      return [expr [string length $Value]==3]
   }

   tepam::procedure AllTypeProcedure {
      -args {
         {-string_size_3 -type string -optional -validatecommand "StringLength_Is_3 %P"}
         {-integer_size_3 -type integer -optional -validatecommand "StringLength_Is_3 %P"}
         {-nonvalid -optional -validatecommand "expr 0"}
         {-valid -optional -validatecommand "expr 1"}
         {-m_string_size_3 -type string -optional -multiple -validatecommand "StringLength_Is_3 %P"}
         {-m_integer_size_3 -type integer -optional -multiple -validatecommand "StringLength_Is_3 %P"}
         {-m_nonvalid -optional -multiple -validatecommand "expr 0"}
         {-m_valid -optional -multiple -validatecommand "expr 1"}
      }
   } {
   }

   # Validation command based argument check

      # Simple parameters
      tests tepam-argval.user1.1 "tepam, User command based argument check - simple parameters" \
               -variations {ab abcd} \
               -body {AllTypeProcedure -string_size_3 %1} \
               -returnCodes error -result "*Argument * is invalid.*" -output "" -match glob

      tests tepam-argval.user1.2 "tepam, User command based argument check - simple parameters" \
               -variations {abc 123} \
               -body {AllTypeProcedure -string_size_3 %1} \
               -result "" -output ""

      tests tepam-argval.user1.3 "tepam, User command based argument check - simple parameters" \
               -variations {12 1234} \
               -body {AllTypeProcedure -integer_size_3 %1} \
               -returnCodes error -result "*Argument * is invalid.*" -output "" -match glob

      tests tepam-argval.user1.4 "tepam, User command based argument check - simple parameters" \
               -variations {123} \
               -body {AllTypeProcedure -integer_size_3 %1} \
               -result "" -output ""

      tests tepam-argval.user1.5 "tepam, User command based argument check - simple parameters" \
               -variations {1a3} \
               -body {AllTypeProcedure -integer_size_3 %1} \
               -returnCodes error -result "*requires type 'integer'*" -output "" -match glob

      tests tepam-argval.user1.6 "tepam, User command based argument check - simple parameters" \
               -variations {abc 123} \
               -body {AllTypeProcedure -nonvalid %1} \
               -returnCodes error -result "*Argument * is invalid.*" -output "" -match glob

      tests tepam-argval.user1.7 "tepam, User command based argument check - simple parameters" \
               -variations {abc 123} \
               -body {AllTypeProcedure -valid %1} \
               -result "" -output ""

      # Multiple parameters"
      tests tepam-argval.user2.1 "tepam, User command based argument check - simple parameters" \
               -variations {ab abcd} \
               -body {AllTypeProcedure -m_string_size_3 %1 -m_string_size_3 %1} \
               -returnCodes error -result "*Argument * is invalid.*" -output "" -match glob

      tests tepam-argval.user2.2 "tepam, User command based argument check - simple parameters" \
               -variations {abc 123} \
               -body {AllTypeProcedure -m_string_size_3 %1 -m_string_size_3 %1} \
               -result "" -output ""

      tests tepam-argval.user2.3 "tepam, User command based argument check - simple parameters" \
               -variations {12 1234} \
               -body {AllTypeProcedure -m_integer_size_3 %1 -m_integer_size_3 %1} \
               -returnCodes error -result "*Argument * is invalid.*" -output "" -match glob

      tests tepam-argval.user2.4 "tepam, User command based argument check - simple parameters" \
               -variations {123} \
               -body {AllTypeProcedure -m_integer_size_3 %1 -m_integer_size_3 %1} \
               -result "" -output ""

      tests tepam-argval.user2.5 "tepam, User command based argument check - simple parameters" \
               -variations {1a3} \
               -body {AllTypeProcedure -m_integer_size_3 %1 -m_integer_size_3 %1} \
               -returnCodes error -result "*requires type 'integer'*" -output "" -match glob

      tests tepam-argval.user2.6 "tepam, User command based argument check - simple parameters" \
               -variations {abc 123} \
               -body {AllTypeProcedure -m_nonvalid %1 -m_nonvalid %1} \
               -returnCodes error -result "*Argument * is invalid.*" -output "" -match glob

      tests tepam-argval.user2.7 "tepam, User command based argument check - simple parameters" \
               -variations {abc 123} \
               -body {AllTypeProcedure -m_valid %1 -m_valid %1} \
               -result "" -output ""

######## That's all ########

::tcltest::cleanupTests
return

##########################################################################
# Id: proc_call_arg_valid.test
# Modifications:
#
# Revision 1.2  2013/10/14 droll
# * Adapted the expected error message to the changes made inside tepam.tcl
#
# Revision 1.1  2010/02/11 21:50:55  droll
# * TEPAM module checkin
##########################################################################
