#!/usr/bin/vipsi

/* ---- vipsi test script ----------------------------
        
        test a lot of vipsi functionality
        add more tests as you like ...
        demonstrates syntax and capabilities as well

        kio 2001-08-24
        kio 2002-03-09
        kio 2002-03-31
		kio 2003-08-14
*/


put nl,nl,"test script for vipsi",nl

if count globals
    log nl, count globals, " global variable", "s"[count globals>1], " already defined:", nl
    {
        var i=1;
        do
            while i<count globals   // globals[count globals] = local { … }
            if name globals[i]!="" log name globals[i], " = "
            else log "unnamed variable: " then
            log globals[i], nl
            i++
        loop
    }
then

del *
var a,b,c,d
var err = 0;
var errors = 0
var e,f,g,h


// ----------------------------------------------------------
put nl,"basic test requirements:"
put " t1" if 0                              log " failed" end then
put " t2" a=4 if a!=4                       log " failed" end then
put " t3" a++ if a!=5                       log " failed" end then
put " t4" a-- if a!=4                       log " failed" end then
put " t5" a=1 b=2 a=b   if a!=2||b!=2       log " failed" end then
put " t6" a=3 var z=a   if a!=3||z!=3       log " failed" end then

put " t7" if 0 log " failed(1)" end else ;                    then
put  "."  if 0 log " failed(2)" end                           then
put  "."  if 1 ;                    else log " failed(3)" end then

put " t8" if err!=0 log " failed" end then
put "."   err++; if err!=1 log " failed" end then
put "."   err--; if err!=0 log " failed" end then 
put "."   proc trap(f) { if f err++ then }
put "."   trap(0) if err!=0 log " failed" end then  
put "."   trap(1) if err!=1 log " failed" end then err--

put " t9" proc trap(f) { if f err++ log " failed" then }
put "."   trap(0) if err!=0 log " failed" end then

put " passed",nl



// ----------------------------------------------------------
put nl,"branching:"
put " t1" if 0                                      log " failed"   err++ then
put " t2" if 1 else                                 log " failed"   err++ then
put " t3" if 1 a=1 b=2 else                         log " failed"   err++ then
put " t4" if 1 if 0 else then else                  log " failed"   err++ then
put " t5" if 1 if 1 else then else                  log " failed"   err++ then

put " t6" err++ if 0 if 0 log" failed(1)" else log" failed(2)" then else err-- then
put "."   err++ if 0 if 1 log" failed(1)" else log" failed(2)" then else err-- then

put " t7" a=10 do a-=1 while a loop                 trap(a)
put "."   a=10 do a-=1 until !a loop                trap(a)
put "."   a=10 do a-=1 if a next then exit loop     trap(a)
put "."   a=10 do a-=1 if !a exit then loop         trap(a)
put "."   a=10 if 1 do a-=1 while a loop then       trap(a)
put "."   a=10 if 0 else do a-=1 while a loop then  trap(a)

if !err put " passed" else errors+=err err=0 then 



// ----------------------------------------------------------
put nl,"comparing:"
put " t1" trap( 1==2 )
put "."   trap( 2!=2 )
put "."   trap( 1>=2 )
put "."   trap( 2<=1 )
put "."   trap( 2>2 || 1>2 )
put "."   trap( 2<2 || 2<1 )

put " t2" var e=1 var z=2
put "."   trap( e==z )
put "."   trap( z!=z )
put "."   trap( e>=z )
put "."   trap( z<=e )
put "."   trap( z >z )
put "."   trap( z< z )
put "."   trap( e!=1 || z!=2 )

if !err put " passed" else errors+=err err=0 then 



// ----------------------------------------------------------
put nl,"numerics:"
put" t1" a=4 trap( a!=4.0 )
put" t2" trap( a+4!=8 )
put"."   trap( 17%5!=2 )
put"."   trap( -17%5!=-2 )
put"."   trap( 17%2.5!=2 )
put"."   trap( -17%2.5!=-2 )
put"."   trap( 17%-2.5!=2 )
put"."   trap( -17%-2.5!=-2 )
put" t3" trap( 4-3.5!=0.5 )
put" t4" trap( -a!=+3-7.0 )
put"."   trap( -0!=0 )
put"."   trap( !0!=1 || !55!=0 )
put"."   trap( ~0!=256*256*256*256-1 )
put" t5" trap( +a!=4 )
put"."   trap( a*3.5!=14 )
put"."   trap( a/0.5!=+0.0+8 )
put"."   trap( 123.456!=((((123.0))+(0.456))) )

