##############################################################################
#   Modules Revision 3.0
#   Providing a flexible user environment
#
#   File:		modules.70-maint/%M%
#   Revision:		%I%
#   First Edition:	2021/01/19
#   Last Mod.:		%U%, %G%
#
#   Authors:		Anaïs Gaertner, anais.gaertner@cea.fr
#
#   Description:	Testuite testsequence
#   Command:
#   Modulefiles:        term_width
#   Sub-Command:        avail, list, savelist, load
#
#   Comment:	%C{
#           Test output width
#		}C%
#
##############################################################################

set test_cols 169
if {![info exists term_cols]} {
    # skip tests if current terminal witdh is unknown
    send_user "\tskipping terminal width-specific tests\n"
# set a specific terminal width
} elseif {[catch {exec stty cols $test_cols}] || [getTtyCols] ne $test_cols} {
    send_user "\tskipping terminal width-specific tests, cannot set width\n"
} else {

set mp $modpath
set mpre [regsub -all "\(\[.+?\]\)" $mp {\\\1}]


# setup specific environment
setenv_path_var MODULEPATH $mp

# ensure advanced version specifiers are enabled
setenv_var MODULES_ADVANCED_VERSION_SPEC 1

# ensure regular avail search match is set for these tests
setenv_var MODULES_SEARCH_MATCH starts_with

# ensure avail tests are made using in depth mode
setenv_var MODULES_AVAIL_INDEPTH 1


# Determine the width of the header for each output
proc ts_avail_header {w} {
   set len  [string length $::modpath]
   set lrep [expr {($w - $len - 2)/2}]
   if {$lrep < 1} {set lrep 1}
   set rrep [expr {$w - $len - 2 - $lrep}]
   if {$rrep < 1} {set rrep 1}
   return "[string repeat {-} $lrep] $::modpath [string repeat {-} $rrep]"
}

#
# 'avail' sub-command
#

# Set the output for different width

set width_0 "[ts_avail_header 169]
loc_rc1/1.0(foo)           loc_rc3/2.0(cur:stable)        loc_rc5/1.0               loc_rc6/bar(@)  loc_rc8/0.9(@)  loc_rcv1/1.2(default:new)  loc_rcv2/2.0  
loc_rc1/2.0                loc_rc3/3.0(chk:exp:new:test)  loc_rc5/2.0               loc_rc7/0.9     loc_rc8/1.0     loc_rcv1/2.0               
loc_rc2/1.0(bar:blah:foo)  loc_rc4/1.0                    loc_rc6/0.9               loc_rc7/1(@)    loc_rc010/2.0   loc_rcv1/bar(@)            
loc_rc2/2.0                loc_rc4/2.0(default)           loc_rc6/1(@)              loc_rc7/1.2     loc_rcv1/1(@)   loc_rcv2/1.2               
loc_rc3/1.0(default)       loc_rc4/3.0                    loc_rc6/1.2(default:new)  loc_rc7/bar(@)  loc_rcv1/1.1    loc_rcv2/1.5               

Key:
(@)=module-alias  (symbolic-version)  "

set width_1 "[ts_avail_header 1]
loc_rc1/1.0(foo)               
loc_rc1/2.0                    
loc_rc2/1.0(bar:blah:foo)      
loc_rc2/2.0                    
loc_rc3/1.0(default)           
loc_rc3/2.0(cur:stable)        
loc_rc3/3.0(chk:exp:new:test)  
loc_rc4/1.0                    
loc_rc4/2.0(default)           
loc_rc4/3.0                    
loc_rc5/1.0                    
loc_rc5/2.0                    
loc_rc6/0.9                    
loc_rc6/1(@)                   
loc_rc6/1.2(default:new)       
loc_rc6/bar(@)                 
loc_rc7/0.9                    
loc_rc7/1(@)                   
loc_rc7/1.2                    
loc_rc7/bar(@)                 
loc_rc8/0.9(@)                 
loc_rc8/1.0                    
loc_rc010/2.0                  
loc_rcv1/1(@)                  
loc_rcv1/1.1                   
loc_rcv1/1.2(default:new)      
loc_rcv1/2.0                   
loc_rcv1/bar(@)                
loc_rcv2/1.2                   
loc_rcv2/1.5                   
loc_rcv2/2.0                   

Key:
(@)=module-alias           
(symbolic-version)  "

set width_30 "[ts_avail_header 30]
loc_rc1/1.0(foo)               
loc_rc1/2.0                    
loc_rc2/1.0(bar:blah:foo)      
loc_rc2/2.0                    
loc_rc3/1.0(default)           
loc_rc3/2.0(cur:stable)        
loc_rc3/3.0(chk:exp:new:test)  
loc_rc4/1.0                    
loc_rc4/2.0(default)           
loc_rc4/3.0                    
loc_rc5/1.0                    
loc_rc5/2.0                    
loc_rc6/0.9                    
loc_rc6/1(@)                   
loc_rc6/1.2(default:new)       
loc_rc6/bar(@)                 
loc_rc7/0.9                    
loc_rc7/1(@)                   
loc_rc7/1.2                    
loc_rc7/bar(@)                 
loc_rc8/0.9(@)                 
loc_rc8/1.0                    
loc_rc010/2.0                  
loc_rcv1/1(@)                  
loc_rcv1/1.1                   
loc_rcv1/1.2(default:new)      
loc_rcv1/2.0                   
loc_rcv1/bar(@)                
loc_rcv2/1.2                   
loc_rcv2/1.5                   
loc_rcv2/2.0                   

Key:
(@)=module-alias           
(symbolic-version)  "

set width_50 "[ts_avail_header 50]
loc_rc1/1.0(foo)               loc_rcv1/2.0     
loc_rc1/2.0                    loc_rcv1/bar(@)  
loc_rc2/1.0(bar:blah:foo)      loc_rcv2/1.2     
loc_rc2/2.0                    loc_rcv2/1.5     
loc_rc3/1.0(default)           loc_rcv2/2.0     
loc_rc3/2.0(cur:stable)        
loc_rc3/3.0(chk:exp:new:test)  
loc_rc4/1.0                    
loc_rc4/2.0(default)           
loc_rc4/3.0                    
loc_rc5/1.0                    
loc_rc5/2.0                    
loc_rc6/0.9                    
loc_rc6/1(@)                   
loc_rc6/1.2(default:new)       
loc_rc6/bar(@)                 
loc_rc7/0.9                    
loc_rc7/1(@)                   
loc_rc7/1.2                    
loc_rc7/bar(@)                 
loc_rc8/0.9(@)                 
loc_rc8/1.0                    
loc_rc010/2.0                  
loc_rcv1/1(@)                  
loc_rcv1/1.1                   
loc_rcv1/1.2(default:new)      

Key:
(@)=module-alias  (symbolic-version)  "

set width_60 "[ts_avail_header 60]
loc_rc1/1.0(foo)               loc_rc7/0.9                
loc_rc1/2.0                    loc_rc7/1(@)               
loc_rc2/1.0(bar:blah:foo)      loc_rc7/1.2                
loc_rc2/2.0                    loc_rc7/bar(@)             
loc_rc3/1.0(default)           loc_rc8/0.9(@)             
loc_rc3/2.0(cur:stable)        loc_rc8/1.0                
loc_rc3/3.0(chk:exp:new:test)  loc_rc010/2.0              
loc_rc4/1.0                    loc_rcv1/1(@)              
loc_rc4/2.0(default)           loc_rcv1/1.1               
loc_rc4/3.0                    loc_rcv1/1.2(default:new)  
loc_rc5/1.0                    loc_rcv1/2.0               
loc_rc5/2.0                    loc_rcv1/bar(@)            
loc_rc6/0.9                    loc_rcv2/1.2               
loc_rc6/1(@)                   loc_rcv2/1.5               
loc_rc6/1.2(default:new)       loc_rcv2/2.0               
loc_rc6/bar(@)                 

Key:
(@)=module-alias  (symbolic-version)  "

set width_80 "[ts_avail_header 80]
loc_rc1/1.0(foo)               loc_rc6/1(@)               loc_rcv1/2.0     
loc_rc1/2.0                    loc_rc6/1.2(default:new)   loc_rcv1/bar(@)  
loc_rc2/1.0(bar:blah:foo)      loc_rc6/bar(@)             loc_rcv2/1.2     
loc_rc2/2.0                    loc_rc7/0.9                loc_rcv2/1.5     
loc_rc3/1.0(default)           loc_rc7/1(@)               loc_rcv2/2.0     
loc_rc3/2.0(cur:stable)        loc_rc7/1.2                
loc_rc3/3.0(chk:exp:new:test)  loc_rc7/bar(@)             
loc_rc4/1.0                    loc_rc8/0.9(@)             
loc_rc4/2.0(default)           loc_rc8/1.0                
loc_rc4/3.0                    loc_rc010/2.0              
loc_rc5/1.0                    loc_rcv1/1(@)              
loc_rc5/2.0                    loc_rcv1/1.1               
loc_rc6/0.9                    loc_rcv1/1.2(default:new)  

Key:
(@)=module-alias  (symbolic-version)  "

set width_100 "[ts_avail_header 100]
loc_rc1/1.0(foo)               loc_rc4/2.0(default)      loc_rc7/0.9     loc_rcv1/1.1               
loc_rc1/2.0                    loc_rc4/3.0               loc_rc7/1(@)    loc_rcv1/1.2(default:new)  
loc_rc2/1.0(bar:blah:foo)      loc_rc5/1.0               loc_rc7/1.2     loc_rcv1/2.0               
loc_rc2/2.0                    loc_rc5/2.0               loc_rc7/bar(@)  loc_rcv1/bar(@)            
loc_rc3/1.0(default)           loc_rc6/0.9               loc_rc8/0.9(@)  loc_rcv2/1.2               
loc_rc3/2.0(cur:stable)        loc_rc6/1(@)              loc_rc8/1.0     loc_rcv2/1.5               
loc_rc3/3.0(chk:exp:new:test)  loc_rc6/1.2(default:new)  loc_rc010/2.0   loc_rcv2/2.0               
loc_rc4/1.0                    loc_rc6/bar(@)            loc_rcv1/1(@)   

Key:
(@)=module-alias  (symbolic-version)  "

set width_400 "[ts_avail_header 400]
loc_rc1/1.0(foo)  loc_rc2/1.0(bar:blah:foo)  loc_rc3/1.0(default)     loc_rc3/3.0(chk:exp:new:test)  loc_rc4/2.0(default)  loc_rc5/1.0  loc_rc6/0.9   loc_rc6/1.2(default:new)  loc_rc7/0.9   loc_rc7/1.2     loc_rc8/0.9(@)  loc_rc010/2.0  loc_rcv1/1.1               loc_rcv1/2.0     loc_rcv2/1.2  loc_rcv2/2.0  
loc_rc1/2.0       loc_rc2/2.0                loc_rc3/2.0(cur:stable)  loc_rc4/1.0                    loc_rc4/3.0           loc_rc5/2.0  loc_rc6/1(@)  loc_rc6/bar(@)            loc_rc7/1(@)  loc_rc7/bar(@)  loc_rc8/1.0     loc_rcv1/1(@)  loc_rcv1/1.2(default:new)  loc_rcv1/bar(@)  loc_rcv2/1.5  

Key:
(@)=module-alias  (symbolic-version)  "



# Test of default configuration
unsetenv_var MODULES_TERM_WIDTH
testerr_cmd sh {avail loc_rc} $width_0


# basic tests with no option but an environment variable defined
# for different values

setenv_var MODULES_TERM_WIDTH "0"
testerr_cmd sh {avail loc_rc} $width_0
unsetenv_var MODULES_TERM_WIDTH

setenv_var MODULES_TERM_WIDTH "1"
testerr_cmd sh {avail loc_rc} $width_1
unsetenv_var MODULES_TERM_WIDTH

setenv_var MODULES_TERM_WIDTH "30"
testerr_cmd sh {avail loc_rc} $width_30
unsetenv_var MODULES_TERM_WIDTH

setenv_var MODULES_TERM_WIDTH "50"
testerr_cmd sh {avail loc_rc} $width_50
unsetenv_var MODULES_TERM_WIDTH

setenv_var MODULES_TERM_WIDTH "60"
testerr_cmd sh {avail loc_rc} $width_60
unsetenv_var MODULES_TERM_WIDTH

setenv_var MODULES_TERM_WIDTH "80"
testerr_cmd sh {avail loc_rc} $width_80
unsetenv_var MODULES_TERM_WIDTH

setenv_var MODULES_TERM_WIDTH "100"
testerr_cmd sh {avail loc_rc} $width_100
unsetenv_var MODULES_TERM_WIDTH

setenv_var MODULES_TERM_WIDTH "400"
testerr_cmd sh {avail loc_rc} $width_400
unsetenv_var MODULES_TERM_WIDTH


# tests with no environment variable defined
# but different values of options

unsetenv_var MODULES_TERM_WIDTH
testerr_cmd sh {avail loc_rc --width=0} $width_0
testerr_cmd sh {avail loc_rc -w 0} $width_0
testerr_cmd sh {avail loc_rc --width=1} $width_1
testerr_cmd sh {avail loc_rc -w 1} $width_1
testerr_cmd sh {avail loc_rc -w 30} $width_30
testerr_cmd sh {avail loc_rc --width=30} $width_30
testerr_cmd sh {avail loc_rc -w 50} $width_50
testerr_cmd sh {avail loc_rc --width=50} $width_50
testerr_cmd sh {avail loc_rc -w 60} $width_60
testerr_cmd sh {avail loc_rc --width=60} $width_60
testerr_cmd sh {avail loc_rc -w 80} $width_80
testerr_cmd sh {avail loc_rc --width=80} $width_80
testerr_cmd sh {avail loc_rc -w 100} $width_100
testerr_cmd sh {avail loc_rc --width=100} $width_100
testerr_cmd sh {avail loc_rc -w 400} $width_400
testerr_cmd sh {avail loc_rc --width=400} $width_400


# tests for the two options possible : "--width=" then "-w"
# with different values, which have to override the environment variable

setenv_var MODULES_TERM_WIDTH "80"
testerr_cmd sh {avail loc_rc --width=0} $width_0
unsetenv_var MODULES_TERM_WIDTH

setenv_var MODULES_TERM_WIDTH "80"
testerr_cmd sh {avail loc_rc -w 0} $width_0
unsetenv_var MODULES_TERM_WIDTH

# basic tests with --width=60 then -w 60

setenv_var MODULES_TERM_WIDTH "1"
testerr_cmd sh {avail loc_rc --width=60} $width_60
unsetenv_var MODULES_TERM_WIDTH

setenv_var MODULES_TERM_WIDTH "1"
testerr_cmd sh {avail loc_rc -w 60} $width_60
unsetenv_var MODULES_TERM_WIDTH

# test empty value set in MODULES_TERM_WIDTH

setenv_var MODULES_TERM_WIDTH ""
testerr_cmd sh {avail loc_rc --width=0} $width_0
unsetenv_var MODULES_TERM_WIDTH

setenv_var MODULES_TERM_WIDTH ""
testerr_cmd sh {avail loc_rc -w 60} $width_60
unsetenv_var MODULES_TERM_WIDTH

# test of ml command
testerr_cmd sh {ml avail loc_rc -w 1} $width_1

# test if two options have been put in command line
testerr_cmd sh {avail loc_rc --width=1 -w 60} $width_60



# non-integer value set via MODULES_TERM_WIDTH should be silently ignored
setenv_var MODULES_TERM_WIDTH "-80"
testouterr_cmd sh {avail loc_rc} OK "[ts_avail_header 169]
loc_rc1/1.0(foo)           loc_rc3/2.0(cur:stable)        loc_rc5/1.0               loc_rc6/bar(@)  loc_rc8/0.9(@)  loc_rcv1/1.2(default:new)  loc_rcv2/2.0  
loc_rc1/2.0                loc_rc3/3.0(chk:exp:new:test)  loc_rc5/2.0               loc_rc7/0.9     loc_rc8/1.0     loc_rcv1/2.0               
loc_rc2/1.0(bar:blah:foo)  loc_rc4/1.0                    loc_rc6/0.9               loc_rc7/1(@)    loc_rc010/2.0   loc_rcv1/bar(@)            
loc_rc2/2.0                loc_rc4/2.0(default)           loc_rc6/1(@)              loc_rc7/1.2     loc_rcv1/1(@)   loc_rcv2/1.2               
loc_rc3/1.0(default)       loc_rc4/3.0                    loc_rc6/1.2(default:new)  loc_rc7/bar(@)  loc_rcv1/1.1    loc_rcv2/1.5               

Key:
(@)=module-alias  (symbolic-version)  "
unsetenv_var MODULES_TERM_WIDTH



#
# 'list' sub-command
#

setenv_loaded_module [list loc_rc1/2.0 loc_rc2/2.0 loc_rc4/1.0 loc_rc4/3.0 loc_rc5/1.0 loc_rc5/2.0 loc_rc7/0.9 loc_rcv2/1.2] [list $mp/koc_rc1/2.0 $mp/koc_rc2/2.0 $mp/koc_rc4/1.0 $mp/koc_rc4/3.0 $mp/oc_rc5/1.0 $mp/oc_rc5/2.0 $mp/oc_rc7/0.9 $mp/oc_rcv2/1.2]
setenv_path_var MODULES_LMALTNAME loc_rc4/1.0&loc_rc4/default&loc_rc4

# Set the outputs for different width

set width_0 "Currently Loaded Modulefiles:
 1) loc_rc1/2.0   2) loc_rc2/2.0   3) loc_rc4/1.0(default)   4) loc_rc4/3.0   5) loc_rc5/1.0   6) loc_rc5/2.0   7) loc_rc7/0.9   8) loc_rcv2/1.2  

