# Tests for math library. -*- tcl -*- # # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1998-2000 by Ajuba Solutions. # All rights reserved. # # RCS: @(#) $Id: math.test,v 1.22 2009/12/04 17:37:47 andreas_kupries Exp $ # ------------------------------------------------------------------------- source [file join \ [file dirname [file dirname [file join [pwd] [info script]]]] \ devtools testutilities.tcl] testsNeedTcl 8.2 testsNeedTcltest 1.0 testing { useLocal math.tcl math } # ------------------------------------------------------------------------- # # Create and register (in that order!) custom matching procedures # proc matchTolerant { expected actual } { set match 1 foreach a $actual e $expected { if { abs($e-$a)>0.0001*abs($e) && abs($e-$a)>0.0001*abs($a) } { set match 0 break } } return $match } # tcltest 2.0-ism, we rely here only on 1.0 features #customMatch tolerant matchTolerant test math-1.1 {math::min, wrong num args} { catch {math::min} msg set msg } [tcltest::wrongNumArgs math::min {val args} 0] test math-1.2 {simple math::min} { math::min 1 } 1 test math-1.3 {simple math::min} { math::min 2 1 } 1 test math-1.4 {math::min} { math::min 2 1 0 } 0 test math-1.5 {math::min with negative numbers} { math::min 2 1 0 -10 } -10 test math-1.6 {math::min with floating point numbers} { math::min 2 1 0 -10 -10.5 } -10.5 test math-2.1 {math::max, wrong num args} { catch {math::max} msg set msg } [tcltest::wrongNumArgs math::max {val args} 0] test math-2.2 {simple math::max} { math::max 1 } 1 test math-2.3 {simple math::max} { math::max 2 1 } 2 test math-2.4 {math::max} { math::max 0 2 1 0 } 2 test math-2.5 {math::max with negative numbers} { math::max 2 1 0 -10 } 2 test math-2.6 {math::max with floating point numbers} { math::max 2 1 0 -10 10.5 } 10.5 test math-3.1 {math::mean, wrong num args} { catch {math::mean} msg set msg } [tcltest::wrongNumArgs math::mean {val args} 0] test math-3.2 {simple math::mean} { math::mean 1 } 1.0 test math-3.3 {simple math::mean} { math::mean 2 1 } 1.5 test math-3.4 {math::mean} { math::mean 0 2 1 0 } 0.75 test math-3.5 {math::mean with negative numbers} { math::mean 2 1 0 -11 } -2.0 test math-3.6 {math::mean with floating point numbers} { matchTolerant 0.7 [math::mean 2 1 0 -10 10.5] } 1 test math-4.1 {math::sum, wrong num args} { catch {math::sum} msg set msg } [tcltest::wrongNumArgs math::sum {val args} 0] test math-4.2 {math::sum} { math::sum 1 } 1 test math-4.3 {math::sum} { math::sum 1 2 3 } 6 test math-4.4 {math::sum} { matchTolerant 1.6 [math::sum 0.1 0.2 0.3 1] } 1 test math-4.5 {math::sum} { math::sum -1 1 } 0 test math-5.1 {math::product, wrong num args} { catch {math::product} msg set msg } [tcltest::wrongNumArgs math::product {val args} 0] test math-5.2 {simple math::product} { math::product 1 } 1 test math-5.3 {simple math::product} { math::product 0 1 2 3 4 5 6 7 } 0 test math-5.4 {math::product} { math::product 1 2 3 4 5 } 120 test math-5.5 {math::product with negative numbers} { math::product 2 -10 } -20 test math-5.6 {math::product with floating point numbers} { math::product 2 0.5 } 1.0 test math-6.1 {math::sigma, wrong num args} { catch {math::sigma} msg set msg } [tcltest::wrongNumArgs math::sigma {val1 val2 args} 0] test math-6.2 {simple math::sigma} { catch {math::sigma 1} msg set msg } [tcltest::wrongNumArgs math::sigma {val1 val2 args} 1] test math-6.3 {simple math::sigma} { expr round([ math::sigma 100 120 ]) } 14 test math-6.4 {math::sigma} { expr round([ math::sigma 100 110 100 100 ]) } 5 test math-6.5 {math::sigma with negative numbers} { math::sigma 100 100 100 -100 } 100.0 test math-6.6 {math::sigma with floating point numbers} { math::sigma 100 110 100 100.0 } 5.0 test math-7.1 {math::cov, wrong num args} { catch {math::cov} msg set msg } [tcltest::wrongNumArgs math::cov {val1 val2 args} 0] test math-7.2 {simple math::cov} { catch {math::cov 1} msg set msg } [tcltest::wrongNumArgs math::cov {val1 val2 args} 1] test math-7.3 {simple math::cov} { math::cov 2 1 } 100.0 test math-7.4 {math::cov} { if {![catch { math::cov 0 2 1 0 } msg]} { if { [string equal $msg Infinity] || [string equal $msg Inf] } { set result ok } else { set result "result of cov was [list $msg],\ should be Infinity" } } else { if { [string equal [lrange $::errorCode 0 1] {ARITH DOMAIN}] } { set result ok } else { set result "error from cov was [list $::errorCode],\ should be {ARITH DOMAIN *}" } } set result } ok test math-7.5 {math::cov with negative numbers} { math::cov 100 100 100 -100 } 200.0 test math-7.6 {math::cov with floating point numbers} { string range [ math::cov 100 110 100 100.0 ] 0 0 } 4 test math-7.7 {math::cov with zero mean} { # Throw an error catch { math::cov 1 1 -2 } msg } 1 test math-8.1 {math::stats, wrong num of args} { catch { math::stats } msg set msg } [tcltest::wrongNumArgs math::stats {val1 val2 args} 0] test math-8.2 {math::stats, wrong num of args} { catch { math::stats 100 } msg set msg } [tcltest::wrongNumArgs math::stats {val1 val2 args} 1] test math-8.3 { simple math::stats } { foreach {a b c} [ math::stats 100 100 100 110 ] { break } set a [ expr round($a) ] set b [ expr round($b) ] set c [ expr round($c) ] list $a $b $c } {102 5 5} test math-9.1 { math::integrate, insufficient data points } { catch { math::integrate {1 10 2 20 3 30 4 40} } msg set msg } "at least 5 x,y pairs must be given" test math-9.2 { simple math::integrate } { math::integrate {1 10 2 20 3 30 4 40 5 50 6 60 7 70 8 80 9 90 10 100} } {500.0 0.5} test math-10.1 { math::random } { set result [expr round(srand(12345) * 1000)] for {set i 0} {$i < 10} {incr i} { lappend result [expr round([::math::random] * 1000)] } set result } {97 834 948 36 12 51 766 585 914 784 333} test math-10.2 { math::random value } { set result {} expr {srand(12345)} for {set i 0} {$i < 10} {incr i} { lappend result [::math::random 10] } set result } {8 9 0 0 0 7 5 9 7 3} test math-10.3 { math::random value value } { set result {} expr {srand(12345)} for {set i 0} {$i < 10} {incr i} { lappend result [::math::random 5 15] } set result } {13 14 5 5 5 12 10 14 12 8} test math-10.4 {math::random} { list [catch {::math::random foo bar baz} msg] $msg } [list 1 "wrong # args: should be \"::math::random ?value1? ?value2?\""] test math-11.1 {math::fibonacci} { set result {} for {set i 0} {$i < 15} {incr i} { lappend result [::math::fibonacci $i] } set result } [list 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377] test math-12.1 {Safe Interpreter} { ::safe::interpCreate safeInterp interp alias safeInterp puts {} puts set result [interp eval safeInterp { package require math set result [math::cov 100 100 100 -100] }] interp delete safeInterp set result } 200.0 testsuiteCleanup