put" t6" trap( (3+4*50)!=203 )
put"."   trap( (3-4/5)!=2.2 )
put"."   trap( (3*(4+5))!=27 )
put"."   trap( ((3+4)*5)!=35 )
put"."   trap( (3+-4)!=-1 )
put"."   trap( (15&26!=10)!=0 )

put" t7" a = 123.456+385.12*46.1/46/(1.02*(0.03+164.44))
         b = 1.02*0.03+164.44*1.02
         c = 385.12*46.1
         d = c/23/2.000     
         trap( a!=d/b+123+0.456 )

put" t8" a=44 trap( ++a!=45 || ++a!=46 )
put"."   a=44 trap( --a!=43 || --a!=42 )
put"."   a=44 trap( a++!=44 || a++!=45 )
put"."   a=44 trap( a--!=44 || a--!=43 )

put" t9" trap( (3>4?(2*3):"B")!="B" )
put"."   trap( (!0?"A"#"B":0)!="AB" )
put"."   trap( (0?5:0?6:1?7:1?8:0)!=7 )
put"."   trap( (0?5:0?6:1?7:0?8:1)!=7 )

put" t10" a=123; a-=20+3;       trap( a-100 )
put"."    a=123; a+=-46/2;      trap( a-100 )
put"."    a=123; a*=3+2*10;     trap( a!=2829 )
put"."    a=1604.928 a/=123.456 trap( a!=13 )

put" t11" trap( stdin!=0 )
put"."    trap( stdout!=1 )
put"."    trap( stderr!=2 )
put"."    trap( pi!=3.141592653589793 )
put"."    trap( ec!=2.718281828459045 )

put " t12" a=3 a=a+a+a trap( a!=9 )
put "."    trap( 33<<2 != 132 )
put "."    trap( 132>>2 != 33 )
put "."    trap( $1234!=4660 )
put "."    trap( $9Affe54f!=2600461647 )

if !err put " passed" else errors+=err err=0 then 


// ----------------------------------------------------------
put nl,"strings: "
put"."    if "abcde"#"fghi"!="abcdefghi" log " t1 failed" err++ then
put"."    if "abcde"[2]!="b"          log " t2 failed" err++ then
put"."    if "abcde"[to 2]!="ab"      log " t3 failed" err++ then
put"."    if "abcde"[4 to]!="de"      log " t4 failed" err++ then
put"."    if "abcde"[2 to 4]!="bcd"   log " t5 failed" err++ then
put"."    if "abcde"[-2 to 2]!="ab"   log " t6 failed" err++ then
put"."    if "abcde"[-2 to]!="abcde"  log " t7 failed" err++ then
put"."    if "abcde"[to 99]!="abcde"  log " t8 failed" err++ then
put"."    if "abcde"[to -5]!=""       log " t9 failed" err++ then

put"."    if "abcde"<"abcde"  log " t10 failed" err++ then
put"."    if "abcde">"abcde"  log " t11 failed" err++ then
put"."    if "abcde"!="abcde" log " t12 failed" err++ then
put"."    if "abcde"<"abcd"   log " t13 failed" err++ then
put"."    if "abcde"<"abcdE"  log " t14 failed" err++ then
put"."    if upperstr"AnToN MüLLer öäüßÖÄÜ"!="ANTON MÜLLER ÖÄÜßÖÄÜ" log " t15 failed" err++ then
put"."    if lowerstr"AnToN MüLLer öäüßÖÄÜ"!="anton müller öäüßöäü" log " t16 failed" err++ then

if !err put " passed" else errors+=err err=0 then 


// ----------------------------------------------------------
put nl,"string functions: "
put"."    if string(0)!="0"                   log " t1 failed" err++ then
put"."    if string(0.001)!="0.001"           log " t2 failed" err++ then
put"."    if string(100.11+0.001)!="100.111"  log " t3 failed" err++ then
put"."    if find("hasta la vista","la")!=7   log " t4 failed" err++ then
put"."    if find("hasta la vista","zz")!=0   log " t5 failed" err++ then
put"."    if find("hasta la vista","ha")!=1   log " t6 failed" err++ then
put"."    if find("hasta la vista","")!=1     log " t7 failed" err++ then
put"."    if find("la","hasta la vista")!=0   log " t8 failed" err++ then
put"."    if find("xyz","xyz")!=1             log " t9 failed" err++ then
put"."    if find("xyz","xy")!=1              log " t10 failed" err++ then
put"."    if find("xyz","yz")!=2              log " t11 failed" err++ then
put"."    if find("","")!=1                   log " t12 failed" err++ then
put"."    if charstr(65)!="A"                 log " t13 failed" err++ then
put"."    b="B" if charstr(65)#b#charstr(67)!="ABC"   log " t14 failed" err++ then    if b!="B" log " t14.1 failed" err++ then

if !err put " passed" else errors+=err err=0 then 



// ----------------------------------------------------------
put nl,"numeric functions: "
put"t1"   a=0 do while ++a<10000 b=random 10000 c=random b until c<0 || c>=b loop
put"."    if a!=10000 log " t1 failed" err++ then
put"."    if round 7.1!=7     log " t19 failed" err++ then
put"."    if round 8.5!=9     log " t20 failed" err++ then
put"."    if round -8.5!=-8   log " t21 failed" err++ then
put"."    if round -8.4!=-8   log " t22 failed" err++ then
put"t2"   if sign 3434.1!=1   log " t23 failed" err++ then
put"."    if sign 0 != 0      log " t24 failed" err++ then
put"."    if sign -0.001!=-1  log " t25 failed" err++ then
put"t3"   if abs +124.4!=124.4 log " t26 failed" err++ then
put"."    if abs 0.0!=0       log " t27 failed" err++ then
put"."    if abs -17.3!=17.3  log " t28 failed" err++ then
put"t4"   if int 99.9!=99     log " t29 failed" err++ then
put"."    if int -99.9!=-99   log " t30 failed" err++ then
put"."    if round(1000*fract 99.9)!=900 log " t31 failed" err++ then
put"."    if round(1000*fract -99.9)!=-900 log " t32 failed" err++ then

put"t5"   if min(2,5)!=2            log " t33 failed" err++ then
put"."    if min(2,5,-55,0,17)!=-55 log " t34 failed" err++ then
put"."    if min(5)!=5              log " t35 failed" err++ then
put"."    a=44 b=33 c=66 min(a,b,c)=99 if b!=99 " t36 failed" err++ then
put"."    if max(2,5)!=5            log " t37 failed" err++ then
put"."    if max(2,5,-55,17,0)!=17  log " t38 failed" err++ then
put"."    if max(5)!=5              log " t39 failed" err++ then
put"t6"   a=44 b=33 c=66 max(a,b,c)=99 if c!=99 log " t40 failed" err++ then
put"."    a=44 b=55 c=66 if max(a,b,c)!=66 log " t41 failed" err++ then
put"."    if (a!=44) log " t42 failed" err++ then
put"."    if (b!=55) log " t43 failed" err++ then
put"."    if (c!=66) log " t44 failed" err++ then
put":"    a=44 b=55 c=66 if max(c,b,a)!=66 log " t45 failed" err++ then
put"."    if (a!=44) log " t46 failed" err++ then
put"."    if (b!=55) log " t47 failed" err++ then
put"."    if (c!=66) log " t48 failed" err++ then
put":"    d=99 d=max(c,b,a) if d!=66 log " t49 failed" err++ then
put"."    if (a!=44) log " t50 failed" err++ then
put"."    if (b!=55) log " t51 failed" err++ then
put"."    if (c!=66) log " t52 failed" err++ then
put"."    if (d!=66) log " t53 failed" err++ then

if !err put " passed" else errors+=err err=0 then



// ----------------------------------------------------------
put nl,"vektor functions:"
put "t1 " a={} if count(a)!=0 log "failed " err++ then
put "t2 " a[1]=1 if count(a)!=1 log "failed " err++ then
put "t3 " a[55]="" if count(a)!=55 log "failed " err++ then
put "t4 " if !islist a log "failed " err++ then
put "t5 " if !isnumber a[5] log "failed " err++ then
put "."   if a[5]!=0 log "failed " err++ then
put "."   a[2]="<AnToN MüLLer öäüßÖÄÜ>" convert a to html
put "t6 " if !isnumber a[1] log "failed " err++ then
put "t7 " if !istext a[55] log "failed " err++ then
put "t8 " if a[2]!="&lt;AnToN MüLLer öäüßÖÄÜ&gt;" log "failed " err++ then
put "t9 " if !isnumber a[6] log "failed " err++ then
put "."   if a[6]!=0 log "failed " err++ then
put "t10 " if a[2,7]!="T" log "failed " err++ then
put "t11 " if {}##1##"1" != {1,"1"}             log "failed " err++ then
put "t12 " a={1,2} a[3]=a if a!={1,2,{1,2,0}}   log "failed " err++ then
put "t13 " a={2,3} a=a##a if a!={2,3,2,3}       log "failed " err++ then

if !err put " passed" else errors+=err err=0 then



// ----------------------------------------------------------
put nl,"variables:"
put " t1" a=0 if !isnumber a            log " failed" err++ then
put "."   a=0 if istext a               log " failed" err++ then
put "."   a=0 if islist a               log " failed" err++ then
put "."   a=0 if !exists a              log " failed" err++ then
put "."   a=0 if exists a.foo           log " failed" err++ then
put "."   a=0 if exists foo             log " failed" err++ then
put " t2" var foo if !exists foo        log " failed" err++ then
put "."   foo={} foo[1]=1 foo[2]=2 foo[3]=3 foo[4]=4
put "."   if !exists foo[2]             log " failed" err++ then
put "."   foo[2]={} foo[2,5]=0
put "."   if !exists foo[2,5]           log " failed" err++ then
put "."   if !isnumber foo[2,5]         log " failed" err++ then
put "."   if count foo[2]!=5            log " failed" err++ then
put " t3" del foo[2]
put "."   if count foo[2]!=0            log " failed" err++ then
put "."   if !isnumber foo[2]           log " failed" err++ then
put " t4" foo={1,2,3,4,5}
put "."   if count foo!=5               log " failed" err++ then
put "."   del foo[5] if count foo!=4    log " failed" err++ then
put "."   del foo[3] if count foo!=3    log " failed" err++ then
put "."   if foo!={1,2,4}               log " failed" err++ then

if !err put " passed" else errors+=err err=0 then



// ----------------------------------------------------------
put nl,"structured vektors:"
put "." var punkt 
put "." punkt={}
put " t0" if name punkt[1]!="" log "failed " err++ then 
put "."   rename punkt[1]="x" put"." punkt.x=0 
put "."   rename punkt[2]="y" put"." punkt.y=0 

put " t1" if name punkt[1]!="x" log "failed " err++ then 
put "."   if name punkt[2]!="y" log "failed " err++ then 
put "."   punkt[1]=77; if punkt.x!=77  log "failed " err++ then 
put "."   punkt[2]=88; if punkt.y!=88  log "failed " err++ then 
put "."   punkt.x=34;  if punkt[1]!=34 log "failed " err++ then 
put "."   punkt.y=45;  if punkt[2]!=45 log "failed " err++ then 

put " t2" var v={} v[3]=punkt rename v[3]="pt"
put "."   if string v != "{ 0, 0, pt={ x=" # string punkt.x # ", y=" # string punkt.y # " } }" log "failed " err++ then
put "."   if !exists v.pt    log "failed " err++ then 
put "."   if v[3,1]!=punkt.x log "failed " err++ then 
put "."   if v[3,2]!=punkt.y log "failed " err++ then 
put "."   if v[3].x!=punkt.x log "failed " err++ then 
put "."   if v[3].y!=punkt.y log "failed " err++ then 
put "."   if v.pt.x!=punkt.x log "failed " err++ then 
put "."   if v.pt.y!=punkt.y log "failed " err++ then 
put "."   if !exists punkt.y log "failed " err++ then 
put "."   if  exists punkt.z log "failed " err++ then 
put "."   if !exists v.pt.y  log "failed " err++ then 
put "."   if  exists v.pt.z  log "failed " err++ then 
put "."   if !exists v[3].y  log "failed " err++ then 
put "."   if  exists v[3].z  log "failed " err++ then 

put " t3" var a.foo.boo.z = 1
put "."   if !exists a.foo.boo.z        log " failed" err++ then 
put "."   if a.foo.boo.z!=1             log " failed" err++ then 
put "."   b="boo" if !exists a.foo.@b.z log " failed" err++ then 
put "."   b="foo.boo" if !exists a.@b.z log " failed" err++ then 
put "."   if a.@b.z!=1                  log " failed" err++ then 

if !err put " passed" else errors+=err err=0 then 



// ----------------------------------------------------------
put nl,"special instructions:"
47+2; "123";    // just execute it
a=1;a++; if a!=2 put " t1 failed" err++ then 

if !err put " passed" else errors+=err err=0 then 



// ----------------------------------------------------------
put nl,"more branching:"

put " t1"
var i=0
var j={} j[6]=0 j[6]+=1 if j[6]!=1 log " failed" err++ then
put " t2"
do
    until ++i==9
    if i==2 j[1]=1 next then
    if i==2 j[2]=2 next then
    if i==9 j[3]=3 next then
    if i==5 
        if 0 j[4]=4 exit else j[5]=5 exit then
    else
        j[6]+=1
    then
loop
if string(j) != "{ 1, 0, 0, 0, 5, 4 }" log " failed", " string(j)=",string(j) err++ then

put " t3"
var i=0
var j={} j[4]=0
var k=0
do
    while ++i!=9
    if i==2 j[1]=1 next then
    if i==2 j[2]=2 next then
    if i==9 j[3]=3 next 
    else
        if i!=5
            if ++k==10 log "abort " end then
            j[4]+=1
            next
        else
            if 1 j[5]=5 exit else j[6]=6 exit then
            j[7]=7
        then
    then
    j[8]=8
loop
if string(j) != "{ 1, 0, 0, 3, 5 }" log " failed" err++ then


if !err put " passed" else errors+=err err=0 then 



// ----------------------------------------------------------
put nl,"functions:"

put " t0" proc test1 ( ) { a=77 }               if !isproc test1 log " failed"  err++ then 
put "."   proc test2 ( a,b,c) {return a*b*c}    if !isproc test2 log " failed"  err++ then 
proc drei ( ) { return 3 }
proc vier(){return 4}
put " t1" a=10 test1() if a!=77         log " failed"  err++ then 
put "." a=10 if test2(2,3,4)!=24        log " failed"  err++ then 
put "." if a!=10                        log " failed"  err++ then 
put "." a=10 if a+drei()!=13            log " failed"  err++ then 
put "." if a!=10                        log " failed"  err++ then 
put "." a=10 if drei()+a!=13            log " failed"  err++ then 
put "." if a!=10                        log " failed"  err++ then 
put "." if drei()*vier()!=12            log " failed"  err++ then 
proc zwei(a){var b return count locals}
put " t2" if zwei(0)!=2                 log " failed"  err++ then 
proc das(a){return locals[1]}
put " t3" if das(55)!=55                log " failed"  err++ then 
proc mult(a,b){return locals[1]*locals[2]}
put " t4" if mult(5,6)!=30              log " failed"  err++ then 
put "." a={} a[1]=drei if !isproc a[1]	log " failed"  err++ then
put "." a=a[1]() if a!=3                log " failed"  err++ then 
proc t(*){return count locals}
put " t5" if t()!=0                     log " failed"  err++ then 
put "." if t(4)!=1                      log " failed"  err++ then 
put "." if t(6,a)!=2                    log " failed"  err++ then 
put "." if t(a,5+6,0)!=3                log " failed"  err++ then 
proc t1(*){return count locals}
put " t6" if t1(4)!=1                   log " failed"  err++ then 
put "." if t1(6,a)!=2                   log " failed"  err++ then 
put "." if t1(a,5+6,0)!=3               log " failed"  err++ then 
proc mult(*) { var n; n=count locals; var r=1; do while --n r*=locals[n] loop return r }
put " t7" if mult()!=1                  log " failed"  err++ then 
put "." if mult(4,5.5)!=22              log " failed"  err++ then 
put "." if mult(pi)!=pi                 log " failed"  err++ then 
var a=10,b=20
put " t8" if mult(a,2,b)!=400           log " failed"  err++ then 
put "." if a!=10||b!=20                 log " failed"  err++ then 
proc fak(n){ if n<=1 return n then return n*fak(n-1)}
put " t9" if fak(11)!=39916800          log " failed"  err++ then 

var a={} rename a[1]="wert" rename a[2]="SetWert" rename a[3]="GetWert" a.wert=55

proc gw() {return wert}     a.GetWert = gw
proc sw(n){wert=n}          a.SetWert = sw

put " t10" a.SetWert(66) if a.wert!=66  log " failed"  err++ then 
put "."    if a.GetWert()!=66           log " failed"  err++ then 
a.SetWert(77)
put " t11" { if a.GetWert()!=77         log " failed"  err++ then }

if !err put " passed" else errors+=err err=0 then 



// ----------------------------------------------------------

put nl,nl,"mounted devices:"    dir ""      // mounted devices

put nl,nl,"root directory:"     dir "/"     // root directory

put nl,nl,"home directory:"     dir "~"     // home directory

put nl,nl,"current directory:"  dir "./"    // current directory



// ----------------------------------------------------------
if errors
    log nl," ",nl,"--- ",errors," errors total ---",nl
else
    put nl," ",nl,"+++ all tests passed +++",nl
then



end