Key:
(symbolic-version)  "

set width_1 "Currently Loaded Modulefiles:
 1) loc_rc1/2.0           
 2) loc_rc2/2.0           
 3) loc_rc4/1.0(default)  
 4) loc_rc4/3.0           
 5) loc_rc5/1.0           
 6) loc_rc5/2.0           
 7) loc_rc7/0.9           
 8) loc_rcv2/1.2          

Key:
(symbolic-version)  "

set width_50 "Currently Loaded Modulefiles:
 1) loc_rc1/2.0            5) loc_rc5/1.0   
 2) loc_rc2/2.0            6) loc_rc5/2.0   
 3) loc_rc4/1.0(default)   7) loc_rc7/0.9   
 4) loc_rc4/3.0            8) loc_rcv2/1.2  

Key:
(symbolic-version)  "

set width_80 "Currently Loaded Modulefiles:
 1) loc_rc1/2.0   3) loc_rc4/1.0(default)   5) loc_rc5/1.0   7) loc_rc7/0.9   
 2) loc_rc2/2.0   4) loc_rc4/3.0            6) loc_rc5/2.0   8) loc_rcv2/1.2  

Key:
(symbolic-version)  "


# Test of default configuration
unsetenv_var MODULES_TERM_WIDTH
testerr_cmd sh {list} $width_0

# basic tests with no option but an environment variable defined
# for different values

setenv_var MODULES_TERM_WIDTH "0"
testerr_cmd sh {list} $width_0
unsetenv_var MODULES_TERM_WIDTH

setenv_var MODULES_TERM_WIDTH "1"
testerr_cmd sh {list} $width_1
unsetenv_var MODULES_TERM_WIDTH

setenv_var MODULES_TERM_WIDTH "50"
testerr_cmd sh {list} $width_50
unsetenv_var MODULES_TERM_WIDTH

# tests with no environment variable defined
# but different values of options

unsetenv_var MODULES_TERM_WIDTH
testerr_cmd sh {list --width=0} $width_0
testerr_cmd sh {list -w 1} $width_1
testerr_cmd sh {list --width=80} $width_80

# tests for the two options possible : "--width=" then "-w"
# with different values, which have to override the environment variable

setenv_var MODULES_TERM_WIDTH "80"
testerr_cmd sh {list --width=0} $width_0
unsetenv_var MODULES_TERM_WIDTH

# basic tests with --width=1 then -w 1

setenv_var MODULES_TERM_WIDTH "50"
testerr_cmd sh {list -w 1} $width_1
unsetenv_var MODULES_TERM_WIDTH


# test of ml command
testerr_cmd sh {ml --width=50} $width_50

unsetenv_loaded_module



#
# 'savelist' sub-command
#

setenv_var HOME $ORIG_HOME/home

setenv_var MODULES_TERM_WIDTH "80"
testerr_cmd sh {savelist} "Named collection list:
 1) coll1   3) coll3          5) coll6.target   7) infocmd     
 2) coll2   4) coll4.target   6) default        8) infocmdexp  "
unsetenv_var MODULES_TERM_WIDTH


setenv_var MODULES_TERM_WIDTH "80"
testerr_cmd sh {savelist --width=0} "Named collection list:
 1) coll1   2) coll2   3) coll3   4) coll4.target   5) coll6.target   6) default   7) infocmd   8) infocmdexp  "
unsetenv_var MODULES_TERM_WIDTH

testerr_cmd sh {savelist -w 1} "Named collection list:
 1) coll1         
 2) coll2         
 3) coll3         
 4) coll4.target  
 5) coll6.target  
 6) default       
 7) infocmd       
 8) infocmdexp    "

setenv_var HOME $ORIG_HOME



#
# 'load' sub-command
#

testerr_cmd sh {load bad2/body -w 10} "Loading bad2/body
  Module
    ERROR:
    invalid command name \"bad-command\"
    while
    executing
    \"bad-command\"
    (file
    \"$::modpath/bad2/body\" line 29)
    Please
    contact <root@localhost>"

setenv_var MODULES_TERM_WIDTH "50"
testerr_cmd sh {load bad2/body} "Loading bad2/body
  Module ERROR: invalid command name \"bad-command\"
        while executing
    \"bad-command\"
        (file
    \"$::modpath/bad2/body\" line 29)
    Please contact <root@localhost>"

testerr_cmd sh {load bad2/body --width=5} "Loading bad2/body
  Module ERROR: invalid command name \"bad-command\"
    while executing
    \"bad-command\"
    (file \"$::modpath/bad2/body\" line 29)
    Please contact <root@localhost>"


#
# 'whatis' sub-command
#

testerr_cmd sh {whatis loc_tr -w 50} "[ts_avail_header 50]
          loc_tr/1.0: loc_tr/1.0
          loc_tr/2.0: loc_tr/2.0
          loc_tr/3.0: loc_tr/3.0"



#
# List of case generating errors for the options -w or --width :
#

set output_error_w "$error_msgs: Invalid value for option '-w'
  Value should be an integer comprised between 0 and 1000"
set output_error_width "$error_msgs: Invalid value for option '--width'
  Value should be an integer comprised between 0 and 1000"



# too big numbers
testouterr_cmd sh {avail alias -w 10000} ERR $output_error_w

# negative numbers,
testouterr_cmd sh {avail alias --width=-100} ERR $output_error_width

# non-numerical character string
testouterr_cmd sh {avail alias -w foo} ERR $output_error_w

# non-integer value
testouterr_cmd sh {avail alias --width=10,90} ERR $output_error_width
testouterr_cmd sh {avail alias -w 10.90} ERR $output_error_w



#
#  Cleanup
#

# restore terminal width
exec stty cols $term_cols

# clean procedures set locally
rename ts_avail_header {}

}

reset_test_env
